From 22b7a0b42f5618e52b717d31933b016b7022e2c6 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 8 Oct 2020 12:13:06 +0200 Subject: [PATCH 001/144] initial work --- Cargo.lock | 523 +++++++++++++++++++++++++++++++++++++- cli/Cargo.toml | 1 + cli/ops/mod.rs | 1 + cli/ops/webgpu/buffer.rs | 126 +++++++++ cli/ops/webgpu/mod.rs | 178 +++++++++++++ cli/ops/webgpu/texture.rs | 205 +++++++++++++++ cli/rt/14_webgpu.js | 148 +++++++++++ 7 files changed, 1181 insertions(+), 1 deletion(-) create mode 100644 cli/ops/webgpu/buffer.rs create mode 100644 cli/ops/webgpu/mod.rs create mode 100644 cli/ops/webgpu/texture.rs create mode 100644 cli/rt/14_webgpu.js diff --git a/Cargo.lock b/Cargo.lock index 8500195a3014fb..f85fbcfe8d780d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,15 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +[[package]] +name = "ash" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c69a8137596e84c22d57f3da1b5de1d4230b1742a710091c85f4d7ce50f00f38" +dependencies = [ + "libloading", +] + [[package]] name = "ast_node" version = "0.7.0" @@ -110,6 +119,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "atom" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9ff149ed9780025acfdb36862d35b28856bb693ceb451259a7164442f22fdc3" + [[package]] name = "atty" version = "0.2.14" @@ -151,6 +166,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.7.3" @@ -247,6 +268,9 @@ name = "cc" version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -289,6 +313,30 @@ dependencies = [ "bitflags", ] +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + [[package]] name = "const-random" version = "0.1.8" @@ -309,6 +357,40 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "copyless" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" + +[[package]] +name = "core-foundation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0af3b5e4601de3837c9332e29e0aae47a0d46ebfa246d12b82f564bac233393" + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + [[package]] name = "cpuid-bool" version = "0.1.2" @@ -345,6 +427,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "d3d12" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a60cceb22c7c53035f8980524fdc7f17cf49681a3c154e6757d30afbec6ec4" +dependencies = [ + "bitflags", + "libloading", + "winapi 0.3.9", +] + [[package]] name = "darling" version = "0.10.2" @@ -444,6 +537,7 @@ dependencies = [ "warp", "webpki", "webpki-roots", + "wgpu", "winapi 0.3.9", "winres", ] @@ -678,6 +772,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "from_variant" version = "0.1.2" @@ -875,6 +984,149 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] +[[package]] +name = "gfx-auxil" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ec012a32036c6439180b688b15a24dc8a3fbdb3b1cd02eb55266201db4c1b0f" +dependencies = [ + "fxhash", + "gfx-hal", + "spirv_cross", +] + +[[package]] +name = "gfx-backend-dx11" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c7fd31dcf0f8496fc94fe44b285a0bfeeb33b5a8ec0f59ea5f8fa64428071b4" +dependencies = [ + "bitflags", + "gfx-auxil", + "gfx-hal", + "libloading", + "log", + "parking_lot", + "range-alloc", + "raw-window-handle", + "smallvec", + "spirv_cross", + "winapi 0.3.9", + "wio", +] + +[[package]] +name = "gfx-backend-dx12" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3173338bc209dab8b83f6c02ba6ab26e31a9428993458e8d474a964b9170d639" +dependencies = [ + "arrayvec", + "bitflags", + "d3d12", + "gfx-auxil", + "gfx-hal", + "log", + "range-alloc", + "raw-window-handle", + "smallvec", + "spirv_cross", + "winapi 0.3.9", +] + +[[package]] +name = "gfx-backend-empty" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2085227c12b78f6657a900c829f2d0deb46a9be3eaf86844fde263cdc218f77c" +dependencies = [ + "gfx-hal", + "log", + "raw-window-handle", +] + +[[package]] +name = "gfx-backend-metal" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a5278b173f1008ad38f2bd38ca51e18a5e5d23a87195824bee468fcc390dce" +dependencies = [ + "arrayvec", + "bitflags", + "block", + "cocoa-foundation", + "copyless", + "foreign-types", + "gfx-auxil", + "gfx-hal", + "lazy_static", + "log", + "metal", + "objc", + "parking_lot", + "range-alloc", + "raw-window-handle", + "smallvec", + "spirv_cross", + "storage-map", +] + +[[package]] +name = "gfx-backend-vulkan" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70aad11a5760d216e3899beac0356560765402f30d2c1eaa79687276c8e006f7" +dependencies = [ + "arrayvec", + "ash", + "byteorder", + "core-graphics-types", + "gfx-hal", + "inplace_it", + "lazy_static", + "log", + "objc", + "raw-window-handle", + "smallvec", + "winapi 0.3.9", + "x11", +] + +[[package]] +name = "gfx-descriptor" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8c7afcd000f279d541a490e27117e61037537279b9342279abf4938fe60c6b" +dependencies = [ + "arrayvec", + "fxhash", + "gfx-hal", + "log", +] + +[[package]] +name = "gfx-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d0754f5b7a43915fd7466883b2d1bb0800d7cc4609178d0b27bf143b9e5123" +dependencies = [ + "bitflags", + "raw-window-handle", +] + +[[package]] +name = "gfx-memory" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe8d8855df07f438eb8a765e90356d5b821d644ea3b59b870091450b89576a9f" +dependencies = [ + "fxhash", + "gfx-hal", + "hibitset", + "log", + "slab", +] + [[package]] name = "h2" version = "0.2.6" @@ -934,6 +1186,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hibitset" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a1bb8316a44459a7d14253c4d28dd7395cbd23cc04a68c46e851b8e46d64b1" +dependencies = [ + "atom", +] + [[package]] name = "http" version = "0.2.1" @@ -1063,6 +1324,12 @@ dependencies = [ "libc", ] +[[package]] +name = "inplace_it" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd01a2a73f2f399df96b22dc88ea687ef4d76226284e7531ae3c7ee1dc5cb534" + [[package]] name = "input_buffer" version = "0.3.1" @@ -1072,6 +1339,15 @@ dependencies = [ "bytes", ] +[[package]] +name = "instant" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" +dependencies = [ + "cfg-if", +] + [[package]] name = "iovec" version = "0.1.4" @@ -1106,6 +1382,15 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "jobserver" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.45" @@ -1174,6 +1459,25 @@ version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +[[package]] +name = "libloading" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2443d8f0478b16759158b2f66d525991a05491138bc05814ef52a250148ef4f9" +dependencies = [ + "cfg-if", + "winapi 0.3.9", +] + +[[package]] +name = "lock_api" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.11" @@ -1183,6 +1487,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "matches" version = "0.1.8" @@ -1201,6 +1514,20 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "metal" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "foreign-types", + "log", + "objc", +] + [[package]] name = "mime" version = "0.3.16" @@ -1321,6 +1648,20 @@ dependencies = [ "twoway", ] +[[package]] +name = "naga" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0873deb76cf44b7454fba7b2ba6a89d3de70c08aceffd2c489379b3d9d08e661" +dependencies = [ + "bitflags", + "fxhash", + "log", + "num-traits", + "spirv_headers", + "thiserror", +] + [[package]] name = "net2" version = "0.2.35" @@ -1422,6 +1763,25 @@ dependencies = [ "libc", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + [[package]] name = "once_cell" version = "1.4.1" @@ -1468,6 +1828,32 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if", + "cloudabi 0.1.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1550,6 +1936,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" + [[package]] name = "pmutil" version = "0.5.3" @@ -1758,7 +2150,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" dependencies = [ - "cloudabi", + "cloudabi 0.0.3", "fuchsia-cprng", "libc", "rand_core 0.4.2", @@ -1794,6 +2186,21 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "range-alloc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a871f1e45a3a3f0c73fb60343c811238bb5143a81642e27c2ac7aac27ff01a63" + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -2152,6 +2559,27 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spirv_cross" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b631bd956108f3e34a4fb7e39621711ac15ce022bc567da2d953c6df13f00e00" +dependencies = [ + "cc", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "spirv_headers" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f5b132530b1ac069df335577e3581765995cba5a13995cdbbdbc8fb057c532c" +dependencies = [ + "bitflags", + "num-traits", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2164,6 +2592,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "storage-map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418bb14643aa55a7841d5303f72cf512cfb323b8cc221d51580500a1ca75206c" +dependencies = [ + "lock_api", +] + [[package]] name = "string_cache" version = "0.8.0" @@ -2747,6 +3184,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "typed-arena" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" + [[package]] name = "typenum" version = "1.12.0" @@ -3019,6 +3462,65 @@ dependencies = [ "webpki", ] +[[package]] +name = "wgpu" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "549160f188eef412ac978499ddf0ceadad4c9159bb1160f9e6b9d4cc8ee977dc" +dependencies = [ + "arrayvec", + "futures", + "gfx-backend-vulkan", + "js-sys", + "objc", + "parking_lot", + "raw-window-handle", + "smallvec", + "tracing", + "typed-arena", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c266a580d5cc13410797edc1bd71518033792945c25bc071a8d3bbdc46710de" +dependencies = [ + "arrayvec", + "bitflags", + "copyless", + "fxhash", + "gfx-backend-dx11", + "gfx-backend-dx12", + "gfx-backend-empty", + "gfx-backend-metal", + "gfx-backend-vulkan", + "gfx-descriptor", + "gfx-hal", + "gfx-memory", + "naga", + "parking_lot", + "raw-window-handle", + "smallvec", + "thiserror", + "tracing", + "wgpu-types", +] + +[[package]] +name = "wgpu-types" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e3529528e608b54838ee618c3923b0f46e6db0334cfc6c42a16cf4ceb3bdb57" +dependencies = [ + "bitflags", +] + [[package]] name = "which" version = "4.0.2" @@ -3090,6 +3592,15 @@ dependencies = [ "toml", ] +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -3099,3 +3610,13 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] + +[[package]] +name = "x11" +version = "2.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773" +dependencies = [ + "libc", + "pkg-config", +] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 603954fdf66ccc..95be6bf1b6f0e4 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -75,6 +75,7 @@ walkdir = "2.3.1" warp = { version = "0.2.5", features = ["tls"] } semver-parser = "0.9.0" uuid = { version = "0.8.1", features = ["v4"] } +wgpu = "0.6.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] } diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index b1ec5c344f6f8b..e137f5361bafe9 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -23,6 +23,7 @@ pub mod timers; pub mod tls; pub mod tty; pub mod web_worker; +pub mod webgpu; pub mod websocket; pub mod worker_host; diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs new file mode 100644 index 00000000000000..7d87f1969257e6 --- /dev/null +++ b/cli/ops/webgpu/buffer.rs @@ -0,0 +1,126 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::bad_resource_id; +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateBufferArgs { + rid: u32, + label: Option, + size: u64, + usage: (), // TODO + mapped_at_creation: Option, +} + +pub fn op_webgpu_create_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateBufferArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: args.label.map(|label| &label), + size: args.size, + usage: (), // TODO + mapped_at_creation: args.mapped_at_creation.unwrap_or(false), + }); + + let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct BufferGetMapAsyncArgs { + rid: u32, + mode: u32, +} + +pub async fn op_webgpu_buffer_get_map_async( + state: Rc>, + args: Value, + _bufs: BufVec, +) -> Result { + let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; + + let mut state = state.borrow_mut(); + let buffer = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + buffer.slice(..).map_async().await; // TODO + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct BufferGetMappedRangeArgs { + rid: u32, + offset: u64, + size: Option, +} + +pub fn op_webgpu_buffer_get_mapped_range( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; + + let buffer = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let end = args.size.map(|size| size + args.offset); + + let slice = buffer.slice(args.offset..end); // TODO + let view = slice.get_mapped_range(); + view[0]; // TODO + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct BufferUnmapArgs { + rid: u32, +} + +pub fn op_webgpu_buffer_unmap( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: BufferUnmapArgs = serde_json::from_value(args)?; + + let buffer = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + buffer.unmap(); + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs new file mode 100644 index 00000000000000..93f57e7a286070 --- /dev/null +++ b/cli/ops/webgpu/mod.rs @@ -0,0 +1,178 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +mod buffer; +mod texture; + +use deno_core::error::bad_resource_id; +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +pub fn init(rt: &mut deno_core::JsRuntime) { + super::reg_json_async( + rt, + "op_webgpu_request_adapter", + op_webgpu_request_adapter, + ); + super::reg_json_async( + rt, + "op_webgpu_request_device", + op_webgpu_request_device, + ); + + super::reg_json_sync( + rt, + "op_webgpu_create_buffer", + buffer::op_webgpu_create_buffer, + ); + super::reg_json_async( + rt, + "op_webgpu_buffer_get_map_async", + buffer::op_webgpu_buffer_get_map_async, + ); + super::reg_json_async( + rt, + "op_webgpu_buffer_get_mapped_range", + buffer::op_webgpu_buffer_get_mapped_range, + ); + super::reg_json_sync( + rt, + "op_webgpu_buffer_unmap", + buffer::op_webgpu_buffer_unmap, + ); + + super::reg_json_sync( + rt, + "op_webgpu_create_texture", + texture::op_webgpu_create_texture, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_texture_view", + texture::op_webgpu_create_texture_view, + ); +} + +fn serialize_features(features: &wgpu::Features) -> Vec<&str> { + let mut extensions: Vec<&str> = vec![]; + + if features.contains(wgpu::Features::DEPTH_CLAMPING) { + extensions.push("depth-clamping"); + } + if features.contains(wgpu::Features) { + // TODO + extensions.push("depth24unorm-stencil8"); + } + if features.contains(wgpu::Features) { + // TODO + extensions.push("depth32float-stencil8"); + } + if features.contains(wgpu::Features) { + // TODO + extensions.push("pipeline-statistics-query"); + } + if features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC) { + extensions.push("texture-compression-bc"); + } + if features.contains(wgpu::Features) { + // TODO + extensions.push("timestamp-query"); + } + + extensions +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RequestAdapterArgs { + power_preference: Option, +} + +pub async fn op_webgpu_request_adapter( + state: Rc>, + args: Value, + _bufs: BufVec, +) -> Result { + let args: RequestAdapterArgs = serde_json::from_value(args)?; + + let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); // TODO: own op + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: match args.power_preference { + Some(&"low-power") => wgpu::PowerPreference::LowPower, + Some(&"high-performance") => wgpu::PowerPreference::HighPerformance, + Some(_) => unreachable!(), + None => wgpu::PowerPreference::Default, + }, + compatible_surface: None, // windowless + }) + .await + .unwrap(); // TODO: dont unwrap + + let name = adapter.get_info().name; + let extensions = serialize_features(&adapter.features()); + + let mut state = state.borrow_mut(); + let rid = state.resource_table.add("webGPUAdapter", Box::new(adapter)); + + Ok(json!({ + "rid": rid, + "name": name, + "extensions": extensions, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RequestDeviceArgs { + rid: u32, + extensions: Option<[String]>, + limits: Option, // TODO +} + +pub async fn op_webgpu_request_device( + state: Rc>, + args: Value, + _bufs: BufVec, +) -> Result { + let args: RequestDeviceArgs = serde_json::from_value(args)?; + + let mut state = state.borrow_mut(); + let adapter = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + features: Default::default(), // TODO + limits: Default::default(), // TODO + shader_validation: false, // TODO + }, + None, // debug + ) + .await + .unwrap(); // TODO: dont unwrap + + let extensions = serialize_features(&device.features()); + let limits = device.limits(); + + let device_rid = state.resource_table.add("webGPUDevice", Box::new(device)); + + let queue_rid = state.resource_table.add("webGPUQueue", Box::new(queue)); + + Ok(json!({ + "deviceRid": device_rid, + "queueRid": queue_rid, + "extensions": extensions, + "limits", // TODO + })) +} diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs new file mode 100644 index 00000000000000..47366361f376b3 --- /dev/null +++ b/cli/ops/webgpu/texture.rs @@ -0,0 +1,205 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +fn serialize_texture_format( + format: &String, +) -> Result { + let texture_format = match *format { + // 8-bit formats + &"r8unorm" => wgpu::TextureFormat::R8Unorm, + &"r8snorm" => wgpu::TextureFormat::R8Snorm, + &"r8uint" => wgpu::TextureFormat::R8Uint, + &"r8sint" => wgpu::TextureFormat::R8Sint, + + // 16-bit formats + &"r16uint" => wgpu::TextureFormat::R16Uint, + &"r16sint" => wgpu::TextureFormat::R16Sint, + &"r16float" => wgpu::TextureFormat::R16Float, + &"rg8unorm" => wgpu::TextureFormat::Rg8Unorm, + &"rg8snorm" => wgpu::TextureFormat::Rg8Snorm, + &"rg8uint" => wgpu::TextureFormat::Rg8Uint, + &"rg8sint" => wgpu::TextureFormat::Rg8Sint, + + // 32-bit formats + &"r32uint" => wgpu::TextureFormat::R32Uint, + &"r32sint" => wgpu::TextureFormat::R32Sint, + &"r32float" => wgpu::TextureFormat::R32Float, + &"rg16uint" => wgpu::TextureFormat::Rg16Uint, + &"rg16sint" => wgpu::TextureFormat::Rg16Sint, + &"rg16float" => wgpu::TextureFormat::Rg16Float, + &"rgba8unorm" => wgpu::TextureFormat::Rgba8Unorm, + &"rgba8unorm-srgb" => wgpu::TextureFormat::Rgba8UnormSrgb, + &"rgba8snorm" => wgpu::TextureFormat::Rgba8Snorm, + &"rgba8uint" => wgpu::TextureFormat::Rgba8Uint, + &"rgba8sint" => wgpu::TextureFormat::Rgba8Sint, + &"bgra8unorm" => wgpu::TextureFormat::Bgra8Unorm, + &"bgra8unorm-srgb" => wgpu::TextureFormat::Bgra8UnormSrgb, + // Packed 32-bit formats + &"rgb9e5ufloat" => return Err(not_supported()), // wgpu-rs#590 + &"rgb10a2unorm" => wgpu::TextureFormat::Rgb10a2Unorm, + &"rg11b10ufloat" => wgpu::TextureFormat::Rg11b10Float, + + // 64-bit formats + &"rg32uint" => wgpu::TextureFormat::Rg32Uint, + &"rg32sint" => wgpu::TextureFormat::Rg32Sint, + &"rg32float" => wgpu::TextureFormat::Rg32Float, + &"rgba16uint" => wgpu::TextureFormat::Rgba16Uint, + &"rgba16sint" => wgpu::TextureFormat::Rgba16Sint, + &"rgba16float" => wgpu::TextureFormat::Rgba16Float, + + // 128-bit formats + &"rgba32uint" => wgpu::TextureFormat::Rgba32Uint, + &"rgba32sint" => wgpu::TextureFormat::Rgba32Sint, + &"rgba32float" => wgpu::TextureFormat::Rgba32Float, + + // Depth and stencil formats + &"stencil8" => return Err(not_supported()), // wgpu-rs#590 + &"depth16unorm" => return Err(not_supported()), // wgpu-rs#590 + &"depth24plus" => wgpu::TextureFormat::Depth24Plus, + &"depth24plus-stencil8" => wgpu::TextureFormat::Depth24PlusStencil8, + &"depth32float" => wgpu::TextureFormat::Depth32Float, + + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + &"bc1-rgba-unorm" => wgpu::TextureFormat::Bc1RgbaUnorm, + &"bc1-rgba-unorm-srgb" => wgpu::TextureFormat::Bc1RgbaUnormSrgb, + &"bc2-rgba-unorm" => wgpu::TextureFormat::Bc2RgbaUnorm, + &"bc2-rgba-unorm-srgb" => wgpu::TextureFormat::Bc2RgbaUnormSrgb, + &"bc3-rgba-unorm" => wgpu::TextureFormat::Bc3RgbaUnorm, + &"bc3-rgba-unorm-srgb" => wgpu::TextureFormat::Bc3RgbaUnormSrgb, + &"bc4-r-unorm" => wgpu::TextureFormat::Bc4RUnorm, + &"bc4-r-snorm" => wgpu::TextureFormat::Bc4RSnorm, + &"bc5-rg-unorm" => wgpu::TextureFormat::Bc5RgUnorm, + &"bc5-rg-snorm" => wgpu::TextureFormat::Bc5RgSnorm, + &"bc6h-rgb-ufloat" => wgpu::TextureFormat::Bc6hRgbUfloat, + &"bc6h-rgb-float" => wgpu::TextureFormat::Bc6hRgbSfloat, // wgpu-rs#590 + &"bc7-rgba-unorm" => wgpu::TextureFormat::Bc7RgbaUnorm, + &"bc7-rgba-unorm-srgb" => wgpu::TextureFormat::Bc7RgbaUnormSrgb, + + // "depth24unorm-stencil8" extension + &"depth24unorm-stencil8" => return Err(not_supported()), // wgpu-rs#590 + + // "depth32float-stencil8" extension + &"depth32float-stencil8" => return Err(not_supported()), // wgpu-rs#590 + _ => unreachable!(), + }; + + Ok(texture_format) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateTextureArgs { + rid: u32, + label: Option, + mip_level_count: Option, + sample_count: Option, + dimension: Option, + format: String, + usage: (), // TODO +} + +pub fn op_webgpu_create_texture( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateTextureArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: args.label.map(|label| &label), + size: Default::default(), // TODO + mip_level_count: args.mip_level_count.unwrap_or(1), + sample_count: args.sample_count.unwrap_or(1), + dimension: match args.dimension { + Some(&"1d") => wgpu::TextureDimension::D1, + Some(&"2d") => wgpu::TextureDimension::D2, + Some(&"3d") => wgpu::TextureDimension::D3, + Some(_) => unreachable!(), + None => wgpu::TextureDimension::D2, + }, + format: serialize_texture_format(&args.format)?, + usage: (), // TODO + }); + + let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); + + Ok(json!({ + "rid": rid, + })) +} +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateTextureViewArgs { + rid: u32, + label: Option, + format: Option, + dimension: Option, + aspect: Option, + base_mip_level: Option, + mip_level_count: Option, + base_array_layer: Option, + array_layer_count: Option, +} + +pub fn op_webgpu_create_texture_view( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateTextureViewArgs = serde_json::from_value(args)?; + + let texture = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let texture_view = texture.create_view(&wgpu::TextureViewDescriptor { + label: args.label.map(|label| &label), + format: args.format.map(|format| serialize_texture_format(&format)?), + dimension: args.dimension.map(|dimension| match dimension { + &"1d" => wgpu::TextureViewDimension::D1, + &"2d" => wgpu::TextureViewDimension::D2, + &"2d-array" => wgpu::TextureViewDimension::D2Array, + &"cube" => wgpu::TextureViewDimension::Cube, + &"cube-array" => wgpu::TextureViewDimension::CubeArray, + &"3d" => wgpu::TextureViewDimension::D3, + _ => unreachable!(), + }), + aspect: match args.aspect { + Some(&"all") => wgpu::TextureAspect::All, + Some(&"stencil-only") => wgpu::TextureAspect::StencilOnly, + Some(&"depth-only") => wgpu::TextureAspect::DepthOnly, + Some(_) => unreachable!(), + None => wgpu::TextureAspect::All, + }, + base_mip_level: args.base_mip_level.unwrap_or(0), + level_count: args.mip_level_count, // TODO + base_array_layer: args.base_array_layer.unwrap_or(0), + array_layer_count: args.array_layer_count, // TODO + }); + + let rid = state + .resource_table + .add("webGPUTextureView", Box::new(texture_view)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js new file mode 100644 index 00000000000000..867194c9cd6c22 --- /dev/null +++ b/cli/rt/14_webgpu.js @@ -0,0 +1,148 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +((window) => { + const core = window.Deno.core; + + const GPU = { + async requestAdapter(options = {}) { + const { rid, name, extensions } = await core.jsonOpAsync( + "op_webgpu_request_adapter", + options, + ); + return new GPUAdapter(rid, name, extensions); + }, + }; + + class GPUAdapter { + #rid; + #name; + get name() { + return this.#name; + } + #extensions; + get extensions() { + return this.#extensions; + } + // TODO: limits + + constructor(rid, name, extensions) { + this.#rid = rid; + this.#name = name; + this.#extensions = Object.freeze(extensions); + } + + async requestDevice(descriptor = {}) { + const data = await core.jsonOpAsync("op_webgpu_request_device", { + rid: this.#rid, + ...descriptor, + }); + + return new GPUDevice(this, data); + } + } + + class GPUDevice extends EventTarget { + #deviceRid; + #adapter; + get adapter() { + return this.#adapter; + } + #extensions; + get extensions() { + return this.#extensions; + } + #limits; + get limits() { + return this.#limits; + } + #defaultQueue; + get defaultQueue() { + return this.#defaultQueue; + } + + constructor(adapter, data) { + super(); + + this.#adapter = adapter; + this.#deviceRid = data.deviceRid; + } + + createBuffer(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { + rid: this.#deviceRid, + ...descriptor, + }); + + return new GPUBuffer(rid); + } + + createTexture(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_texture", { + rid: this.#deviceRid, + ...descriptor, + }); + + new GPUTexture(rid); + } + } + + class GPUBuffer { + #rid; + + constructor(rid) { + this.#rid = rid; + } + + async mapAsync(mode, offset = 0, size = undefined) { + await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { + rid: this.#rid, + offset, + size, + }); + } + getMappedRange(offset = 0, size = undefined) { + core.jsonOpSync("op_webgpu_buffer_get_mapped_range", { + rid: this.#rid, + offset, + size, + }); // TODO + } + unmap() { + core.jsonOpSync("op_webgpu_buffer_unmap", { + rid: this.#rid, + }); + } + + destroy() { + } // TODO + } + + class GPUTexture { + #rid; + constructor(rid) { + this.#rid = rid; + } + + createView(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { + rid: this.#deviceRid, + ...descriptor, + }); + + new GPUTextureView(rid); + } + + destroy() {} // TODO + } + + class GPUTextureView { + #rid; + constructor(rid) { + this.#rid = rid; + } + } + + window.__bootstrap.webGPU = { + webGPU: GPU, + }; +})(this); From 3112ee4ee8778d6d2a077e73ed04c5c852571049 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 9 Oct 2020 06:53:25 +0200 Subject: [PATCH 002/144] up to pipeline --- cli/ops/webgpu/binding.rs | 253 ++++++++++++++++++++ cli/ops/webgpu/mod.rs | 49 ++++ cli/ops/webgpu/pipeline.rs | 474 +++++++++++++++++++++++++++++++++++++ cli/ops/webgpu/sampler.rs | 98 ++++++++ cli/ops/webgpu/shader.rs | 45 ++++ cli/ops/webgpu/texture.rs | 39 +-- cli/rt/14_webgpu.js | 212 ++++++++++++++++- cli/worker.rs | 2 + 8 files changed, 1144 insertions(+), 28 deletions(-) create mode 100644 cli/ops/webgpu/binding.rs create mode 100644 cli/ops/webgpu/pipeline.rs create mode 100644 cli/ops/webgpu/sampler.rs create mode 100644 cli/ops/webgpu/shader.rs diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs new file mode 100644 index 00000000000000..4194c954026d1c --- /dev/null +++ b/cli/ops/webgpu/binding.rs @@ -0,0 +1,253 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use super::texture::{serialize_dimension, serialize_texture_format}; +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +fn serialize_texture_component_type( + component_type: String, +) -> Result { + Ok(match component_type { + &"float" => wgpu::TextureComponentType::Float, + &"sint" => wgpu::TextureComponentType::Sint, + &"uint" => wgpu::TextureComponentType::Uint, + &"depth-comparison" => return Err(not_supported()), + _ => unreachable!(), + }) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUBindGroupLayoutEntry { + binding: u32, + visibility: u32, + #[serde(rename = "type")] + kind: String, + has_dynamic_offset: Option, + min_buffer_binding_size: Option, + view_dimension: Option, + texture_component_type: Option, + storage_texture_format: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateBindGroupLayoutArgs { + rid: u32, + label: Option, + entries: [GPUBindGroupLayoutEntry], +} + +pub fn op_webgpu_create_bind_group_layout( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: args.label.map(|label| &label), + entries: &args + .entries + .iter() + .map(|entry| { + wgpu::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgpu::ShaderStage::from_bits(entry.visibility).unwrap(), // TODO + ty: match entry.kind { + &"uniform-buffer" => wgpu::BindingType::UniformBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + }, + &"storage-buffer" => wgpu::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: false, + }, + &"readonly-storage-buffer" => wgpu::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: true, + }, + &"sampler" => wgpu::BindingType::Sampler { comparison: false }, + &"comparison-sampler" => { + wgpu::BindingType::Sampler { comparison: true } + } + &"sampled-texture" => wgpu::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, // TODO + multisampled: false, + }, + &"multisampled-texture" => wgpu::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, // TODO + multisampled: true, + }, + &"readonly-storage-texture" => { + wgpu::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, // TODO + readonly: true, + } + } + &"writeonly-storage-texture" => { + wgpu::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, // TODO + readonly: false, + } + } + _ => unreachable!(), + }, + count: None, // TODO + } + }) + .collect::<[wgpu::BindGroupLayoutEntry]>(), + }); + + let rid = state + .resource_table + .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreatePipelineLayoutArgs { + rid: u32, + label: Option, + bind_group_layouts: [u32], +} + +pub fn op_webgpu_create_pipeline_layout( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: args.label.map(|label| &label), + bind_group_layouts: &args + .bind_group_layouts + .iter() + .map(|rid| { + state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::<[&wgpu::BindGroupLayout]>(), + push_constant_ranges: &[], // TODO + }); + + let rid = state + .resource_table + .add("webGPUPipelineLayout", Box::new(pipeline_layout)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUBindGroupEntry { + binding: u32, + resource_kind: String, + resource: u32, // TODO +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateBindGroupArgs { + rid: u32, + label: Option, + layout: u32, + entries: [GPUBindGroupEntry], +} + +pub fn op_webgpu_create_bind_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateBindGroupArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: args.label.map(|label| &label), + layout: state + .resource_table + .get_mut::(args.layout) + .ok_or_else(bad_resource_id)?, + entries: &args + .entries + .iter() + .map(|entry| { + let resource = state + .resource_table + .get_mut(entry.resource) + .ok_or_else(bad_resource_id)?; + + wgpu::BindGroupEntry { + binding: entry.binding, + resource: match entry.resource_kind { + &"GPUSampler" => { + wgpu::BindingResource::Sampler(resource as &mut wgpu::Sampler) + } + &"GPUTextureView" => wgpu::BindingResource::TextureView( + resource as &mut wgpu::TextureView, + ), + &"GPUBufferBinding" => wgpu::BindingResource::Buffer(), // TODO + _ => unreachable!(), + }, + } + }) + .collect::<[wgpu::BindGroupEntry]>(), + }); + + let rid = state + .resource_table + .add("webGPUBindGroup", Box::new(bind_group)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 93f57e7a286070..a82ceeebbceaff 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -1,7 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +mod binding; mod buffer; +mod pipeline; +mod sampler; +mod shader; mod texture; +mod command_buffer; use deno_core::error::bad_resource_id; use deno_core::error::type_error; @@ -58,6 +63,49 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_create_texture_view", texture::op_webgpu_create_texture_view, ); + + super::reg_json_sync( + rt, + "op_webgpu_create_sampler", + sampler::op_webgpu_create_sampler, + ); + + super::reg_json_sync( + rt, + "op_webgpu_create_bind_group_layout", + binding::op_webgpu_create_bind_group_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_pipeline_layout", + binding::op_webgpu_create_pipeline_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_bind_group", + binding::op_webgpu_create_bind_group, + ); + + super::reg_json_sync( + rt, + "op_webgpu_create_compute_pipeline", + pipeline::op_webgpu_create_compute_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pipeline_get_bind_group_layout", + pipeline::op_webgpu_compute_pipeline_get_bind_group_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_render_pipeline", + pipeline::op_webgpu_create_render_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pipeline_get_bind_group_layout", + pipeline::op_webgpu_render_pipeline_get_bind_group_layout, + ); } fn serialize_features(features: &wgpu::Features) -> Vec<&str> { @@ -153,6 +201,7 @@ pub async fn op_webgpu_request_device( let (device, queue) = adapter .request_device( &wgpu::DeviceDescriptor { + // TODO: should accept label features: Default::default(), // TODO limits: Default::default(), // TODO shader_validation: false, // TODO diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs new file mode 100644 index 00000000000000..45b55e68a9fec6 --- /dev/null +++ b/cli/ops/webgpu/pipeline.rs @@ -0,0 +1,474 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use super::sampler::serialize_compare_function; +use super::texture::serialize_texture_format; +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +fn serialize_programmable_stage_descriptor( + state: &mut OpState, + programmable_stage_descriptor: GPUProgrammableStageDescriptor, +) -> Result { + Ok(wgpu::ProgrammableStageDescriptor { + module: state + .resource_table + .get_mut::(programmable_stage_descriptor.module) + .ok_or_else(bad_resource_id)?, + entry_point: &programmable_stage_descriptor.entry_point, + }) +} + +fn serialize_stencil_operation(operation: String) -> wgpu::StencilOperation { + match operation { + &"keep" => wgpu::StencilOperation::Keep, + &"zero" => wgpu::StencilOperation::Zero, + &"replace" => wgpu::StencilOperation::Replace, + &"invert" => wgpu::StencilOperation::Invert, + &"increment-clamp" => wgpu::StencilOperation::IncrementClamp, + &"decrement-clamp" => wgpu::StencilOperation::DecrementClamp, + &"increment-wrap" => wgpu::StencilOperation::IncrementWrap, + &"decrement-wrap" => wgpu::StencilOperation::DecrementWrap, + _ => unreachable!(), + } +} + +fn serialize_stencil_state_face_descriptor( + state: GPUStencilStateFaceDescriptor, +) -> wgpu::StencilStateFaceDescriptor { + wgpu::StencilStateFaceDescriptor { + compare: state + .compare + .map_or(wgpu::CompareFunction::Always, |compare| { + serialize_compare_function(compare) + }), + fail_op: state.fail_op.map_or(wgpu::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), + depth_fail_op: state + .depth_fail_op + .map_or(wgpu::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), + pass_op: state.pass_op.map_or(wgpu::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), + } +} + +fn serialize_blend_factor(blend_factor: String) -> wgpu::BlendFactor { + match blend_factor { + &"zero" => wgpu::BlendFactor::Zero, + &"one" => wgpu::BlendFactor::One, + &"src-color" => wgpu::BlendFactor::SrcColor, + &"one-minus-src-color" => wgpu::BlendFactor::OneMinusSrcColor, + &"src-alpha" => wgpu::BlendFactor::SrcAlpha, + &"one-minus-src-alpha" => wgpu::BlendFactor::OneMinusSrcAlpha, + &"dst-color" => wgpu::BlendFactor::DstColor, + &"one-minus-dst-color" => wgpu::BlendFactor::OneMinusDstColor, + &"dst-alpha" => wgpu::BlendFactor::DstAlpha, + &"one-minus-dst-alpha" => wgpu::BlendFactor::OneMinusDstAlpha, + &"src-alpha-saturated" => wgpu::BlendFactor::SrcAlphaSaturated, + &"blend-color" => wgpu::BlendFactor::BlendColor, + &"one-minus-blend-color" => wgpu::BlendFactor::OneMinusBlendColor, + _ => unreachable!(), + } +} + +fn serialize_blend_descriptor(blend: GPUBlendDescriptor) -> wgpu::BlendDescriptor { + wgpu::BlendDescriptor { + src_factor: blend.src_factor.map_or(wgpu::BlendFactor::One, serialize_blend_factor), + dst_factor: blend.dst_factor.map_or(wgpu::BlendFactor::Zero, serialize_blend_factor), + operation: match blend.operation { + Some(&"add") => wgpu::BlendOperation::Add, + Some(&"subtract") => wgpu::BlendOperation::Subtract, + Some(&"reverse-subtract") => wgpu::BlendOperation::ReverseSubtract, + Some(&"min") => wgpu::BlendOperation::Min, + Some(&"max") => wgpu::BlendOperation::Max, + Some(_) => unreachable!(), + None => wgpu::BlendOperation::Add, + } + } +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUProgrammableStageDescriptor { + module: u32, + entry_point: String, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateComputePipelineArgs { + rid: u32, + label: Option, + layout: Option, + compute_stage: GPUProgrammableStageDescriptor, +} + +pub fn op_webgpu_create_compute_pipeline( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateComputePipelineArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let compute_pipeline = + device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: args.label.map(|label| &label), + layout: args.layout.map(|rid| { + state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)? + }), + compute_stage: serialize_programmable_stage_descriptor( + state, + args.compute_stage, + )?, + }); + + let rid = state + .resource_table + .add("webGPUComputePipeline", Box::new(compute_pipeline)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePipelineGetBindGroupLayoutArgs { + rid: u32, + index: u32, +} + +pub fn op_webgpu_compute_pipeline_get_bind_group_layout( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePipelineGetBindGroupLayoutArgs = + serde_json::from_value(args)?; + + let compute_pipeline = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let bind_group_layout = compute_pipeline.get_bind_group_layout(args.index); + + let rid = state + .resource_table + .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPURasterizationStateDescriptor { + front_face: Option, + cull_mode: Option, + clamp_depth: Option, + depth_bias: Option, + depth_bias_slope_scale: Option, + depth_bias_clamp: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUBlendDescriptor { + src_factor: Option, + dst_factor: Option, + operation: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUColorStateDescriptor { + format: String, + alpha_blend: Option, + color_blend: Option, + write_mask: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUStencilStateFaceDescriptor { + compare: Option, + fail_op: Option, + depth_fail_op: Option, + pass_op: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUDepthStencilStateDescriptor { + format: String, + depth_write_enabled: Option, + depth_compare: Option, + stencil_front: Option, + stencil_back: Option, + stencil_read_mask: Option, + stencil_write_mask: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUVertexAttributeDescriptor { + format: String, + offset: u64, + shader_location: u32, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUVertexBufferLayoutDescriptor { + array_stride: u64, + step_mode: Option, + attributes: [GPUVertexAttributeDescriptor], +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUVertexStateDescriptor { + index_format: Option, + vertex_buffers: Option<[GPUVertexBufferLayoutDescriptor]>, // TODO: nullable +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateRenderPipelineArgs { + rid: u32, + label: Option, + layout: Option, + vertex_stage: GPUProgrammableStageDescriptor, + fragment_stage: Option, + primitive_topology: String, + rasterization_state: Option, + color_states: [GPUColorStateDescriptor], + depth_stencil_state: Option, + vertex_state: Option, + sample_count: Option, + sample_mask: Option, + alpha_to_coverage_enabled: Option, +} + +pub fn op_webgpu_create_render_pipeline( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let render_pipeline = + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: args.label.map(|label| &label), + layout: args.layout.map(|rid| { + state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)? + }), + vertex_stage: serialize_programmable_stage_descriptor( + state, + args.vertex_stage, + )?, + fragment_stage: args.fragment_stage.map( + |programmable_stage_descriptor| { + serialize_programmable_stage_descriptor( + state, + programmable_stage_descriptor, + )? + }, + ), + rasterization_state: args.rasterization_state.map( + |rasterization_state| wgpu::RasterizationStateDescriptor { + front_face: match rasterization_state.front_face { + Some(&"ccw") => wgpu::FrontFace::Ccw, + Some(&"cw") => wgpu::FrontFace::Cw, + Some(_) => unreachable!(), + None => wgpu::FrontFace::Ccw, + }, + cull_mode: match rasterization_state.cull_mode { + Some(&"none") => wgpu::CullMode::None, + Some(&"front") => wgpu::CullMode::Front, + Some(&"back") => wgpu::CullMode::Back, + Some(_) => unreachable!(), + None => wgpu::CullMode::None, + }, + clamp_depth: rasterization_state.clamp_depth.unwrap_or(false), + depth_bias: rasterization_state.depth_bias.unwrap_or(0), + depth_bias_slope_scale: rasterization_state + .depth_bias_slope_scale + .unwrap_or(0.0), + depth_bias_clamp: rasterization_state.depth_bias_clamp.unwrap_or(0.0), + }, + ), + primitive_topology: match args.primitive_topology { + &"point-list" => wgpu::PrimitiveTopology::PointList, + &"line-list" => wgpu::PrimitiveTopology::LineList, + &"line-strip" => wgpu::PrimitiveTopology::LineStrip, + &"triangle-list" => wgpu::PrimitiveTopology::TriangleList, + &"triangle-strip" => wgpu::PrimitiveTopology::TriangleStrip, + _ => unreachable!(), + }, + color_states: &args + .color_states + .iter() + .map(|color_state| { + wgpu::ColorStateDescriptor { + format: serialize_texture_format(color_state.format.clone())?, + alpha_blend: color_state.alpha_blend.map_or("", serialize_blend_descriptor), // TODO + color_blend: color_state.color_blend.map_or("", serialize_blend_descriptor), // TODO + write_mask: color_state.write_mask, // TODO + } + }) + .collect::<[wgpu::ColorStateDescriptor]>(), + depth_stencil_state: args.depth_stencil_state.map(|state| { + wgpu::DepthStencilStateDescriptor { + format: serialize_texture_format(state.format)?, + depth_write_enabled: state.depth_write_enabled.unwrap_or(false), + depth_compare: state.depth_compare.map_or(wgpu::CompareFunction::Always, serialize_compare_function), + stencil: wgpu::StencilStateDescriptor { + front: state.stencil_front.map_or(wgpu::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor), + back: state.stencil_front.map_or(wgpu::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor), + read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), + write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), + }, + } + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: args.vertex_state.unwrap().index_format.map_or("", |format| match format { // TODO + &"uint16" => wgpu::IndexFormat::Uint16, + &"uint32" => wgpu::IndexFormat::Uint32, + _ => unreachable!(), + }), + vertex_buffers: &args + .vertex_state + .unwrap() + .vertex_buffers + .unwrap() // TODO + .iter() + .map(|buffer| { + wgpu::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode { + Some(&"vertex") => wgpu::InputStepMode::Vertex, + Some(&"instance") => wgpu::InputStepMode::Instance, + Some(_) => unreachable!(), + None => wgpu::InputStepMode::Vertex, + }, + attributes: &buffer + .attributes + .iter() + .map(|attribute| wgpu::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format { + &"uchar2" => wgpu::VertexFormat::Uchar2, + &"uchar4" => wgpu::VertexFormat::Uchar4, + &"char2" => wgpu::VertexFormat::Char2, + &"char4" => wgpu::VertexFormat::Char4, + &"uchar2norm" => wgpu::VertexFormat::Uchar2Norm, + &"uchar4norm" => wgpu::VertexFormat::Uchar4, + &"char2norm" => wgpu::VertexFormat::Char2Norm, + &"char4norm" => wgpu::VertexFormat::Char4Norm, + &"ushort2" => wgpu::VertexFormat::Ushort2, + &"ushort4" => wgpu::VertexFormat::Ushort4, + &"short2" => wgpu::VertexFormat::Short2, + &"short4" => wgpu::VertexFormat::Short4, + &"ushort2norm" => wgpu::VertexFormat::Ushort2Norm, + &"ushort4norm" => wgpu::VertexFormat::Ushort4Norm, + &"short2norm" => wgpu::VertexFormat::Short2Norm, + &"short4norm" => wgpu::VertexFormat::Short4Norm, + &"half2" => wgpu::VertexFormat::Half2, + &"half4" => wgpu::VertexFormat::Half4, + &"float" => wgpu::VertexFormat::Float, + &"float2" => wgpu::VertexFormat::Float2, + &"float3" => wgpu::VertexFormat::Float3, + &"float4" => wgpu::VertexFormat::Float4, + &"uint" => wgpu::VertexFormat::Uint, + &"uint2" => wgpu::VertexFormat::Uint2, + &"uint3" => wgpu::VertexFormat::Uint3, + &"uint4" => wgpu::VertexFormat::Uint4, + &"int" => wgpu::VertexFormat::Int, + &"int2" => wgpu::VertexFormat::Int2, + &"int3" => wgpu::VertexFormat::Int3, + &"int4" => wgpu::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::<[wgpu::VertexAttributeDescriptor]>(), + } + }) + .collect::<[wgpu::VertexBufferDescriptor]>(), + }, + sample_count: args.sample_count.unwrap_or(1), + sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), + alpha_to_coverage_enabled: args + .alpha_to_coverage_enabled + .unwrap_or(false), + }); + + let rid = state + .resource_table + .add("webGPURenderPipeline", Box::new(render_pipeline)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPipelineGetBindGroupLayoutArgs { + rid: u32, + index: u32, +} + +pub fn op_webgpu_render_pipeline_get_bind_group_layout( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + + let render_pipeline = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let bind_group_layout = render_pipeline.get_bind_group_layout(args.index); + + let rid = state + .resource_table + .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs new file mode 100644 index 00000000000000..e2147d59a20b2a --- /dev/null +++ b/cli/ops/webgpu/sampler.rs @@ -0,0 +1,98 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +fn serialize_address_mode(address_mode: Option) -> wgpu::AddressMode { + match address_mode { + Some(&"clamp-to-edge") => wgpu::AddressMode::ClampToEdge, + Some(&"repeat") => wgpu::AddressMode::Repeat, + Some(&"mirror-repeat") => wgpu::AddressMode::MirrorRepeat, + Some(_) => unreachable!(), + None => wgpu::AddressMode::ClampToEdge, + } +} + +fn serialize_filter_mode(filter_mode: Option) -> wgpu::FilterMode { + match filter_mode { + Some(&"nearest") => wgpu::FilterMode::Nearest, + Some(&"linear") => wgpu::FilterMode::Linear, + Some(_) => unreachable!(), + None => wgpu::FilterMode::Nearest, + } +} + +pub fn serialize_compare_function(compare: String) -> wgpu::CompareFunction { + match compare { + &"never" => wgpu::CompareFunction::Never, + &"less" => wgpu::CompareFunction::Less, + &"equal" => wgpu::CompareFunction::Equal, + &"less-equal" => wgpu::CompareFunction::LessEqual, + &"greater" => wgpu::CompareFunction::Greater, + &"not-equal" => wgpu::CompareFunction::NotEqual, + &"greater-equal" => wgpu::CompareFunction::GreaterEqual, + &"always" => wgpu::CompareFunction::Always, + _ => unreachable!(), + } +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateSamplerArgs { + rid: u32, + label: Option, + address_mode_u: Option, + address_mode_v: Option, + address_mode_w: Option, + mag_filter: Option, + min_filter: Option, + mipmap_filter: Option, + lod_min_clamp: Option, + lod_max_clamp: Option, + compare: Option, + max_anisotropy: Option, +} + +pub fn op_webgpu_create_sampler( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateSamplerArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: args.label.map(|label| &label), + address_mode_u: serialize_address_mode(args.address_mode_u), + address_mode_v: serialize_address_mode(args.address_mode_v), + address_mode_w: serialize_address_mode(args.address_mode_w), + mag_filter: serialize_filter_mode(args.mag_filter), + min_filter: serialize_filter_mode(args.min_filter), + mipmap_filter: serialize_filter_mode(args.mipmap_filter), + lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), + lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO + compare: args + .compare + .map(|compare| serialize_compare_function(compare)), + anisotropy_clamp: args.max_anisotropy.unwrap_or(1), // TODO + }); + + let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs new file mode 100644 index 00000000000000..19e5c081b48e5b --- /dev/null +++ b/cli/ops/webgpu/shader.rs @@ -0,0 +1,45 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateShaderModuleArgs { + rid: u32, + label: Option, + code: String, + source_map: (), // TODO +} + +pub fn op_webgpu_create_shader_module( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateShaderModuleArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let shader_module = device.create_shader_module(wgpu::ShaderModuleSource); // TODO + + let rid = state + .resource_table + .add("webGPUShaderModule", Box::new(shader_module)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 47366361f376b3..04b4b52e5c760f 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -12,10 +12,10 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; -fn serialize_texture_format( - format: &String, +pub fn serialize_texture_format( + format: String, ) -> Result { - let texture_format = match *format { + Ok(match format { // 8-bit formats &"r8unorm" => wgpu::TextureFormat::R8Unorm, &"r8snorm" => wgpu::TextureFormat::R8Snorm, @@ -93,9 +93,7 @@ fn serialize_texture_format( // "depth32float-stencil8" extension &"depth32float-stencil8" => return Err(not_supported()), // wgpu-rs#590 _ => unreachable!(), - }; - - Ok(texture_format) + }) } #[derive(Deserialize)] @@ -134,7 +132,7 @@ pub fn op_webgpu_create_texture( Some(_) => unreachable!(), None => wgpu::TextureDimension::D2, }, - format: serialize_texture_format(&args.format)?, + format: serialize_texture_format(args.format)?, usage: (), // TODO }); @@ -144,6 +142,19 @@ pub fn op_webgpu_create_texture( "rid": rid, })) } + +pub fn serialize_dimension(dimension: String) -> wgpu::TextureViewDimension { + match dimension { + &"1d" => wgpu::TextureViewDimension::D1, + &"2d" => wgpu::TextureViewDimension::D2, + &"2d-array" => wgpu::TextureViewDimension::D2Array, + &"cube" => wgpu::TextureViewDimension::Cube, + &"cube-array" => wgpu::TextureViewDimension::CubeArray, + &"3d" => wgpu::TextureViewDimension::D3, + _ => unreachable!(), + } +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureViewArgs { @@ -172,16 +183,10 @@ pub fn op_webgpu_create_texture_view( let texture_view = texture.create_view(&wgpu::TextureViewDescriptor { label: args.label.map(|label| &label), - format: args.format.map(|format| serialize_texture_format(&format)?), - dimension: args.dimension.map(|dimension| match dimension { - &"1d" => wgpu::TextureViewDimension::D1, - &"2d" => wgpu::TextureViewDimension::D2, - &"2d-array" => wgpu::TextureViewDimension::D2Array, - &"cube" => wgpu::TextureViewDimension::Cube, - &"cube-array" => wgpu::TextureViewDimension::CubeArray, - &"3d" => wgpu::TextureViewDimension::D3, - _ => unreachable!(), - }), + format: args.format.map(|format| serialize_texture_format(format)?), + dimension: args + .dimension + .map(|dimension| serialize_dimension(dimension)), aspect: match args.aspect { Some(&"all") => wgpu::TextureAspect::All, Some(&"stencil-only") => wgpu::TextureAspect::StencilOnly, diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 867194c9cd6c22..dc77a14c837664 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -58,13 +58,15 @@ #defaultQueue; get defaultQueue() { return this.#defaultQueue; - } + } // TODO + + // TODO: should have label constructor(adapter, data) { super(); this.#adapter = adapter; - this.#deviceRid = data.deviceRid; + this.#deviceRid = data.deviceRid; // TODO: properties } createBuffer(descriptor) { @@ -73,7 +75,7 @@ ...descriptor, }); - return new GPUBuffer(rid); + return new GPUBuffer(rid, descriptor.label); // TODO } createTexture(descriptor) { @@ -82,15 +84,114 @@ ...descriptor, }); - new GPUTexture(rid); + return new GPUTexture(rid, descriptor.label); // TODO + } + + createSampler(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { + rid: this.#deviceRid, + ...descriptor, + }); + + const sampler = new GPUSampler(descriptor.label); + GPUSamplerMap.set(sampler, rid); + return sampler; + } + + createBindGroupLayout(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { + rid: this.#deviceRid, + ...descriptor, + }); + + const bindGroupLayout = new GPUBindGroupLayout(descriptor.label); + GPUBindGroupLayoutMap.set(bindGroupLayout, rid); + return bindGroupLayout; + } + + createPipelineLayout(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { + rid: this.#deviceRid, + label: descriptor.label, + bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => { + return GPUBindGroupLayoutMap.get(bindGroupLayout); + }), + }); + + const pipelineLayout = new GPUPipelineLayout(descriptor.label); + GPUPipelineLayoutMap.set(pipelineLayout, rid); + return pipelineLayout; + } + + createBindGroup(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { + rid: this.#deviceRid, + label: descriptor.label, + layout: GPUBindGroupLayoutMap.get(descriptor.layout), + entries: descriptor.entries.map((entry) => { + if (entry instanceof GPUSampler) { + return { + kind: "GPUSampler", + resource: GPUSamplerMap.get(entry), + }; + } else if (entry instanceof GPUTextureView) { + return { + kind: "GPUTextureView", + resource: GPUTextureViewMap.get(entry), + }; + } else { + // TODO + } + }), + }); + + const bindGroup = new GPUBindGroup(descriptor.label); + GPUBindGroupMap.set(bindGroup, rid); + return bindGroup; + } + + createShaderModule(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_shader_module", { + rid: this.#deviceRid, + ...descriptor, + }); + + const shaderModule = new GPUShaderModule(rid, descriptor.label); + GPUShaderModuleMap.set(shaderModule, rid); + return shaderModule; + } + + createComputePipeline(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { + rid: this.#deviceRid, + label: descriptor.label, + layout: descriptor.layout && + GPUPipelineLayoutMap.get(descriptor.layout), + computeStage: { + module: GPUShaderModuleMap.get(descriptor.computeStage.module), + entryPoint: descriptor.computeStage.entryPoint, + }, + }); + + return new GPUComputePipeline(rid, descriptor.label); + } + + createRenderPipeline(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { + rid: this.#deviceRid, + ...descriptor + }); + + return new GPURenderPipeline(rid, descriptor.label); } } class GPUBuffer { #rid; - constructor(rid) { + constructor(rid, label) { this.#rid = rid; + this.label = label; } async mapAsync(mode, offset = 0, size = undefined) { @@ -100,6 +201,7 @@ size, }); } + getMappedRange(offset = 0, size = undefined) { core.jsonOpSync("op_webgpu_buffer_get_mapped_range", { rid: this.#rid, @@ -107,38 +209,126 @@ size, }); // TODO } + unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { rid: this.#rid, }); } - destroy() { - } // TODO + destroy() {} // TODO } class GPUTexture { #rid; - constructor(rid) { + constructor(rid, label) { this.#rid = rid; + this.label = label; } createView(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { - rid: this.#deviceRid, + rid: this.#rid, ...descriptor, }); - new GPUTextureView(rid); + const view = new GPUTextureView(); + GPUTextureViewMap.set(view, rid); + return view; } destroy() {} // TODO } + const GPUTextureViewMap = new WeakMap(); class GPUTextureView { + constructor(label) { + this.label = label; + } + } + + const GPUSamplerMap = new WeakMap(); + class GPUSampler { + constructor(label) { + this.label = label; + } + } + + const GPUBindGroupLayoutMap = new WeakMap(); + class GPUBindGroupLayout { + constructor(label) { + this.label = label; + } + } + + const GPUPipelineLayoutMap = new WeakMap(); + class GPUPipelineLayout { + constructor(label) { + this.label = label; + } + } + + const GPUBindGroupMap = new WeakMap(); + class GPUBindGroup { + constructor(label) { + this.label = label; + } + } + + const GPUShaderModuleMap = new WeakMap(); + class GPUShaderModule { #rid; - constructor(rid) { + constructor(rid, label) { this.#rid = rid; + this.label = label; + } + + async compilationInfo() {} // TODO + } + + class GPUComputePipeline { + #rid; + + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + getBindGroupLayout(index) { + const { rid } = core.jsonOpSync( + "op_webgpu_compute_pipeline_get_bind_group_layout", + { + rid: this.#rid, + index, + }, + ); + + const bindGroupLayout = new GPUBindGroupLayout(); // TODO + GPUBindGroupLayoutMap.set(bindGroupLayout, rid); + return bindGroupLayout; + } + } + + class GPURenderPipeline { + #rid; + + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + getBindGroupLayout(index) { + const { rid } = core.jsonOpSync( + "op_webgpu_render_pipeline_get_bind_group_layout", + { + rid: this.#rid, + index, + }, + ); + + const bindGroupLayout = new GPUBindGroupLayout(); // TODO + GPUBindGroupLayoutMap.set(bindGroupLayout, rid); + return bindGroupLayout; } } diff --git a/cli/worker.rs b/cli/worker.rs index 488a2eeba6e714..d74d51c080b483 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -313,6 +313,7 @@ impl MainWorker { ops::signal::init(&mut worker); ops::tls::init(&mut worker); ops::tty::init(&mut worker); + ops::webgpu::init(&mut worker); ops::websocket::init(&mut worker); } { @@ -477,6 +478,7 @@ impl WebWorker { ); ops::errors::init(&mut web_worker); ops::io::init(&mut web_worker); + ops::webgpu::init(&mut web_worker); ops::websocket::init(&mut web_worker); if has_deno_namespace { From 097f7bcf056b669e4d37f514bc695b23ac7ced5b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 9 Oct 2020 12:01:10 +0200 Subject: [PATCH 003/144] up to renderbundleencoder --- cli/ops/webgpu/bundle.rs | 86 +++++++++++ cli/ops/webgpu/command_encoder.rs | 243 ++++++++++++++++++++++++++++++ cli/ops/webgpu/mod.rs | 35 ++++- cli/rt/14_webgpu.js | 212 ++++++++++++++++++++++++++ 4 files changed, 575 insertions(+), 1 deletion(-) create mode 100644 cli/ops/webgpu/bundle.rs create mode 100644 cli/ops/webgpu/command_encoder.rs diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs new file mode 100644 index 00000000000000..23ba64ac8d19c5 --- /dev/null +++ b/cli/ops/webgpu/bundle.rs @@ -0,0 +1,86 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; +use super::texture::serialize_texture_format; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateRenderBundleEncoderArgs { + rid: u32, + label: Option, + color_formats: [String], + depth_stencil_format: Option, + sample_count: Option, +} + +pub fn op_webgpu_create_render_bundle_encoder( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateRenderBundleEncoderArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let render_bundle_encoder = device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { + label: args.label.map(|label| &label), + color_formats: &args.color_formats.iter().map(|format| { + serialize_texture_format(format.clone())? + }).collect::<[wgpu::TextureFormat]>(), + depth_stencil_format: args.depth_stencil_format.map(|format| serialize_texture_format(format)?), + sample_count: args.sample_count.unwrap_or(1), + }); + + let rid = state + .resource_table + .add("webGPURenderBundleEncoder", Box::new(render_bundle_encoder)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderFinishArgs { + rid: u32, + label: Option, +} + +pub fn op_webgpu_render_bundle_encoder_finish( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderFinishArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let render_bundle = render_bundle_encoder.finish(&wgpu::RenderBundleDescriptor { + label: args.label.map(|label| &label), + }); + + let rid = state + .resource_table + .add("webGPURenderBundle", Box::new(render_bundle)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs new file mode 100644 index 00000000000000..227e937dc28784 --- /dev/null +++ b/cli/ops/webgpu/command_encoder.rs @@ -0,0 +1,243 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateCommandEncoderArgs { + rid: u32, + label: Option, + measure_execution_time: Option, // TODO +} + +pub fn op_webgpu_create_command_encoder( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; + + let device = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let command_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: args.label.map(|label| &label), + }); + + let rid = state + .resource_table + .add("webGPUCommandEncoder", Box::new(command_encoder)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPURenderPassColorAttachmentDescriptor { + attachment: u32, + resolve_target: Option, + load_value: (), // TODO + store_op: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPURenderPassDepthStencilAttachmentDescriptor { + attachment: u32, + depth_load_value: (), // TODO + depth_store_op: String, + depth_read_only: Option, + stencil_load_value: (), // TODO + stencil_store_op: String, + stencil_read_only: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderBeginRenderPassArgs { + rid: u32, + label: Option, // TODO + color_attachments: [GPURenderPassColorAttachmentDescriptor], + depth_stencil_attachment: Option, + occlusion_query_set: (), // TODO +} + +pub fn op_webgpu_command_encoder_begin_render_pass( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; + + let command_encoder = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &args.color_attachments.iter().map(|color_attachment| { + wgpu::RenderPassColorAttachmentDescriptor { + attachment: state + .resource_table + .get_mut::(color_attachment.attachment) + .ok_or_else(bad_resource_id)?, + resolve_target: color_attachment.resolve_target.map(|rid| { + state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)? + }), + ops: (), // TODO + } + }).collect::<[wgpu::RenderPassColorAttachmentDescriptor]>(), + depth_stencil_attachment: args.depth_stencil_attachment.map(|depth_stencil_attachment| { + wgpu::RenderPassDepthStencilAttachmentDescriptor { + attachment: state + .resource_table + .get_mut::(depth_stencil_attachment.attachment) + .ok_or_else(bad_resource_id)?, + depth_ops: None, // TODO + stencil_ops: None, // TODO + } + }), + }); + + let rid = state + .resource_table + .add("webGPURenderPass", Box::new(render_pass)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderBeginComputePassArgs { + rid: u32, + label: Option, // TODO +} + +pub fn op_webgpu_command_encoder_begin_compute_pass( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderBeginComputePassArgs = serde_json::from_value(args)?; + + let command_encoder = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let compute_pass = command_encoder.begin_compute_pass(); + + let rid = state + .resource_table + .add("webGPUComputePass", Box::new(compute_pass)); + + Ok(json!({ + "rid": rid, + })) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUTextureCopyView { + texture: u32, + mip_level: Option, + origin: (), // TODO +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderCopyTextureToTextureArgs { + rid: u32, + source: GPUTextureCopyView, + destination: GPUTextureCopyView, + copy_size: (), // TODO +} + +pub fn op_webgpu_command_encoder_copy_texture_to_texture( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; + + let command_encoder = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + command_encoder.copy_texture_to_texture( + wgpu::TextureCopyView { + texture: state + .resource_table + .get_mut::(args.source.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.source.mip_level.unwrap_or(0), + origin: Default::default(), // TODO + }, + wgpu::TextureCopyView { + texture: state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: Default::default(), // TODO + }, + wgpu::Extent3d { + width: 0, + height: 0, + depth: 0 + } + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderFinishArgs { + rid: u32, + label: Option, // TODO +} + +pub fn op_webgpu_command_encoder_finish( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; + + let command_encoder = state + .resource_table + .get_mut::(args.rid) + .ok_or_else(bad_resource_id)?; + + let command_buffer = command_encoder.finish(); + + let rid = state + .resource_table + .add("webGPUCommandBuffer", Box::new(command_buffer)); + + Ok(json!({ + "rid": rid, + })) +} + diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index a82ceeebbceaff..f7e5d0008c7241 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -6,7 +6,8 @@ mod pipeline; mod sampler; mod shader; mod texture; -mod command_buffer; +mod command_encoder; +mod bundle; use deno_core::error::bad_resource_id; use deno_core::error::type_error; @@ -106,6 +107,38 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pipeline_get_bind_group_layout", pipeline::op_webgpu_render_pipeline_get_bind_group_layout, ); + + super::reg_json_sync( + rt, + "op_webgpu_create_command_encoder", + command_encoder::op_webgpu_create_command_encoder, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_render_pass", + command_encoder::op_webgpu_command_encoder_begin_render_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_compute_pass", + command_encoder::op_webgpu_command_encoder_begin_compute_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_texture", + command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, + ); + + super::reg_json_sync( + rt, + "op_webgpu_create_render_bundle_encoder", + bundle::op_webgpu_create_render_bundle_encoder, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_finish", + bundle::op_webgpu_render_bundle_encoder_finish, + ); } fn serialize_features(features: &wgpu::Features) -> Vec<&str> { diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index dc77a14c837664..3ea2e7419bc9bb 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -184,6 +184,29 @@ return new GPURenderPipeline(rid, descriptor.label); } + + async createReadyComputePipeline(descriptor) {} // TODO + + async createReadyRenderPipeline(descriptor) {} // TODO + + createCommandEncoder(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { + rid: this.#deviceRid, + ...descriptor + }); + + return new GPUCommandEncoder(rid, descriptor.label); + } + + createRenderBundleEncoder(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_render_bundle_encoder", { + rid: this.#deviceRid, + ...descriptor, + }); + + + new GPURenderBundleEncoder(); + } } class GPUBuffer { @@ -332,6 +355,195 @@ } } + class GPUCommandEncoder { + #rid; + + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + beginRenderPass(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_command_encoder_begin_render_pass", { + rid: this.#rid, + ...descriptor, + }); + + return new GPURenderPassEncoder(rid, descriptor.label); + } + + beginComputePass(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_command_encoder_begin_compute_pass", { + rid: this.#rid, + ...descriptor, + }); + + return new GPUComputePassEncoder(rid, descriptor.label); + } + + copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {} // TODO + + copyBufferToTexture(source, destination, copySize) {} // TODO + + copyTextureToBuffer(source, destination, copySize) {} // TODO + + copyTextureToTexture(source, destination, copySize) { + const { rid } = core.jsonOpSync("op_webgpu_command_encoder_copy_texture_to_texture", { + rid: this.#rid, + source, + destination, + copySize, + }); + } + + pushDebugGroup(groupLabel) {} // TODO + popDebugGroup() {} // TODO + insertDebugMarker(markerLabel) {} // TODO + + writeTimestamp(querySet, queryIndex) {} // TODO + + resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {} // TODO + + finish(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { + rid: this.#rid, + ...descriptor, + }); + + return new GPUCommandBuffer(descriptor.label); + } + } + + class GPURenderPassEncoder { + #rid; + + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + setViewport(x, y, width, height, minDepth, maxDepth) {} // TODO + + setScissorRect(x, y, width, height) {} // TODO + + setBlendColor(color) {} // TODO + setStencilReference(reference) {} // TODO + + beginOcclusionQuery(queryIndex) {} // TODO + endOcclusionQuery() {} // TODO + + beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO + endPipelineStatisticsQuery() {} // TODO + + writeTimestamp(querySet, queryIndex) {} // TODO + + executeBundles(bundles) {} // TODO + endPass() {} // TODO + + + setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO + + setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + + pushDebugGroup(groupLabel) {} // TODO + popDebugGroup() {} // TODO + insertDebugMarker(markerLabel) {} // TODO + + + setPipeline(pipeline) {} // TODO + + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO + setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO + + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO + drawIndexed(indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0) {} // TODO + + drawIndirect(indirectBuffer, indirectOffset) {} // TODO + drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO + } + + class GPUComputePassEncoder { + #rid; + + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + setPipeline(pipeline) {} // TODO + dispatch(x, y = 1, z = 1) {} // TODO + dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO + + beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO + endPipelineStatisticsQuery() {} // TODO + + writeTimestamp(querySet, queryIndex) {} // TODO + + endPass() {} // TODO + + + setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO + + setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + + pushDebugGroup(groupLabel) {} // TODO + popDebugGroup() {} // TODO + insertDebugMarker(markerLabel) {} // TODO + } + + class GPUCommandBuffer { + constructor(label) { + this.label = label; + } + + async get executionTime() {} // TODO + } + + class GPURenderBundleEncoder { + #rid; + constructor(rid, label) { + this.#rid = rid; + this.label = label; + } + + finish(descriptor = {}) { + const { rid } = core.jsonOpSync("op_webgpu_render_bundle_encoder_finish", { + rid: this.#rid, + ...descriptor, + }); + + return new GPURenderBundle(descriptor.label); + } + + + setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO + + setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + + pushDebugGroup(groupLabel) {} // TODO + popDebugGroup() {} // TODO + insertDebugMarker(markerLabel) {} // TODO + + + setPipeline(pipeline) {} // TODO + + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO + setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO + + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO + drawIndexed(indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0) {} // TODO + + drawIndirect(indirectBuffer, indirectOffset) {} // TODO + drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO + + } + + class GPURenderBundle { + constructor(label) { + this.label = label; + } + } + window.__bootstrap.webGPU = { webGPU: GPU, }; From 708007f73327afd38a9e5c2746aeb6594ea11024 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 9 Oct 2020 20:39:32 +0200 Subject: [PATCH 004/144] cleanup --- cli/ops/webgpu/bundle.rs | 30 ++-- ...command_encoder.rs => command_encoding.rs} | 79 +++++---- cli/ops/webgpu/mod.rs | 12 +- cli/ops/webgpu/pipeline.rs | 153 ++++++++++-------- cli/rt/14_webgpu.js | 132 ++++++++++----- 5 files changed, 248 insertions(+), 158 deletions(-) rename cli/ops/webgpu/{command_encoder.rs => command_encoding.rs} (76%) diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 23ba64ac8d19c5..f3613b5f3589a3 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -1,5 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +use super::texture::serialize_texture_format; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; @@ -11,7 +12,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; -use super::texture::serialize_texture_format; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -35,14 +35,19 @@ pub fn op_webgpu_create_render_bundle_encoder( .get_mut::(args.rid) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { - label: args.label.map(|label| &label), - color_formats: &args.color_formats.iter().map(|format| { - serialize_texture_format(format.clone())? - }).collect::<[wgpu::TextureFormat]>(), - depth_stencil_format: args.depth_stencil_format.map(|format| serialize_texture_format(format)?), - sample_count: args.sample_count.unwrap_or(1), - }); + let render_bundle_encoder = + device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { + label: args.label.map(|label| &label), + color_formats: &args + .color_formats + .iter() + .map(|format| serialize_texture_format(format.clone())?) + .collect::<[wgpu::TextureFormat]>(), + depth_stencil_format: args + .depth_stencil_format + .map(|format| serialize_texture_format(format)?), + sample_count: args.sample_count.unwrap_or(1), + }); let rid = state .resource_table @@ -72,9 +77,10 @@ pub fn op_webgpu_render_bundle_encoder_finish( .get_mut::(args.rid) .ok_or_else(bad_resource_id)?; - let render_bundle = render_bundle_encoder.finish(&wgpu::RenderBundleDescriptor { - label: args.label.map(|label| &label), - }); + let render_bundle = + render_bundle_encoder.finish(&wgpu::RenderBundleDescriptor { + label: args.label.map(|label| &label), + }); let rid = state .resource_table diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoding.rs similarity index 76% rename from cli/ops/webgpu/command_encoder.rs rename to cli/ops/webgpu/command_encoding.rs index 227e937dc28784..3e83ce9fb0c500 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -32,9 +32,10 @@ pub fn op_webgpu_create_command_encoder( .get_mut::(args.rid) .ok_or_else(bad_resource_id)?; - let command_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: args.label.map(|label| &label), - }); + let command_encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: args.label.map(|label| &label), + }); let rid = state .resource_table @@ -72,7 +73,8 @@ struct CommandEncoderBeginRenderPassArgs { rid: u32, label: Option, // TODO color_attachments: [GPURenderPassColorAttachmentDescriptor], - depth_stencil_attachment: Option, + depth_stencil_attachment: + Option, occlusion_query_set: (), // TODO } @@ -88,33 +90,40 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .get_mut::(args.rid) .ok_or_else(bad_resource_id)?; - let render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &args.color_attachments.iter().map(|color_attachment| { - wgpu::RenderPassColorAttachmentDescriptor { - attachment: state - .resource_table - .get_mut::(color_attachment.attachment) - .ok_or_else(bad_resource_id)?, - resolve_target: color_attachment.resolve_target.map(|rid| { - state - .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id)? - }), - ops: (), // TODO - } - }).collect::<[wgpu::RenderPassColorAttachmentDescriptor]>(), - depth_stencil_attachment: args.depth_stencil_attachment.map(|depth_stencil_attachment| { - wgpu::RenderPassDepthStencilAttachmentDescriptor { - attachment: state - .resource_table - .get_mut::(depth_stencil_attachment.attachment) - .ok_or_else(bad_resource_id)?, - depth_ops: None, // TODO - stencil_ops: None, // TODO - } - }), - }); + let render_pass = + command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &args + .color_attachments + .iter() + .map(|color_attachment| { + wgpu::RenderPassColorAttachmentDescriptor { + attachment: state + .resource_table + .get_mut::(color_attachment.attachment) + .ok_or_else(bad_resource_id)?, + resolve_target: color_attachment.resolve_target.map(|rid| { + state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)? + }), + ops: (), // TODO + } + }) + .collect::<[wgpu::RenderPassColorAttachmentDescriptor]>(), + depth_stencil_attachment: args.depth_stencil_attachment.map( + |depth_stencil_attachment| { + wgpu::RenderPassDepthStencilAttachmentDescriptor { + attachment: state + .resource_table + .get_mut::(depth_stencil_attachment.attachment) + .ok_or_else(bad_resource_id)?, + depth_ops: None, // TODO + stencil_ops: None, // TODO + } + }, + ), + }); let rid = state .resource_table @@ -177,7 +186,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; + let args: CommandEncoderCopyTextureToTextureArgs = + serde_json::from_value(args)?; let command_encoder = state .resource_table @@ -204,8 +214,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( wgpu::Extent3d { width: 0, height: 0, - depth: 0 - } + depth: 0, + }, ); Ok(json!({})) @@ -240,4 +250,3 @@ pub fn op_webgpu_command_encoder_finish( "rid": rid, })) } - diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index f7e5d0008c7241..e4d58f553c442e 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -2,12 +2,12 @@ mod binding; mod buffer; +mod bundle; +mod command_encoding; mod pipeline; mod sampler; mod shader; mod texture; -mod command_encoder; -mod bundle; use deno_core::error::bad_resource_id; use deno_core::error::type_error; @@ -111,22 +111,22 @@ pub fn init(rt: &mut deno_core::JsRuntime) { super::reg_json_sync( rt, "op_webgpu_create_command_encoder", - command_encoder::op_webgpu_create_command_encoder, + command_encoding::op_webgpu_create_command_encoder, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_begin_render_pass", - command_encoder::op_webgpu_command_encoder_begin_render_pass, + command_encoding::op_webgpu_command_encoder_begin_render_pass, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_begin_compute_pass", - command_encoder::op_webgpu_command_encoder_begin_compute_pass, + command_encoding::op_webgpu_command_encoder_begin_compute_pass, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_copy_texture_to_texture", - command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, + command_encoding::op_webgpu_command_encoder_copy_texture_to_texture, ); super::reg_json_sync( diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 45b55e68a9fec6..985b671b02ada6 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -83,10 +83,16 @@ fn serialize_blend_factor(blend_factor: String) -> wgpu::BlendFactor { } } -fn serialize_blend_descriptor(blend: GPUBlendDescriptor) -> wgpu::BlendDescriptor { +fn serialize_blend_descriptor( + blend: GPUBlendDescriptor, +) -> wgpu::BlendDescriptor { wgpu::BlendDescriptor { - src_factor: blend.src_factor.map_or(wgpu::BlendFactor::One, serialize_blend_factor), - dst_factor: blend.dst_factor.map_or(wgpu::BlendFactor::Zero, serialize_blend_factor), + src_factor: blend + .src_factor + .map_or(wgpu::BlendFactor::One, serialize_blend_factor), + dst_factor: blend + .dst_factor + .map_or(wgpu::BlendFactor::Zero, serialize_blend_factor), operation: match blend.operation { Some(&"add") => wgpu::BlendOperation::Add, Some(&"subtract") => wgpu::BlendOperation::Subtract, @@ -95,7 +101,7 @@ fn serialize_blend_descriptor(blend: GPUBlendDescriptor) -> wgpu::BlendDescripto Some(&"max") => wgpu::BlendOperation::Max, Some(_) => unreachable!(), None => wgpu::BlendOperation::Add, - } + }, } } @@ -342,8 +348,12 @@ pub fn op_webgpu_create_render_pipeline( .map(|color_state| { wgpu::ColorStateDescriptor { format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state.alpha_blend.map_or("", serialize_blend_descriptor), // TODO - color_blend: color_state.color_blend.map_or("", serialize_blend_descriptor), // TODO + alpha_blend: color_state + .alpha_blend + .map_or("", serialize_blend_descriptor), // TODO + color_blend: color_state + .color_blend + .map_or("", serialize_blend_descriptor), // TODO write_mask: color_state.write_mask, // TODO } }) @@ -352,78 +362,88 @@ pub fn op_webgpu_create_render_pipeline( wgpu::DepthStencilStateDescriptor { format: serialize_texture_format(state.format)?, depth_write_enabled: state.depth_write_enabled.unwrap_or(false), - depth_compare: state.depth_compare.map_or(wgpu::CompareFunction::Always, serialize_compare_function), + depth_compare: state + .depth_compare + .map_or(wgpu::CompareFunction::Always, serialize_compare_function), stencil: wgpu::StencilStateDescriptor { - front: state.stencil_front.map_or(wgpu::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor), - back: state.stencil_front.map_or(wgpu::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor), + front: state.stencil_front.map_or( + wgpu::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), + back: state.stencil_front.map_or( + wgpu::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), }, } }), vertex_state: wgpu::VertexStateDescriptor { - index_format: args.vertex_state.unwrap().index_format.map_or("", |format| match format { // TODO - &"uint16" => wgpu::IndexFormat::Uint16, - &"uint32" => wgpu::IndexFormat::Uint32, - _ => unreachable!(), - }), + index_format: args.vertex_state.unwrap().index_format.map_or( + "", + |format| match format { + // TODO + &"uint16" => wgpu::IndexFormat::Uint16, + &"uint32" => wgpu::IndexFormat::Uint32, + _ => unreachable!(), + }, + ), vertex_buffers: &args .vertex_state .unwrap() .vertex_buffers .unwrap() // TODO .iter() - .map(|buffer| { - wgpu::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode { - Some(&"vertex") => wgpu::InputStepMode::Vertex, - Some(&"instance") => wgpu::InputStepMode::Instance, - Some(_) => unreachable!(), - None => wgpu::InputStepMode::Vertex, - }, - attributes: &buffer - .attributes - .iter() - .map(|attribute| wgpu::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format { - &"uchar2" => wgpu::VertexFormat::Uchar2, - &"uchar4" => wgpu::VertexFormat::Uchar4, - &"char2" => wgpu::VertexFormat::Char2, - &"char4" => wgpu::VertexFormat::Char4, - &"uchar2norm" => wgpu::VertexFormat::Uchar2Norm, - &"uchar4norm" => wgpu::VertexFormat::Uchar4, - &"char2norm" => wgpu::VertexFormat::Char2Norm, - &"char4norm" => wgpu::VertexFormat::Char4Norm, - &"ushort2" => wgpu::VertexFormat::Ushort2, - &"ushort4" => wgpu::VertexFormat::Ushort4, - &"short2" => wgpu::VertexFormat::Short2, - &"short4" => wgpu::VertexFormat::Short4, - &"ushort2norm" => wgpu::VertexFormat::Ushort2Norm, - &"ushort4norm" => wgpu::VertexFormat::Ushort4Norm, - &"short2norm" => wgpu::VertexFormat::Short2Norm, - &"short4norm" => wgpu::VertexFormat::Short4Norm, - &"half2" => wgpu::VertexFormat::Half2, - &"half4" => wgpu::VertexFormat::Half4, - &"float" => wgpu::VertexFormat::Float, - &"float2" => wgpu::VertexFormat::Float2, - &"float3" => wgpu::VertexFormat::Float3, - &"float4" => wgpu::VertexFormat::Float4, - &"uint" => wgpu::VertexFormat::Uint, - &"uint2" => wgpu::VertexFormat::Uint2, - &"uint3" => wgpu::VertexFormat::Uint3, - &"uint4" => wgpu::VertexFormat::Uint4, - &"int" => wgpu::VertexFormat::Int, - &"int2" => wgpu::VertexFormat::Int2, - &"int3" => wgpu::VertexFormat::Int3, - &"int4" => wgpu::VertexFormat::Int4, - _ => unreachable!(), - }, - shader_location: attribute.shader_location, - }) - .collect::<[wgpu::VertexAttributeDescriptor]>(), - } + .map(|buffer| wgpu::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode { + Some(&"vertex") => wgpu::InputStepMode::Vertex, + Some(&"instance") => wgpu::InputStepMode::Instance, + Some(_) => unreachable!(), + None => wgpu::InputStepMode::Vertex, + }, + attributes: &buffer + .attributes + .iter() + .map(|attribute| wgpu::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format { + &"uchar2" => wgpu::VertexFormat::Uchar2, + &"uchar4" => wgpu::VertexFormat::Uchar4, + &"char2" => wgpu::VertexFormat::Char2, + &"char4" => wgpu::VertexFormat::Char4, + &"uchar2norm" => wgpu::VertexFormat::Uchar2Norm, + &"uchar4norm" => wgpu::VertexFormat::Uchar4, + &"char2norm" => wgpu::VertexFormat::Char2Norm, + &"char4norm" => wgpu::VertexFormat::Char4Norm, + &"ushort2" => wgpu::VertexFormat::Ushort2, + &"ushort4" => wgpu::VertexFormat::Ushort4, + &"short2" => wgpu::VertexFormat::Short2, + &"short4" => wgpu::VertexFormat::Short4, + &"ushort2norm" => wgpu::VertexFormat::Ushort2Norm, + &"ushort4norm" => wgpu::VertexFormat::Ushort4Norm, + &"short2norm" => wgpu::VertexFormat::Short2Norm, + &"short4norm" => wgpu::VertexFormat::Short4Norm, + &"half2" => wgpu::VertexFormat::Half2, + &"half4" => wgpu::VertexFormat::Half4, + &"float" => wgpu::VertexFormat::Float, + &"float2" => wgpu::VertexFormat::Float2, + &"float3" => wgpu::VertexFormat::Float3, + &"float4" => wgpu::VertexFormat::Float4, + &"uint" => wgpu::VertexFormat::Uint, + &"uint2" => wgpu::VertexFormat::Uint2, + &"uint3" => wgpu::VertexFormat::Uint3, + &"uint4" => wgpu::VertexFormat::Uint4, + &"int" => wgpu::VertexFormat::Int, + &"int2" => wgpu::VertexFormat::Int2, + &"int3" => wgpu::VertexFormat::Int3, + &"int4" => wgpu::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::<[wgpu::VertexAttributeDescriptor]>(), }) .collect::<[wgpu::VertexBufferDescriptor]>(), }, @@ -455,7 +475,8 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + let args: RenderPipelineGetBindGroupLayoutArgs = + serde_json::from_value(args)?; let render_pipeline = state .resource_table diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 3ea2e7419bc9bb..4b964cd433f966 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -179,7 +179,7 @@ createRenderPipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { rid: this.#deviceRid, - ...descriptor + ...descriptor, }); return new GPURenderPipeline(rid, descriptor.label); @@ -192,20 +192,26 @@ createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { rid: this.#deviceRid, - ...descriptor + ...descriptor, }); return new GPUCommandEncoder(rid, descriptor.label); } createRenderBundleEncoder(descriptor) { - const { rid } = core.jsonOpSync("op_webgpu_create_render_bundle_encoder", { - rid: this.#deviceRid, - ...descriptor, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_create_render_bundle_encoder", + { + rid: this.#deviceRid, + ...descriptor, + }, + ); + return new GPURenderBundleEncoder(rid, descriptor.label); + } - new GPURenderBundleEncoder(); + createQuerySet(descriptor) { + throw new Error("Not yet implemented"); } } @@ -364,36 +370,51 @@ } beginRenderPass(descriptor) { - const { rid } = core.jsonOpSync("op_webgpu_command_encoder_begin_render_pass", { - rid: this.#rid, - ...descriptor, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_command_encoder_begin_render_pass", + { + rid: this.#rid, + ...descriptor, + }, + ); return new GPURenderPassEncoder(rid, descriptor.label); } beginComputePass(descriptor = {}) { - const { rid } = core.jsonOpSync("op_webgpu_command_encoder_begin_compute_pass", { - rid: this.#rid, - ...descriptor, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_command_encoder_begin_compute_pass", + { + rid: this.#rid, + ...descriptor, + }, + ); return new GPUComputePassEncoder(rid, descriptor.label); } - copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {} // TODO + copyBufferToBuffer( + source, + sourceOffset, + destination, + destinationOffset, + size, + ) {} // TODO copyBufferToTexture(source, destination, copySize) {} // TODO copyTextureToBuffer(source, destination, copySize) {} // TODO copyTextureToTexture(source, destination, copySize) { - const { rid } = core.jsonOpSync("op_webgpu_command_encoder_copy_texture_to_texture", { - rid: this.#rid, - source, - destination, - copySize, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_command_encoder_copy_texture_to_texture", + { + rid: this.#rid, + source, + destination, + copySize, + }, + ); } pushDebugGroup(groupLabel) {} // TODO @@ -402,7 +423,13 @@ writeTimestamp(querySet, queryIndex) {} // TODO - resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {} // TODO + resolveQuerySet( + querySet, + firstQuery, + queryCount, + destination, + destinationOffset, + ) {} // TODO finish(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { @@ -440,23 +467,33 @@ executeBundles(bundles) {} // TODO endPass() {} // TODO - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) {} // TODO pushDebugGroup(groupLabel) {} // TODO popDebugGroup() {} // TODO insertDebugMarker(markerLabel) {} // TODO - setPipeline(pipeline) {} // TODO setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO - drawIndexed(indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0) {} // TODO + drawIndexed( + indexCount, + instanceCount = 1, + firstIndex = 0, + baseVertex = 0, + firstInstance = 0, + ) {} // TODO drawIndirect(indirectBuffer, indirectOffset) {} // TODO drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO @@ -481,10 +518,15 @@ endPass() {} // TODO - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) {} // TODO pushDebugGroup(groupLabel) {} // TODO popDebugGroup() {} // TODO @@ -496,7 +538,7 @@ this.label = label; } - async get executionTime() {} // TODO + get executionTime() {} // TODO } class GPURenderBundleEncoder { @@ -507,35 +549,47 @@ } finish(descriptor = {}) { - const { rid } = core.jsonOpSync("op_webgpu_render_bundle_encoder_finish", { - rid: this.#rid, - ...descriptor, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_render_bundle_encoder_finish", + { + rid: this.#rid, + ...descriptor, + }, + ); return new GPURenderBundle(descriptor.label); } - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) {} // TODO + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) {} // TODO pushDebugGroup(groupLabel) {} // TODO popDebugGroup() {} // TODO insertDebugMarker(markerLabel) {} // TODO - setPipeline(pipeline) {} // TODO setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO - drawIndexed(indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0) {} // TODO + drawIndexed( + indexCount, + instanceCount = 1, + firstIndex = 0, + baseVertex = 0, + firstInstance = 0, + ) {} // TODO drawIndirect(indirectBuffer, indirectOffset) {} // TODO drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO - } class GPURenderBundle { From 1c2434cb94f15c9f0ff1b082480e6794b0edc5a3 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 11 Oct 2020 13:51:46 +0200 Subject: [PATCH 005/144] switch to wgpu-core --- Cargo.lock | 50 +--- cli/Cargo.toml | 3 +- cli/ops/webgpu/binding.rs | 281 +++++++++++++--------- cli/ops/webgpu/buffer.rs | 69 ++++-- cli/ops/webgpu/bundle.rs | 52 ++-- cli/ops/webgpu/command_encoding.rs | 148 ++++++++---- cli/ops/webgpu/mod.rs | 87 ++++--- cli/ops/webgpu/pipeline.rs | 374 ++++++++++++++++------------- cli/ops/webgpu/sampler.rs | 80 +++--- cli/ops/webgpu/shader.rs | 15 +- cli/ops/webgpu/texture.rs | 229 ++++++++++-------- cli/rt/14_webgpu.js | 71 ++++-- 12 files changed, 826 insertions(+), 633 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f85fbcfe8d780d..6cccc81b80e43d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,7 +537,8 @@ dependencies = [ "warp", "webpki", "webpki-roots", - "wgpu", + "wgpu-core", + "wgpu-types", "winapi 0.3.9", "winres", ] @@ -1089,7 +1090,6 @@ dependencies = [ "raw-window-handle", "smallvec", "winapi 0.3.9", - "x11", ] [[package]] @@ -1936,12 +1936,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" - [[package]] name = "pmutil" version = "0.5.3" @@ -3184,12 +3178,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "typed-arena" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" - [[package]] name = "typenum" version = "1.12.0" @@ -3462,29 +3450,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "wgpu" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "549160f188eef412ac978499ddf0ceadad4c9159bb1160f9e6b9d4cc8ee977dc" -dependencies = [ - "arrayvec", - "futures", - "gfx-backend-vulkan", - "js-sys", - "objc", - "parking_lot", - "raw-window-handle", - "smallvec", - "tracing", - "typed-arena", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-types", -] - [[package]] name = "wgpu-core" version = "0.6.4" @@ -3505,7 +3470,6 @@ dependencies = [ "gfx-memory", "naga", "parking_lot", - "raw-window-handle", "smallvec", "thiserror", "tracing", @@ -3610,13 +3574,3 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] - -[[package]] -name = "x11" -version = "2.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773" -dependencies = [ - "libc", - "pkg-config", -] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 95be6bf1b6f0e4..7f4eaa3e0a0802 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -75,7 +75,8 @@ walkdir = "2.3.1" warp = { version = "0.2.5", features = ["tls"] } semver-parser = "0.9.0" uuid = { version = "0.8.1", features = ["v4"] } -wgpu = "0.6.0" +wgc = { package = "wgpu-core", version = "0.6.4" } +wgt = { package = "wgpu-types", versionn = "0.6.1" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] } diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 4194c954026d1c..e69acb76180698 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -10,17 +10,18 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; fn serialize_texture_component_type( component_type: String, -) -> Result { +) -> Result { Ok(match component_type { - &"float" => wgpu::TextureComponentType::Float, - &"sint" => wgpu::TextureComponentType::Sint, - &"uint" => wgpu::TextureComponentType::Uint, - &"depth-comparison" => return Err(not_supported()), + &"float" => wgt::TextureComponentType::Float, + &"sint" => wgt::TextureComponentType::Sint, + &"uint" => wgt::TextureComponentType::Uint, + &"depth-comparison" => return Err(not_supported()), // TODO _ => unreachable!(), }) } @@ -42,7 +43,8 @@ struct GPUBindGroupLayoutEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBindGroupLayoutArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, entries: [GPUBindGroupLayoutEntry], } @@ -54,79 +56,95 @@ pub fn op_webgpu_create_bind_group_layout( ) -> Result { let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: args.label.map(|label| &label), - entries: &args - .entries - .iter() - .map(|entry| { - wgpu::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgpu::ShaderStage::from_bits(entry.visibility).unwrap(), // TODO - ty: match entry.kind { - &"uniform-buffer" => wgpu::BindingType::UniformBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - }, - &"storage-buffer" => wgpu::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: false, - }, - &"readonly-storage-buffer" => wgpu::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: true, - }, - &"sampler" => wgpu::BindingType::Sampler { comparison: false }, - &"comparison-sampler" => { - wgpu::BindingType::Sampler { comparison: true } - } - &"sampled-texture" => wgpu::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, // TODO - multisampled: false, - }, - &"multisampled-texture" => wgpu::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, // TODO - multisampled: true, - }, - &"readonly-storage-texture" => { - wgpu::BindingType::StorageTexture { + let bind_group_layout = instance.device_create_bind_group_layout( + *device, + &wgc::binding_model::BindGroupLayoutDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + entries: Cow::Owned( + args + .entries + .iter() + .map(|entry| { + wgt::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgt::ShaderStage::from_bits(entry.visibility) + .unwrap(), // TODO + ty: match entry.kind { + &"uniform-buffer" => wgt::BindingType::UniformBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + }, + &"storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: false, + }, + &"readonly-storage-buffer" => { + wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: true, + } + } + &"sampler" => wgt::BindingType::Sampler { comparison: false }, + &"comparison-sampler" => { + wgt::BindingType::Sampler { comparison: true } + } + &"sampled-texture" => wgt::BindingType::SampledTexture { dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), )?, // TODO - readonly: true, - } - } - &"writeonly-storage-texture" => { - wgpu::BindingType::StorageTexture { + multisampled: false, + }, + &"multisampled-texture" => wgt::BindingType::SampledTexture { dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), )?, // TODO - readonly: false, + multisampled: true, + }, + &"readonly-storage-texture" => { + wgt::BindingType::StorageTexture { + dimension: serialize_dimension( + entry.view_dimension.unwrap(), + ), // TODO + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, // TODO + readonly: true, + } + } + &"writeonly-storage-texture" => { + wgt::BindingType::StorageTexture { + dimension: serialize_dimension( + entry.view_dimension.unwrap(), + ), // TODO + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, // TODO + readonly: false, + } } - } - _ => unreachable!(), - }, - count: None, // TODO - } - }) - .collect::<[wgpu::BindGroupLayoutEntry]>(), - }); + _ => unreachable!(), + }, + count: None, // TODO + } + }) + .collect::>(), + ), + }, + (), // TODO + )?; let rid = state .resource_table @@ -140,7 +158,8 @@ pub fn op_webgpu_create_bind_group_layout( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreatePipelineLayoutArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, bind_group_layouts: [u32], } @@ -152,26 +171,35 @@ pub fn op_webgpu_create_pipeline_layout( ) -> Result { let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let pipeline_layout = - device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: args.label.map(|label| &label), - bind_group_layouts: &args - .bind_group_layouts - .iter() - .map(|rid| { - state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::<[&wgpu::BindGroupLayout]>(), - push_constant_ranges: &[], // TODO - }); + let pipeline_layout = instance.device_create_pipeline_layout( + *device, + &wgc::binding_model::PipelineLayoutDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + bind_group_layouts: Cow::Owned( + args + .bind_group_layouts + .iter() + .map(|rid| { + state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::>(), + ), + push_constant_ranges: Default::default(), // TODO + }, + (), // TODO + )?; let rid = state .resource_table @@ -193,7 +221,8 @@ struct GPUBindGroupEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBindGroupArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, layout: u32, entries: [GPUBindGroupEntry], @@ -206,42 +235,56 @@ pub fn op_webgpu_create_bind_group( ) -> Result { let args: CreateBindGroupArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: args.label.map(|label| &label), - layout: state - .resource_table - .get_mut::(args.layout) - .ok_or_else(bad_resource_id)?, - entries: &args - .entries - .iter() - .map(|entry| { - let resource = state - .resource_table - .get_mut(entry.resource) - .ok_or_else(bad_resource_id)?; - - wgpu::BindGroupEntry { - binding: entry.binding, - resource: match entry.resource_kind { - &"GPUSampler" => { - wgpu::BindingResource::Sampler(resource as &mut wgpu::Sampler) + let bind_group = instance.device_create_bind_group( + *device, + &wgc::binding_model::BindGroupDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + layout: *state + .resource_table + .get_mut::(args.layout) + .ok_or_else(bad_resource_id)?, + entries: Cow::Owned( + args + .entries + .iter() + .map(|entry| { + let resource = state + .resource_table + .get_mut(entry.resource) + .ok_or_else(bad_resource_id)?; + + wgc::binding_model::BindGroupEntry { + binding: entry.binding, + resource: match entry.resource_kind { + &"GPUSampler" => wgc::binding_model::BindingResource::Sampler( + *resource as wgc::id::SamplerId, + ), + &"GPUTextureView" => { + wgc::binding_model::BindingResource::TextureView( + *resource as wgc::id::TextureViewId, + ) + } + &"GPUBufferBinding" => { + wgc::binding_model::BindingResource::Buffer() + } // TODO + _ => unreachable!(), + }, } - &"GPUTextureView" => wgpu::BindingResource::TextureView( - resource as &mut wgpu::TextureView, - ), - &"GPUBufferBinding" => wgpu::BindingResource::Buffer(), // TODO - _ => unreachable!(), - }, - } - }) - .collect::<[wgpu::BindGroupEntry]>(), - }); + }) + .collect::>(), + ), + }, + (), // TODO + )?; let rid = state .resource_table diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 7d87f1969257e6..0f0f9abb05e1c9 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -15,7 +15,8 @@ use std::rc::Rc; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBufferArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, size: u64, usage: (), // TODO @@ -29,17 +30,25 @@ pub fn op_webgpu_create_buffer( ) -> Result { let args: CreateBufferArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let buffer = device.create_buffer(&wgpu::BufferDescriptor { - label: args.label.map(|label| &label), - size: args.size, - usage: (), // TODO - mapped_at_creation: args.mapped_at_creation.unwrap_or(false), - }); + let buffer = instance.device_create_buffer( + *device, + &wgc::resource::BufferDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + size: args.size, + usage: (), + mapped_at_creation: args.mapped_at_creation.unwrap_or(false), + }, + (), // TODO + )?; let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); @@ -51,7 +60,8 @@ pub fn op_webgpu_create_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferGetMapAsyncArgs { - rid: u32, + instance_rid: u32, + buffer_rid: u32, mode: u32, } @@ -63,12 +73,19 @@ pub async fn op_webgpu_buffer_get_map_async( let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let buffer = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - buffer.slice(..).map_async().await; // TODO + instance.buffer_map_async( + *buffer, + // TODO + )?; Ok(json!({})) } @@ -76,7 +93,8 @@ pub async fn op_webgpu_buffer_get_map_async( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferGetMappedRangeArgs { - rid: u32, + instance_rid: u32, + buffer_rid: u32, offset: u64, size: Option, } @@ -88,16 +106,20 @@ pub fn op_webgpu_buffer_get_mapped_range( ) -> Result { let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let buffer = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let end = args.size.map(|size| size + args.offset); - - let slice = buffer.slice(args.offset..end); // TODO - let view = slice.get_mapped_range(); - view[0]; // TODO + let slice = instance.buffer_get_mapped_range( + *buffer, + args.offset, + args.size, // TODO + )?; // TODO Ok(json!({})) } @@ -105,7 +127,8 @@ pub fn op_webgpu_buffer_get_mapped_range( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferUnmapArgs { - rid: u32, + instance_rid: u32, + buffer_rid: u32, } pub fn op_webgpu_buffer_unmap( @@ -115,12 +138,16 @@ pub fn op_webgpu_buffer_unmap( ) -> Result { let args: BufferUnmapArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let buffer = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - buffer.unmap(); + instance.buffer_unmap(*buffer)?; Ok(json!({})) } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index f3613b5f3589a3..987bd9ebf694c6 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -10,13 +10,15 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderBundleEncoderArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, color_formats: [String], depth_stencil_format: Option, @@ -30,24 +32,32 @@ pub fn op_webgpu_create_render_bundle_encoder( ) -> Result { let args: CreateRenderBundleEncoderArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = - device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { - label: args.label.map(|label| &label), - color_formats: &args - .color_formats - .iter() - .map(|format| serialize_texture_format(format.clone())?) - .collect::<[wgpu::TextureFormat]>(), + let render_bundle_encoder = instance.device_create_render_bundle_encoder( + *device, + &wgc::command::RenderBundleEncoderDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + color_formats: Cow::Owned( + args + .color_formats + .iter() + .map(|format| serialize_texture_format(format.clone())?) + .collect::>(), + ), // TODO depth_stencil_format: args .depth_stencil_format .map(|format| serialize_texture_format(format)?), sample_count: args.sample_count.unwrap_or(1), - }); + }, + )?; let rid = state .resource_table @@ -61,7 +71,8 @@ pub fn op_webgpu_create_render_bundle_encoder( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderBundleEncoderFinishArgs { - rid: u32, + instance_rid: u32, + render_bundle_encoder_rid: u32, label: Option, } @@ -72,15 +83,22 @@ pub fn op_webgpu_render_bundle_encoder_finish( ) -> Result { let args: RenderBundleEncoderFinishArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - let render_bundle = - render_bundle_encoder.finish(&wgpu::RenderBundleDescriptor { - label: args.label.map(|label| &label), - }); + let render_bundle = instance.render_bundle_encoder_finish( + render_bundle_encoder, // TODO + &wgc::command::RenderBundleDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + }, + (), // TODO + )?; let rid = state .resource_table diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index 3e83ce9fb0c500..c83dce2550d101 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -9,13 +9,15 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateCommandEncoderArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, measure_execution_time: Option, // TODO } @@ -27,15 +29,22 @@ pub fn op_webgpu_create_command_encoder( ) -> Result { let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: args.label.map(|label| &label), - }); + let command_encoder = instance.device_create_command_encoder( + *device, + &wgt::CommandEncoderDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + }, + (), // TODO + )?; let rid = state .resource_table @@ -70,7 +79,8 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderBeginRenderPassArgs { - rid: u32, + instance_rid: u32, + command_encoder_rid: u32, label: Option, // TODO color_attachments: [GPURenderPassColorAttachmentDescriptor], depth_stencil_attachment: @@ -85,45 +95,57 @@ pub fn op_webgpu_command_encoder_begin_render_pass( ) -> Result { let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let render_pass = - command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &args - .color_attachments - .iter() - .map(|color_attachment| { - wgpu::RenderPassColorAttachmentDescriptor { - attachment: state - .resource_table - .get_mut::(color_attachment.attachment) - .ok_or_else(bad_resource_id)?, - resolve_target: color_attachment.resolve_target.map(|rid| { - state + let render_pass = wgc::command::RenderPass::new( + *command_encoder, + wgc::command::RenderPassDescriptor { + color_attachments: Cow::Owned( + args + .color_attachments + .iter() + .map(|color_attachment| { + wgc::command::ColorAttachmentDescriptor { + attachment: *state .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id)? - }), - ops: (), // TODO - } - }) - .collect::<[wgpu::RenderPassColorAttachmentDescriptor]>(), + .get_mut::(color_attachment.attachment) + .ok_or_else(bad_resource_id)?, + resolve_target: color_attachment.resolve_target.map(|rid| { + *state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)? + }), + channel: PassChannel {}, // TODO + } + }) + .collect::>(), + ), depth_stencil_attachment: args.depth_stencil_attachment.map( |depth_stencil_attachment| { - wgpu::RenderPassDepthStencilAttachmentDescriptor { - attachment: state + &wgc::command::DepthStencilAttachmentDescriptor { + attachment: *state .resource_table - .get_mut::(depth_stencil_attachment.attachment) + .get_mut::( + depth_stencil_attachment.attachment, + ) .ok_or_else(bad_resource_id)?, - depth_ops: None, // TODO - stencil_ops: None, // TODO + depth: PassChannel {}, // TODO + stencil: PassChannel {}, // TODO } }, ), - }); + }, + ); + + instance.command_encoder_run_render_pass(*command_encoder, &render_pass)?; let rid = state .resource_table @@ -137,7 +159,8 @@ pub fn op_webgpu_command_encoder_begin_render_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderBeginComputePassArgs { - rid: u32, + instance_rid: u32, + command_encoder_rid: u32, label: Option, // TODO } @@ -148,12 +171,18 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( ) -> Result { let args: CommandEncoderBeginComputePassArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let compute_pass = command_encoder.begin_compute_pass(); + let compute_pass = wgc::command::ComputePass::new(*command_encoder); + + instance.command_encoder_run_compute_pass(*command_encoder, &compute_pass); let rid = state .resource_table @@ -175,7 +204,8 @@ struct GPUTextureCopyView { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyTextureToTextureArgs { - rid: u32, + instance_rid: u32, + command_encoder_rid: u32, source: GPUTextureCopyView, destination: GPUTextureCopyView, copy_size: (), // TODO @@ -189,34 +219,40 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - command_encoder.copy_texture_to_texture( - wgpu::TextureCopyView { - texture: state + instance.command_encoder_copy_texture_to_texture( + *command_encoder, + &wgc::command::TextureCopyView { + texture: *state .resource_table - .get_mut::(args.source.texture) + .get_mut::(args.source.texture) .ok_or_else(bad_resource_id)?, mip_level: args.source.mip_level.unwrap_or(0), origin: Default::default(), // TODO }, - wgpu::TextureCopyView { - texture: state + &wgc::command::TextureCopyView { + texture: *state .resource_table - .get_mut::(args.destination.texture) + .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), origin: Default::default(), // TODO }, - wgpu::Extent3d { + &wgt::Extent3d { + // TODO width: 0, height: 0, depth: 0, }, - ); + )?; Ok(json!({})) } @@ -224,7 +260,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderFinishArgs { - rid: u32, + instance_rid: u32, + command_encoder_rid: u32, label: Option, // TODO } @@ -235,12 +272,21 @@ pub fn op_webgpu_command_encoder_finish( ) -> Result { let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_buffer = command_encoder.finish(); + let command_buffer = instance.command_encoder_finish( + *command_encoder, + &wgt::CommandBufferDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + }, + )?; let rid = state .resource_table diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index e4d58f553c442e..896f3b0595ec93 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -141,35 +141,33 @@ pub fn init(rt: &mut deno_core::JsRuntime) { ); } -fn serialize_features(features: &wgpu::Features) -> Vec<&str> { +fn serialize_features(features: &wgt::Features) -> Vec<&str> { let mut extensions: Vec<&str> = vec![]; - if features.contains(wgpu::Features::DEPTH_CLAMPING) { + if features.contains(wgt::Features::DEPTH_CLAMPING) { extensions.push("depth-clamping"); } - if features.contains(wgpu::Features) { - // TODO + if features.contains(wgt::Features) { // TODO extensions.push("depth24unorm-stencil8"); } - if features.contains(wgpu::Features) { - // TODO + if features.contains(wgt::Features) { // TODO extensions.push("depth32float-stencil8"); } - if features.contains(wgpu::Features) { - // TODO + if features.contains(wgt::Features) { // TODO extensions.push("pipeline-statistics-query"); } - if features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC) { + if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) { extensions.push("texture-compression-bc"); } - if features.contains(wgpu::Features) { - // TODO + if features.contains(wgt::Features) { // TODO extensions.push("timestamp-query"); } extensions } +pub type WgcInstance = wgc::hub::Global; + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestAdapterArgs { @@ -183,24 +181,31 @@ pub async fn op_webgpu_request_adapter( ) -> Result { let args: RequestAdapterArgs = serde_json::from_value(args)?; - let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); // TODO: own op - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { + let instance = wgc::hub::Global::new( + "webgpu", + wgc::hub::IdentityManagerFactory, + wgt::BackendBit::PRIMARY, + ); // TODO: own op + let adapter = instance.request_adapter( + &wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { - Some(&"low-power") => wgpu::PowerPreference::LowPower, - Some(&"high-performance") => wgpu::PowerPreference::HighPerformance, + Some(&"low-power") => wgt::PowerPreference::LowPower, + Some(&"high-performance") => wgt::PowerPreference::HighPerformance, Some(_) => unreachable!(), - None => wgpu::PowerPreference::Default, + None => wgt::PowerPreference::Default, }, compatible_surface: None, // windowless - }) - .await - .unwrap(); // TODO: dont unwrap + }, + wgc::instance::AdapterInputs::Mask(wgt::BackendBit::PRIMARY, ()), // TODO + )?; - let name = adapter.get_info().name; - let extensions = serialize_features(&adapter.features()); + let name = instance.adapter_get_info(adapter)?.name; + let extensions = serialize_features(&instance.adapter_features(adapter)?); let mut state = state.borrow_mut(); + let rid = state + .resource_table + .add("webGPUInstance", Box::new(instance)); let rid = state.resource_table.add("webGPUAdapter", Box::new(adapter)); Ok(json!({ @@ -213,7 +218,8 @@ pub async fn op_webgpu_request_adapter( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestDeviceArgs { - rid: u32, + instance_rid: u32, + adapter_rid: u32, extensions: Option<[String]>, limits: Option, // TODO } @@ -226,31 +232,32 @@ pub async fn op_webgpu_request_device( let args: RequestDeviceArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let adapter = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.adapter_rid) .ok_or_else(bad_resource_id)?; - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - // TODO: should accept label - features: Default::default(), // TODO - limits: Default::default(), // TODO - shader_validation: false, // TODO - }, - None, // debug - ) - .await - .unwrap(); // TODO: dont unwrap + let device = instance.adapter_request_device( + *adapter, + &wgt::DeviceDescriptor { + // TODO: should accept label + features: Default::default(), // TODO + limits: Default::default(), // TODO + shader_validation: false, // TODO + }, + None, + (), // TODO + )?; - let extensions = serialize_features(&device.features()); - let limits = device.limits(); + let extensions = serialize_features(&instance.device_features(device)?); + let limits = instance.device_limits(device)?; // TODO let device_rid = state.resource_table.add("webGPUDevice", Box::new(device)); - let queue_rid = state.resource_table.add("webGPUQueue", Box::new(queue)); - Ok(json!({ "deviceRid": device_rid, "queueRid": queue_rid, diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 985b671b02ada6..db571d1859f2f4 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -11,96 +11,93 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; fn serialize_programmable_stage_descriptor( state: &mut OpState, programmable_stage_descriptor: GPUProgrammableStageDescriptor, -) -> Result { - Ok(wgpu::ProgrammableStageDescriptor { - module: state +) -> Result { + Ok(wgc::pipeline::ProgrammableStageDescriptor { + module: *state .resource_table - .get_mut::(programmable_stage_descriptor.module) + .get_mut::(programmable_stage_descriptor.module) .ok_or_else(bad_resource_id)?, - entry_point: &programmable_stage_descriptor.entry_point, + entry_point: Cow::Owned(programmable_stage_descriptor.entry_point), }) } -fn serialize_stencil_operation(operation: String) -> wgpu::StencilOperation { +fn serialize_stencil_operation(operation: String) -> wgt::StencilOperation { match operation { - &"keep" => wgpu::StencilOperation::Keep, - &"zero" => wgpu::StencilOperation::Zero, - &"replace" => wgpu::StencilOperation::Replace, - &"invert" => wgpu::StencilOperation::Invert, - &"increment-clamp" => wgpu::StencilOperation::IncrementClamp, - &"decrement-clamp" => wgpu::StencilOperation::DecrementClamp, - &"increment-wrap" => wgpu::StencilOperation::IncrementWrap, - &"decrement-wrap" => wgpu::StencilOperation::DecrementWrap, + &"keep" => wgt::StencilOperation::Keep, + &"zero" => wgt::StencilOperation::Zero, + &"replace" => wgt::StencilOperation::Replace, + &"invert" => wgt::StencilOperation::Invert, + &"increment-clamp" => wgt::StencilOperation::IncrementClamp, + &"decrement-clamp" => wgt::StencilOperation::DecrementClamp, + &"increment-wrap" => wgt::StencilOperation::IncrementWrap, + &"decrement-wrap" => wgt::StencilOperation::DecrementWrap, _ => unreachable!(), } } fn serialize_stencil_state_face_descriptor( state: GPUStencilStateFaceDescriptor, -) -> wgpu::StencilStateFaceDescriptor { - wgpu::StencilStateFaceDescriptor { +) -> wgt::StencilStateFaceDescriptor { + wgt::StencilStateFaceDescriptor { compare: state .compare - .map_or(wgpu::CompareFunction::Always, |compare| { - serialize_compare_function(compare) - }), - fail_op: state.fail_op.map_or(wgpu::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), + .map_or(wgt::CompareFunction::Always, serialize_compare_function), + fail_op: state + .fail_op + .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), depth_fail_op: state .depth_fail_op - .map_or(wgpu::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), - pass_op: state.pass_op.map_or(wgpu::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), + .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), + pass_op: state + .pass_op + .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), } } -fn serialize_blend_factor(blend_factor: String) -> wgpu::BlendFactor { +fn serialize_blend_factor(blend_factor: String) -> wgt::BlendFactor { match blend_factor { - &"zero" => wgpu::BlendFactor::Zero, - &"one" => wgpu::BlendFactor::One, - &"src-color" => wgpu::BlendFactor::SrcColor, - &"one-minus-src-color" => wgpu::BlendFactor::OneMinusSrcColor, - &"src-alpha" => wgpu::BlendFactor::SrcAlpha, - &"one-minus-src-alpha" => wgpu::BlendFactor::OneMinusSrcAlpha, - &"dst-color" => wgpu::BlendFactor::DstColor, - &"one-minus-dst-color" => wgpu::BlendFactor::OneMinusDstColor, - &"dst-alpha" => wgpu::BlendFactor::DstAlpha, - &"one-minus-dst-alpha" => wgpu::BlendFactor::OneMinusDstAlpha, - &"src-alpha-saturated" => wgpu::BlendFactor::SrcAlphaSaturated, - &"blend-color" => wgpu::BlendFactor::BlendColor, - &"one-minus-blend-color" => wgpu::BlendFactor::OneMinusBlendColor, + &"zero" => wgt::BlendFactor::Zero, + &"one" => wgt::BlendFactor::One, + &"src-color" => wgt::BlendFactor::SrcColor, + &"one-minus-src-color" => wgt::BlendFactor::OneMinusSrcColor, + &"src-alpha" => wgt::BlendFactor::SrcAlpha, + &"one-minus-src-alpha" => wgt::BlendFactor::OneMinusSrcAlpha, + &"dst-color" => wgt::BlendFactor::DstColor, + &"one-minus-dst-color" => wgt::BlendFactor::OneMinusDstColor, + &"dst-alpha" => wgt::BlendFactor::DstAlpha, + &"one-minus-dst-alpha" => wgt::BlendFactor::OneMinusDstAlpha, + &"src-alpha-saturated" => wgt::BlendFactor::SrcAlphaSaturated, + &"blend-color" => wgt::BlendFactor::BlendColor, + &"one-minus-blend-color" => wgt::BlendFactor::OneMinusBlendColor, _ => unreachable!(), } } fn serialize_blend_descriptor( blend: GPUBlendDescriptor, -) -> wgpu::BlendDescriptor { - wgpu::BlendDescriptor { +) -> wgt::BlendDescriptor { + wgt::BlendDescriptor { src_factor: blend .src_factor - .map_or(wgpu::BlendFactor::One, serialize_blend_factor), + .map_or(wgt::BlendFactor::One, serialize_blend_factor), dst_factor: blend .dst_factor - .map_or(wgpu::BlendFactor::Zero, serialize_blend_factor), + .map_or(wgt::BlendFactor::Zero, serialize_blend_factor), operation: match blend.operation { - Some(&"add") => wgpu::BlendOperation::Add, - Some(&"subtract") => wgpu::BlendOperation::Subtract, - Some(&"reverse-subtract") => wgpu::BlendOperation::ReverseSubtract, - Some(&"min") => wgpu::BlendOperation::Min, - Some(&"max") => wgpu::BlendOperation::Max, + Some(&"add") => wgt::BlendOperation::Add, + Some(&"subtract") => wgt::BlendOperation::Subtract, + Some(&"reverse-subtract") => wgt::BlendOperation::ReverseSubtract, + Some(&"min") => wgt::BlendOperation::Min, + Some(&"max") => wgt::BlendOperation::Max, Some(_) => unreachable!(), - None => wgpu::BlendOperation::Add, + None => wgt::BlendOperation::Add, }, } } @@ -115,7 +112,8 @@ struct GPUProgrammableStageDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateComputePipelineArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, layout: Option, compute_stage: GPUProgrammableStageDescriptor, @@ -128,25 +126,34 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let compute_pipeline = - device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - label: args.label.map(|label| &label), + let (compute_pipeline, smth) = instance.device_create_compute_pipeline( + // TODO + *device, + &wgc::pipeline::ComputePipelineDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), layout: args.layout.map(|rid| { - state + *state .resource_table - .get_mut::(rid) + .get_mut::(rid) .ok_or_else(bad_resource_id)? }), compute_stage: serialize_programmable_stage_descriptor( state, args.compute_stage, )?, - }); + }, + (), // TODO + (), // TODO + )?; let rid = state .resource_table @@ -160,7 +167,8 @@ pub fn op_webgpu_create_compute_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePipelineGetBindGroupLayoutArgs { - rid: u32, + instance_rid: u32, + compute_pipeline_rid: u32, index: u32, } @@ -172,12 +180,17 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( let args: ComputePipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let compute_pipeline = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.compute_pipeline_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = compute_pipeline.get_bind_group_layout(args.index); + let bind_group_layout = instance + .compute_pipeline_get_bind_group_layout(*compute_pipeline, args.index)?; let rid = state .resource_table @@ -263,7 +276,8 @@ struct GPUVertexStateDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderPipelineArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, layout: Option, vertex_stage: GPUProgrammableStageDescriptor, @@ -285,18 +299,23 @@ pub fn op_webgpu_create_render_pipeline( ) -> Result { let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let render_pipeline = - device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: args.label.map(|label| &label), + let (render_pipeline, smth) = instance.device_create_render_pipeline( + *device, + &wgc::pipeline::RenderPipelineDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), layout: args.layout.map(|rid| { - state + *state .resource_table - .get_mut::(rid) + .get_mut::(rid) .ok_or_else(bad_resource_id)? }), vertex_stage: serialize_programmable_stage_descriptor( @@ -312,19 +331,19 @@ pub fn op_webgpu_create_render_pipeline( }, ), rasterization_state: args.rasterization_state.map( - |rasterization_state| wgpu::RasterizationStateDescriptor { + |rasterization_state| wgt::RasterizationStateDescriptor { front_face: match rasterization_state.front_face { - Some(&"ccw") => wgpu::FrontFace::Ccw, - Some(&"cw") => wgpu::FrontFace::Cw, + Some(&"ccw") => wgt::FrontFace::Ccw, + Some(&"cw") => wgt::FrontFace::Cw, Some(_) => unreachable!(), - None => wgpu::FrontFace::Ccw, + None => wgt::FrontFace::Ccw, }, cull_mode: match rasterization_state.cull_mode { - Some(&"none") => wgpu::CullMode::None, - Some(&"front") => wgpu::CullMode::Front, - Some(&"back") => wgpu::CullMode::Back, + Some(&"none") => wgt::CullMode::None, + Some(&"front") => wgt::CullMode::Front, + Some(&"back") => wgt::CullMode::Back, Some(_) => unreachable!(), - None => wgpu::CullMode::None, + None => wgt::CullMode::None, }, clamp_depth: rasterization_state.clamp_depth.unwrap_or(false), depth_bias: rasterization_state.depth_bias.unwrap_or(0), @@ -335,43 +354,45 @@ pub fn op_webgpu_create_render_pipeline( }, ), primitive_topology: match args.primitive_topology { - &"point-list" => wgpu::PrimitiveTopology::PointList, - &"line-list" => wgpu::PrimitiveTopology::LineList, - &"line-strip" => wgpu::PrimitiveTopology::LineStrip, - &"triangle-list" => wgpu::PrimitiveTopology::TriangleList, - &"triangle-strip" => wgpu::PrimitiveTopology::TriangleStrip, + &"point-list" => wgt::PrimitiveTopology::PointList, + &"line-list" => wgt::PrimitiveTopology::LineList, + &"line-strip" => wgt::PrimitiveTopology::LineStrip, + &"triangle-list" => wgt::PrimitiveTopology::TriangleList, + &"triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, _ => unreachable!(), }, - color_states: &args - .color_states - .iter() - .map(|color_state| { - wgpu::ColorStateDescriptor { - format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state - .alpha_blend - .map_or("", serialize_blend_descriptor), // TODO - color_blend: color_state - .color_blend - .map_or("", serialize_blend_descriptor), // TODO - write_mask: color_state.write_mask, // TODO - } - }) - .collect::<[wgpu::ColorStateDescriptor]>(), + color_states: Cow::Owned( + args + .color_states + .iter() + .map(|color_state| { + wgt::ColorStateDescriptor { + format: serialize_texture_format(color_state.format.clone())?, + alpha_blend: color_state + .alpha_blend + .map_or("", serialize_blend_descriptor), // TODO + color_blend: color_state + .color_blend + .map_or("", serialize_blend_descriptor), // TODO + write_mask: color_state.write_mask, // TODO + } + }) + .collect::>(), + ), depth_stencil_state: args.depth_stencil_state.map(|state| { - wgpu::DepthStencilStateDescriptor { + wgt::DepthStencilStateDescriptor { format: serialize_texture_format(state.format)?, depth_write_enabled: state.depth_write_enabled.unwrap_or(false), depth_compare: state .depth_compare - .map_or(wgpu::CompareFunction::Always, serialize_compare_function), - stencil: wgpu::StencilStateDescriptor { + .map_or(wgt::CompareFunction::Always, serialize_compare_function), + stencil: wgt::StencilStateDescriptor { front: state.stencil_front.map_or( - wgpu::StencilStateFaceDescriptor::IGNORE, + wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), back: state.stencil_front.map_or( - wgpu::StencilStateFaceDescriptor::IGNORE, + wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), @@ -379,80 +400,87 @@ pub fn op_webgpu_create_render_pipeline( }, } }), - vertex_state: wgpu::VertexStateDescriptor { + vertex_state: wgc::pipeline::VertexStateDescriptor { index_format: args.vertex_state.unwrap().index_format.map_or( - "", + // TODO + "", // TODO |format| match format { - // TODO - &"uint16" => wgpu::IndexFormat::Uint16, - &"uint32" => wgpu::IndexFormat::Uint32, + &"uint16" => wgt::IndexFormat::Uint16, + &"uint32" => wgt::IndexFormat::Uint32, _ => unreachable!(), }, ), - vertex_buffers: &args - .vertex_state - .unwrap() - .vertex_buffers - .unwrap() // TODO - .iter() - .map(|buffer| wgpu::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode { - Some(&"vertex") => wgpu::InputStepMode::Vertex, - Some(&"instance") => wgpu::InputStepMode::Instance, - Some(_) => unreachable!(), - None => wgpu::InputStepMode::Vertex, - }, - attributes: &buffer - .attributes - .iter() - .map(|attribute| wgpu::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format { - &"uchar2" => wgpu::VertexFormat::Uchar2, - &"uchar4" => wgpu::VertexFormat::Uchar4, - &"char2" => wgpu::VertexFormat::Char2, - &"char4" => wgpu::VertexFormat::Char4, - &"uchar2norm" => wgpu::VertexFormat::Uchar2Norm, - &"uchar4norm" => wgpu::VertexFormat::Uchar4, - &"char2norm" => wgpu::VertexFormat::Char2Norm, - &"char4norm" => wgpu::VertexFormat::Char4Norm, - &"ushort2" => wgpu::VertexFormat::Ushort2, - &"ushort4" => wgpu::VertexFormat::Ushort4, - &"short2" => wgpu::VertexFormat::Short2, - &"short4" => wgpu::VertexFormat::Short4, - &"ushort2norm" => wgpu::VertexFormat::Ushort2Norm, - &"ushort4norm" => wgpu::VertexFormat::Ushort4Norm, - &"short2norm" => wgpu::VertexFormat::Short2Norm, - &"short4norm" => wgpu::VertexFormat::Short4Norm, - &"half2" => wgpu::VertexFormat::Half2, - &"half4" => wgpu::VertexFormat::Half4, - &"float" => wgpu::VertexFormat::Float, - &"float2" => wgpu::VertexFormat::Float2, - &"float3" => wgpu::VertexFormat::Float3, - &"float4" => wgpu::VertexFormat::Float4, - &"uint" => wgpu::VertexFormat::Uint, - &"uint2" => wgpu::VertexFormat::Uint2, - &"uint3" => wgpu::VertexFormat::Uint3, - &"uint4" => wgpu::VertexFormat::Uint4, - &"int" => wgpu::VertexFormat::Int, - &"int2" => wgpu::VertexFormat::Int2, - &"int3" => wgpu::VertexFormat::Int3, - &"int4" => wgpu::VertexFormat::Int4, - _ => unreachable!(), - }, - shader_location: attribute.shader_location, - }) - .collect::<[wgpu::VertexAttributeDescriptor]>(), - }) - .collect::<[wgpu::VertexBufferDescriptor]>(), + vertex_buffers: Cow::Owned( + args + .vertex_state + .unwrap() + .vertex_buffers + .unwrap() // TODO + .iter() + .map(|buffer| wgc::pipeline::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode { + Some(&"vertex") => wgt::InputStepMode::Vertex, + Some(&"instance") => wgt::InputStepMode::Instance, + Some(_) => unreachable!(), + None => wgt::InputStepMode::Vertex, + }, + attributes: Cow::Owned( + buffer + .attributes + .iter() + .map(|attribute| wgt::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format { + &"uchar2" => wgt::VertexFormat::Uchar2, + &"uchar4" => wgt::VertexFormat::Uchar4, + &"char2" => wgt::VertexFormat::Char2, + &"char4" => wgt::VertexFormat::Char4, + &"uchar2norm" => wgt::VertexFormat::Uchar2Norm, + &"uchar4norm" => wgt::VertexFormat::Uchar4, + &"char2norm" => wgt::VertexFormat::Char2Norm, + &"char4norm" => wgt::VertexFormat::Char4Norm, + &"ushort2" => wgt::VertexFormat::Ushort2, + &"ushort4" => wgt::VertexFormat::Ushort4, + &"short2" => wgt::VertexFormat::Short2, + &"short4" => wgt::VertexFormat::Short4, + &"ushort2norm" => wgt::VertexFormat::Ushort2Norm, + &"ushort4norm" => wgt::VertexFormat::Ushort4Norm, + &"short2norm" => wgt::VertexFormat::Short2Norm, + &"short4norm" => wgt::VertexFormat::Short4Norm, + &"half2" => wgt::VertexFormat::Half2, + &"half4" => wgt::VertexFormat::Half4, + &"float" => wgt::VertexFormat::Float, + &"float2" => wgt::VertexFormat::Float2, + &"float3" => wgt::VertexFormat::Float3, + &"float4" => wgt::VertexFormat::Float4, + &"uint" => wgt::VertexFormat::Uint, + &"uint2" => wgt::VertexFormat::Uint2, + &"uint3" => wgt::VertexFormat::Uint3, + &"uint4" => wgt::VertexFormat::Uint4, + &"int" => wgt::VertexFormat::Int, + &"int2" => wgt::VertexFormat::Int2, + &"int3" => wgt::VertexFormat::Int3, + &"int4" => wgt::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::>(), + ), + }) + .collect::>(), + ), }, sample_count: args.sample_count.unwrap_or(1), sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), alpha_to_coverage_enabled: args .alpha_to_coverage_enabled .unwrap_or(false), - }); + }, + (), // TODO + (), // TODO + )?; let rid = state .resource_table @@ -466,7 +494,8 @@ pub fn op_webgpu_create_render_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPipelineGetBindGroupLayoutArgs { - rid: u32, + instance_rid: u32, + render_pipeline_rid: u32, index: u32, } @@ -478,12 +507,17 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let render_pipeline = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.render_pipeline_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = render_pipeline.get_bind_group_layout(args.index); + let bind_group_layout = instance + .render_pipeline_get_bind_group_layout(*render_pipeline, args.index)?; let rid = state .resource_table diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index e2147d59a20b2a..8c7035ffef5dbf 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -9,38 +9,39 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; -fn serialize_address_mode(address_mode: Option) -> wgpu::AddressMode { +fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { match address_mode { - Some(&"clamp-to-edge") => wgpu::AddressMode::ClampToEdge, - Some(&"repeat") => wgpu::AddressMode::Repeat, - Some(&"mirror-repeat") => wgpu::AddressMode::MirrorRepeat, + Some(&"clamp-to-edge") => wgt::AddressMode::ClampToEdge, + Some(&"repeat") => wgt::AddressMode::Repeat, + Some(&"mirror-repeat") => wgt::AddressMode::MirrorRepeat, Some(_) => unreachable!(), - None => wgpu::AddressMode::ClampToEdge, + None => wgt::AddressMode::ClampToEdge, } } -fn serialize_filter_mode(filter_mode: Option) -> wgpu::FilterMode { +fn serialize_filter_mode(filter_mode: Option) -> wgt::FilterMode { match filter_mode { - Some(&"nearest") => wgpu::FilterMode::Nearest, - Some(&"linear") => wgpu::FilterMode::Linear, + Some(&"nearest") => wgt::FilterMode::Nearest, + Some(&"linear") => wgt::FilterMode::Linear, Some(_) => unreachable!(), - None => wgpu::FilterMode::Nearest, + None => wgt::FilterMode::Nearest, } } -pub fn serialize_compare_function(compare: String) -> wgpu::CompareFunction { +pub fn serialize_compare_function(compare: String) -> wgt::CompareFunction { match compare { - &"never" => wgpu::CompareFunction::Never, - &"less" => wgpu::CompareFunction::Less, - &"equal" => wgpu::CompareFunction::Equal, - &"less-equal" => wgpu::CompareFunction::LessEqual, - &"greater" => wgpu::CompareFunction::Greater, - &"not-equal" => wgpu::CompareFunction::NotEqual, - &"greater-equal" => wgpu::CompareFunction::GreaterEqual, - &"always" => wgpu::CompareFunction::Always, + &"never" => wgt::CompareFunction::Never, + &"less" => wgt::CompareFunction::Less, + &"equal" => wgt::CompareFunction::Equal, + &"less-equal" => wgt::CompareFunction::LessEqual, + &"greater" => wgt::CompareFunction::Greater, + &"not-equal" => wgt::CompareFunction::NotEqual, + &"greater-equal" => wgt::CompareFunction::GreaterEqual, + &"always" => wgt::CompareFunction::Always, _ => unreachable!(), } } @@ -48,7 +49,8 @@ pub fn serialize_compare_function(compare: String) -> wgpu::CompareFunction { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateSamplerArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, address_mode_u: Option, address_mode_v: Option, @@ -69,26 +71,34 @@ pub fn op_webgpu_create_sampler( ) -> Result { let args: CreateSamplerArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: args.label.map(|label| &label), - address_mode_u: serialize_address_mode(args.address_mode_u), - address_mode_v: serialize_address_mode(args.address_mode_v), - address_mode_w: serialize_address_mode(args.address_mode_w), - mag_filter: serialize_filter_mode(args.mag_filter), - min_filter: serialize_filter_mode(args.min_filter), - mipmap_filter: serialize_filter_mode(args.mipmap_filter), - lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO - compare: args - .compare - .map(|compare| serialize_compare_function(compare)), - anisotropy_clamp: args.max_anisotropy.unwrap_or(1), // TODO - }); + let sampler = instance.device_create_sampler( + *device, + &wgc::resource::SamplerDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + address_modes: [ + serialize_address_mode(args.address_mode_u), + serialize_address_mode(args.address_mode_v), + serialize_address_mode(args.address_mode_w), + ], + mag_filter: serialize_filter_mode(args.mag_filter), + min_filter: serialize_filter_mode(args.min_filter), + mipmap_filter: serialize_filter_mode(args.mipmap_filter), + lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), + lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO + compare: args.compare.map(serialize_compare_function), + anisotropy_clamp: args.max_anisotropy.unwrap_or(1), // TODO + }, + (), // TODO + )?; let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 19e5c081b48e5b..2004bb9bcaf782 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -15,7 +15,8 @@ use std::rc::Rc; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateShaderModuleArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, code: String, source_map: (), // TODO @@ -28,12 +29,20 @@ pub fn op_webgpu_create_shader_module( ) -> Result { let args: CreateShaderModuleArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let shader_module = device.create_shader_module(wgpu::ShaderModuleSource); // TODO + let shader_module = instance.device_create_shader_module( + *device, + wgc::pipeline::ShaderModuleSource, // TODO + (), // TODO + )?; let rid = state .resource_table diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 04b4b52e5c760f..2798759ba76ac0 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -9,97 +9,111 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; pub fn serialize_texture_format( format: String, -) -> Result { +) -> Result { Ok(match format { // 8-bit formats - &"r8unorm" => wgpu::TextureFormat::R8Unorm, - &"r8snorm" => wgpu::TextureFormat::R8Snorm, - &"r8uint" => wgpu::TextureFormat::R8Uint, - &"r8sint" => wgpu::TextureFormat::R8Sint, + &"r8unorm" => wgt::TextureFormat::R8Unorm, + &"r8snorm" => wgt::TextureFormat::R8Snorm, + &"r8uint" => wgt::TextureFormat::R8Uint, + &"r8sint" => wgt::TextureFormat::R8Sint, // 16-bit formats - &"r16uint" => wgpu::TextureFormat::R16Uint, - &"r16sint" => wgpu::TextureFormat::R16Sint, - &"r16float" => wgpu::TextureFormat::R16Float, - &"rg8unorm" => wgpu::TextureFormat::Rg8Unorm, - &"rg8snorm" => wgpu::TextureFormat::Rg8Snorm, - &"rg8uint" => wgpu::TextureFormat::Rg8Uint, - &"rg8sint" => wgpu::TextureFormat::Rg8Sint, + &"r16uint" => wgt::TextureFormat::R16Uint, + &"r16sint" => wgt::TextureFormat::R16Sint, + &"r16float" => wgt::TextureFormat::R16Float, + &"rg8unorm" => wgt::TextureFormat::Rg8Unorm, + &"rg8snorm" => wgt::TextureFormat::Rg8Snorm, + &"rg8uint" => wgt::TextureFormat::Rg8Uint, + &"rg8sint" => wgt::TextureFormat::Rg8Sint, // 32-bit formats - &"r32uint" => wgpu::TextureFormat::R32Uint, - &"r32sint" => wgpu::TextureFormat::R32Sint, - &"r32float" => wgpu::TextureFormat::R32Float, - &"rg16uint" => wgpu::TextureFormat::Rg16Uint, - &"rg16sint" => wgpu::TextureFormat::Rg16Sint, - &"rg16float" => wgpu::TextureFormat::Rg16Float, - &"rgba8unorm" => wgpu::TextureFormat::Rgba8Unorm, - &"rgba8unorm-srgb" => wgpu::TextureFormat::Rgba8UnormSrgb, - &"rgba8snorm" => wgpu::TextureFormat::Rgba8Snorm, - &"rgba8uint" => wgpu::TextureFormat::Rgba8Uint, - &"rgba8sint" => wgpu::TextureFormat::Rgba8Sint, - &"bgra8unorm" => wgpu::TextureFormat::Bgra8Unorm, - &"bgra8unorm-srgb" => wgpu::TextureFormat::Bgra8UnormSrgb, + &"r32uint" => wgt::TextureFormat::R32Uint, + &"r32sint" => wgt::TextureFormat::R32Sint, + &"r32float" => wgt::TextureFormat::R32Float, + &"rg16uint" => wgt::TextureFormat::Rg16Uint, + &"rg16sint" => wgt::TextureFormat::Rg16Sint, + &"rg16float" => wgt::TextureFormat::Rg16Float, + &"rgba8unorm" => wgt::TextureFormat::Rgba8Unorm, + &"rgba8unorm-srgb" => wgt::TextureFormat::Rgba8UnormSrgb, + &"rgba8snorm" => wgt::TextureFormat::Rgba8Snorm, + &"rgba8uint" => wgt::TextureFormat::Rgba8Uint, + &"rgba8sint" => wgt::TextureFormat::Rgba8Sint, + &"bgra8unorm" => wgt::TextureFormat::Bgra8Unorm, + &"bgra8unorm-srgb" => wgt::TextureFormat::Bgra8UnormSrgb, // Packed 32-bit formats - &"rgb9e5ufloat" => return Err(not_supported()), // wgpu-rs#590 - &"rgb10a2unorm" => wgpu::TextureFormat::Rgb10a2Unorm, - &"rg11b10ufloat" => wgpu::TextureFormat::Rg11b10Float, + &"rgb9e5ufloat" => return Err(not_supported()), // wgpu#967 + &"rgb10a2unorm" => wgt::TextureFormat::Rgb10a2Unorm, + &"rg11b10ufloat" => wgt::TextureFormat::Rg11b10Float, // 64-bit formats - &"rg32uint" => wgpu::TextureFormat::Rg32Uint, - &"rg32sint" => wgpu::TextureFormat::Rg32Sint, - &"rg32float" => wgpu::TextureFormat::Rg32Float, - &"rgba16uint" => wgpu::TextureFormat::Rgba16Uint, - &"rgba16sint" => wgpu::TextureFormat::Rgba16Sint, - &"rgba16float" => wgpu::TextureFormat::Rgba16Float, + &"rg32uint" => wgt::TextureFormat::Rg32Uint, + &"rg32sint" => wgt::TextureFormat::Rg32Sint, + &"rg32float" => wgt::TextureFormat::Rg32Float, + &"rgba16uint" => wgt::TextureFormat::Rgba16Uint, + &"rgba16sint" => wgt::TextureFormat::Rgba16Sint, + &"rgba16float" => wgt::TextureFormat::Rgba16Float, // 128-bit formats - &"rgba32uint" => wgpu::TextureFormat::Rgba32Uint, - &"rgba32sint" => wgpu::TextureFormat::Rgba32Sint, - &"rgba32float" => wgpu::TextureFormat::Rgba32Float, + &"rgba32uint" => wgt::TextureFormat::Rgba32Uint, + &"rgba32sint" => wgt::TextureFormat::Rgba32Sint, + &"rgba32float" => wgt::TextureFormat::Rgba32Float, // Depth and stencil formats - &"stencil8" => return Err(not_supported()), // wgpu-rs#590 - &"depth16unorm" => return Err(not_supported()), // wgpu-rs#590 - &"depth24plus" => wgpu::TextureFormat::Depth24Plus, - &"depth24plus-stencil8" => wgpu::TextureFormat::Depth24PlusStencil8, - &"depth32float" => wgpu::TextureFormat::Depth32Float, + &"stencil8" => return Err(not_supported()), // wgpu#967 + &"depth16unorm" => return Err(not_supported()), // wgpu#967 + &"depth24plus" => wgt::TextureFormat::Depth24Plus, + &"depth24plus-stencil8" => wgt::TextureFormat::Depth24PlusStencil8, + &"depth32float" => wgt::TextureFormat::Depth32Float, // BC compressed formats usable if "texture-compression-bc" is both // supported by the device/user agent and enabled in requestDevice. - &"bc1-rgba-unorm" => wgpu::TextureFormat::Bc1RgbaUnorm, - &"bc1-rgba-unorm-srgb" => wgpu::TextureFormat::Bc1RgbaUnormSrgb, - &"bc2-rgba-unorm" => wgpu::TextureFormat::Bc2RgbaUnorm, - &"bc2-rgba-unorm-srgb" => wgpu::TextureFormat::Bc2RgbaUnormSrgb, - &"bc3-rgba-unorm" => wgpu::TextureFormat::Bc3RgbaUnorm, - &"bc3-rgba-unorm-srgb" => wgpu::TextureFormat::Bc3RgbaUnormSrgb, - &"bc4-r-unorm" => wgpu::TextureFormat::Bc4RUnorm, - &"bc4-r-snorm" => wgpu::TextureFormat::Bc4RSnorm, - &"bc5-rg-unorm" => wgpu::TextureFormat::Bc5RgUnorm, - &"bc5-rg-snorm" => wgpu::TextureFormat::Bc5RgSnorm, - &"bc6h-rgb-ufloat" => wgpu::TextureFormat::Bc6hRgbUfloat, - &"bc6h-rgb-float" => wgpu::TextureFormat::Bc6hRgbSfloat, // wgpu-rs#590 - &"bc7-rgba-unorm" => wgpu::TextureFormat::Bc7RgbaUnorm, - &"bc7-rgba-unorm-srgb" => wgpu::TextureFormat::Bc7RgbaUnormSrgb, + &"bc1-rgba-unorm" => wgt::TextureFormat::Bc1RgbaUnorm, + &"bc1-rgba-unorm-srgb" => wgt::TextureFormat::Bc1RgbaUnormSrgb, + &"bc2-rgba-unorm" => wgt::TextureFormat::Bc2RgbaUnorm, + &"bc2-rgba-unorm-srgb" => wgt::TextureFormat::Bc2RgbaUnormSrgb, + &"bc3-rgba-unorm" => wgt::TextureFormat::Bc3RgbaUnorm, + &"bc3-rgba-unorm-srgb" => wgt::TextureFormat::Bc3RgbaUnormSrgb, + &"bc4-r-unorm" => wgt::TextureFormat::Bc4RUnorm, + &"bc4-r-snorm" => wgt::TextureFormat::Bc4RSnorm, + &"bc5-rg-unorm" => wgt::TextureFormat::Bc5RgUnorm, + &"bc5-rg-snorm" => wgt::TextureFormat::Bc5RgSnorm, + &"bc6h-rgb-ufloat" => wgt::TextureFormat::Bc6hRgbUfloat, + &"bc6h-rgb-float" => wgt::TextureFormat::Bc6hRgbSfloat, // wgpu#967 + &"bc7-rgba-unorm" => wgt::TextureFormat::Bc7RgbaUnorm, + &"bc7-rgba-unorm-srgb" => wgt::TextureFormat::Bc7RgbaUnormSrgb, // "depth24unorm-stencil8" extension - &"depth24unorm-stencil8" => return Err(not_supported()), // wgpu-rs#590 + &"depth24unorm-stencil8" => return Err(not_supported()), // wgpu#967 // "depth32float-stencil8" extension - &"depth32float-stencil8" => return Err(not_supported()), // wgpu-rs#590 + &"depth32float-stencil8" => return Err(not_supported()), // wgpu#967 _ => unreachable!(), }) } +pub fn serialize_dimension(dimension: String) -> wgt::TextureViewDimension { + match dimension { + &"1d" => wgt::TextureViewDimension::D1, + &"2d" => wgt::TextureViewDimension::D2, + &"2d-array" => wgt::TextureViewDimension::D2Array, + &"cube" => wgt::TextureViewDimension::Cube, + &"cube-array" => wgt::TextureViewDimension::CubeArray, + &"3d" => wgt::TextureViewDimension::D3, + _ => unreachable!(), + } +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureArgs { - rid: u32, + instance_rid: u32, + device_rid: u32, label: Option, mip_level_count: Option, sample_count: Option, @@ -115,26 +129,34 @@ pub fn op_webgpu_create_texture( ) -> Result { let args: CreateTextureArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let device = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let texture = device.create_texture(&wgpu::TextureDescriptor { - label: args.label.map(|label| &label), - size: Default::default(), // TODO - mip_level_count: args.mip_level_count.unwrap_or(1), - sample_count: args.sample_count.unwrap_or(1), - dimension: match args.dimension { - Some(&"1d") => wgpu::TextureDimension::D1, - Some(&"2d") => wgpu::TextureDimension::D2, - Some(&"3d") => wgpu::TextureDimension::D3, - Some(_) => unreachable!(), - None => wgpu::TextureDimension::D2, + let texture = instance.device_create_texture( + *device, + &wgc::resource::TextureDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + size: Default::default(), // TODO + mip_level_count: args.mip_level_count.unwrap_or(1), + sample_count: args.sample_count.unwrap_or(1), + dimension: match args.dimension { + Some(&"1d") => wgt::TextureDimension::D1, + Some(&"2d") => wgt::TextureDimension::D2, + Some(&"3d") => wgt::TextureDimension::D3, + Some(_) => unreachable!(), + None => wgt::TextureDimension::D2, + }, + format: serialize_texture_format(args.format)?, + usage: (), // TODO }, - format: serialize_texture_format(args.format)?, - usage: (), // TODO - }); + (), // TODO + )?; let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); @@ -143,22 +165,11 @@ pub fn op_webgpu_create_texture( })) } -pub fn serialize_dimension(dimension: String) -> wgpu::TextureViewDimension { - match dimension { - &"1d" => wgpu::TextureViewDimension::D1, - &"2d" => wgpu::TextureViewDimension::D2, - &"2d-array" => wgpu::TextureViewDimension::D2Array, - &"cube" => wgpu::TextureViewDimension::Cube, - &"cube-array" => wgpu::TextureViewDimension::CubeArray, - &"3d" => wgpu::TextureViewDimension::D3, - _ => unreachable!(), - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureViewArgs { - rid: u32, + instance_rid: u32, + texture_rid: u32, label: Option, format: Option, dimension: Option, @@ -176,29 +187,37 @@ pub fn op_webgpu_create_texture_view( ) -> Result { let args: CreateTextureViewArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; let texture = state .resource_table - .get_mut::(args.rid) + .get_mut::(args.texture_rid) .ok_or_else(bad_resource_id)?; - let texture_view = texture.create_view(&wgpu::TextureViewDescriptor { - label: args.label.map(|label| &label), - format: args.format.map(|format| serialize_texture_format(format)?), - dimension: args - .dimension - .map(|dimension| serialize_dimension(dimension)), - aspect: match args.aspect { - Some(&"all") => wgpu::TextureAspect::All, - Some(&"stencil-only") => wgpu::TextureAspect::StencilOnly, - Some(&"depth-only") => wgpu::TextureAspect::DepthOnly, - Some(_) => unreachable!(), - None => wgpu::TextureAspect::All, + let texture_view = instance.texture_create_view( + *texture, + &wgc::resource::TextureViewDescriptor { + label: args.label.map(|label| Cow::Borrowed(&label)), + format: args.format.map(|format| serialize_texture_format(format)?), + dimension: args + .dimension + .map(|dimension| serialize_dimension(dimension)), + aspect: match args.aspect { + Some(&"all") => wgt::TextureAspect::All, + Some(&"stencil-only") => wgt::TextureAspect::StencilOnly, + Some(&"depth-only") => wgt::TextureAspect::DepthOnly, + Some(_) => unreachable!(), + None => wgt::TextureAspect::All, + }, + base_mip_level: args.base_mip_level.unwrap_or(0), + level_count: args.mip_level_count, // TODO + base_array_layer: args.base_array_layer.unwrap_or(0), + array_layer_count: args.array_layer_count, // TODO }, - base_mip_level: args.base_mip_level.unwrap_or(0), - level_count: args.mip_level_count, // TODO - base_array_layer: args.base_array_layer.unwrap_or(0), - array_layer_count: args.array_layer_count, // TODO - }); + (), // TODO + )?; let rid = state .resource_table diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 4b964cd433f966..52c6afeca307ef 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -13,6 +13,8 @@ }, }; + let instanceRid; // TODO define + class GPUAdapter { #rid; #name; @@ -33,7 +35,8 @@ async requestDevice(descriptor = {}) { const data = await core.jsonOpAsync("op_webgpu_request_device", { - rid: this.#rid, + instanceRid, + adapterRid: this.#rid, ...descriptor, }); @@ -71,7 +74,8 @@ createBuffer(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -80,7 +84,8 @@ createTexture(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_texture", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -89,7 +94,8 @@ createSampler(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -100,7 +106,8 @@ createBindGroupLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -111,7 +118,8 @@ createPipelineLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, label: descriptor.label, bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => { return GPUBindGroupLayoutMap.get(bindGroupLayout); @@ -125,7 +133,8 @@ createBindGroup(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, label: descriptor.label, layout: GPUBindGroupLayoutMap.get(descriptor.layout), entries: descriptor.entries.map((entry) => { @@ -152,7 +161,8 @@ createShaderModule(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_shader_module", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -163,7 +173,8 @@ createComputePipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, label: descriptor.label, layout: descriptor.layout && GPUPipelineLayoutMap.get(descriptor.layout), @@ -178,7 +189,8 @@ createRenderPipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -191,7 +203,8 @@ createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }); @@ -202,7 +215,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { - rid: this.#deviceRid, + instanceRid, + deviceRid: this.#deviceRid, ...descriptor, }, ); @@ -225,7 +239,8 @@ async mapAsync(mode, offset = 0, size = undefined) { await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { - rid: this.#rid, + instanceRid, + bufferRid: this.#rid, offset, size, }); @@ -233,7 +248,8 @@ getMappedRange(offset = 0, size = undefined) { core.jsonOpSync("op_webgpu_buffer_get_mapped_range", { - rid: this.#rid, + instanceRid, + bufferRid: this.#rid, offset, size, }); // TODO @@ -241,7 +257,8 @@ unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { - rid: this.#rid, + instanceRid, + bufferRid: this.#rid, }); } @@ -257,7 +274,8 @@ createView(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { - rid: this.#rid, + instanceRid, + textureRid: this.#rid, ...descriptor, }); @@ -327,7 +345,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", { - rid: this.#rid, + instanceRid, + computePipelineRid: this.#rid, index, }, ); @@ -350,7 +369,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", { - rid: this.#rid, + instanceRid, + renderPipelineRid: this.#rid, index, }, ); @@ -373,7 +393,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_render_pass", { - rid: this.#rid, + instanceRid, + commandEncoderRid: this.#rid, ...descriptor, }, ); @@ -385,7 +406,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_compute_pass", { - rid: this.#rid, + instanceRid, + commandEncoderRid: this.#rid, ...descriptor, }, ); @@ -409,7 +431,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { - rid: this.#rid, + instanceRid, + commandEncoderRid: this.#rid, source, destination, copySize, @@ -433,7 +456,8 @@ finish(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { - rid: this.#rid, + instanceRid, + commandEncoderRid: this.#rid, ...descriptor, }); @@ -552,7 +576,8 @@ const { rid } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { - rid: this.#rid, + instanceRid, + renderBundleEncoderRid: this.#rid, ...descriptor, }, ); From ea292e3a98fb94bca19f51f297512ebc3ab37ce3 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 11 Oct 2020 18:27:43 +0200 Subject: [PATCH 006/144] Better TODOs --- cli/Cargo.toml | 2 +- cli/ops/webgpu/binding.rs | 60 ++++++----- cli/ops/webgpu/buffer.rs | 27 +++-- cli/ops/webgpu/bundle.rs | 4 +- cli/ops/webgpu/command_encoding.rs | 24 +++-- cli/ops/webgpu/mod.rs | 121 +++++++++++++++++----- cli/ops/webgpu/pipeline.rs | 157 +++++++++++++++-------------- cli/ops/webgpu/sampler.rs | 12 ++- cli/ops/webgpu/shader.rs | 5 +- cli/ops/webgpu/texture.rs | 17 ++-- cli/rt/14_webgpu.js | 98 +++++++++++------- 11 files changed, 323 insertions(+), 204 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7f4eaa3e0a0802..74be21943d8abc 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -76,7 +76,7 @@ warp = { version = "0.2.5", features = ["tls"] } semver-parser = "0.9.0" uuid = { version = "0.8.1", features = ["v4"] } wgc = { package = "wgpu-core", version = "0.6.4" } -wgt = { package = "wgpu-types", versionn = "0.6.1" } +wgt = { package = "wgpu-types", version = "0.6.1" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] } diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index e69acb76180698..1e4c36bbeb6032 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -21,7 +21,7 @@ fn serialize_texture_component_type( &"float" => wgt::TextureComponentType::Float, &"sint" => wgt::TextureComponentType::Sint, &"uint" => wgt::TextureComponentType::Uint, - &"depth-comparison" => return Err(not_supported()), // TODO + &"depth-comparison" => return Err(not_supported()), _ => unreachable!(), }) } @@ -77,7 +77,7 @@ pub fn op_webgpu_create_bind_group_layout( wgt::BindGroupLayoutEntry { binding: entry.binding, visibility: wgt::ShaderStage::from_bits(entry.visibility) - .unwrap(), // TODO + .unwrap(), // TODO: dont unwrap ty: match entry.kind { &"uniform-buffer" => wgt::BindingType::UniformBuffer { dynamic: entry.has_dynamic_offset.unwrap_or(false), @@ -88,62 +88,60 @@ pub fn op_webgpu_create_bind_group_layout( min_binding_size: entry.min_buffer_binding_size, readonly: false, }, - &"readonly-storage-buffer" => { - wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: true, - } - } + &"readonly-storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: true, + }, &"sampler" => wgt::BindingType::Sampler { comparison: false }, &"comparison-sampler" => { wgt::BindingType::Sampler { comparison: true } } &"sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO: dont unwrap component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, // TODO + entry.texture_component_type.unwrap(), // TODO: dont unwrap + )?, multisampled: false, }, &"multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO + dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO: dont unwrap component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, // TODO + entry.texture_component_type.unwrap(), // TODO: dont unwrap + )?, multisampled: true, }, &"readonly-storage-texture" => { wgt::BindingType::StorageTexture { dimension: serialize_dimension( - entry.view_dimension.unwrap(), - ), // TODO + entry.view_dimension.unwrap(), // TODO: dont unwrap + ), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, // TODO + entry.storage_texture_format.unwrap(), // TODO: dont unwrap + )?, readonly: true, } } &"writeonly-storage-texture" => { wgt::BindingType::StorageTexture { dimension: serialize_dimension( - entry.view_dimension.unwrap(), - ), // TODO + entry.view_dimension.unwrap(), // TODO: dont unwrap + ), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, // TODO + entry.storage_texture_format.unwrap(), // TODO: dont unwrap + )?, readonly: false, } } _ => unreachable!(), }, - count: None, // TODO + count: None, // TODO: look into what this is } }) .collect::>(), ), }, - (), // TODO + (), // TODO: id_in )?; let rid = state @@ -196,9 +194,9 @@ pub fn op_webgpu_create_pipeline_layout( }) .collect::>(), ), - push_constant_ranges: Default::default(), // TODO + push_constant_ranges: Default::default(), // TODO: look into what this is }, - (), // TODO + (), // TODO: id_in )?; let rid = state @@ -215,7 +213,7 @@ pub fn op_webgpu_create_pipeline_layout( struct GPUBindGroupEntry { binding: u32, resource_kind: String, - resource: u32, // TODO + resource: u32, // TODO: buffer } #[derive(Deserialize)] @@ -274,8 +272,8 @@ pub fn op_webgpu_create_bind_group( ) } &"GPUBufferBinding" => { - wgc::binding_model::BindingResource::Buffer() - } // TODO + wgc::binding_model::BindingResource::Buffer() // TODO: buffer + } _ => unreachable!(), }, } @@ -283,7 +281,7 @@ pub fn op_webgpu_create_bind_group( .collect::>(), ), }, - (), // TODO + (), // TODO: id_in )?; let rid = state diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 0f0f9abb05e1c9..0008415b448edd 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -9,6 +9,7 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; @@ -19,7 +20,7 @@ struct CreateBufferArgs { device_rid: u32, label: Option, size: u64, - usage: (), // TODO + usage: u32, mapped_at_creation: Option, } @@ -44,10 +45,10 @@ pub fn op_webgpu_create_buffer( &wgc::resource::BufferDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), size: args.size, - usage: (), + usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), // TODO: don't unwrap mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }, - (), // TODO + (), // TODO: id_in )?; let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); @@ -63,6 +64,8 @@ struct BufferGetMapAsyncArgs { instance_rid: u32, buffer_rid: u32, mode: u32, + offset: Option, + size: Option, } pub async fn op_webgpu_buffer_get_map_async( @@ -84,7 +87,16 @@ pub async fn op_webgpu_buffer_get_map_async( instance.buffer_map_async( *buffer, - // TODO + (), // TODO + wgc::resource::BufferMapOperation { + host: match args.mode { + 1 => wgc::device::HostMap::Read, + 2 => wgc::device::HostMap::Read, + _ => unreachable!(), + }, + callback: (), // TODO + user_data: (), // TODO + }, )?; Ok(json!({})) @@ -96,7 +108,7 @@ struct BufferGetMappedRangeArgs { instance_rid: u32, buffer_rid: u32, offset: u64, - size: Option, + size: Option, } pub fn op_webgpu_buffer_get_mapped_range( @@ -116,10 +128,11 @@ pub fn op_webgpu_buffer_get_mapped_range( .ok_or_else(bad_resource_id)?; let slice = instance.buffer_get_mapped_range( + // TODO: use *buffer, args.offset, - args.size, // TODO - )?; // TODO + args.size, + )?; Ok(json!({})) } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 987bd9ebf694c6..cebcbe70ecd1d9 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -51,7 +51,7 @@ pub fn op_webgpu_create_render_bundle_encoder( .iter() .map(|format| serialize_texture_format(format.clone())?) .collect::>(), - ), // TODO + ), depth_stencil_format: args .depth_stencil_format .map(|format| serialize_texture_format(format)?), @@ -97,7 +97,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( &wgc::command::RenderBundleDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), }, - (), // TODO + (), // TODO: id_in )?; let rid = state diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index c83dce2550d101..c27baf435c9d0d 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -19,7 +19,7 @@ struct CreateCommandEncoderArgs { instance_rid: u32, device_rid: u32, label: Option, - measure_execution_time: Option, // TODO + measure_execution_time: Option, } pub fn op_webgpu_create_command_encoder( @@ -41,9 +41,10 @@ pub fn op_webgpu_create_command_encoder( let command_encoder = instance.device_create_command_encoder( *device, &wgt::CommandEncoderDescriptor { + // TODO: should accept measure_execution_time label: args.label.map(|label| Cow::Borrowed(&label)), }, - (), // TODO + (), // TODO: id_in )?; let rid = state @@ -60,7 +61,7 @@ pub fn op_webgpu_create_command_encoder( struct GPURenderPassColorAttachmentDescriptor { attachment: u32, resolve_target: Option, - load_value: (), // TODO + load_value: (), // TODO: mixed types store_op: Option, } @@ -68,10 +69,10 @@ struct GPURenderPassColorAttachmentDescriptor { #[serde(rename_all = "camelCase")] struct GPURenderPassDepthStencilAttachmentDescriptor { attachment: u32, - depth_load_value: (), // TODO + depth_load_value: (), // TODO: mixed types depth_store_op: String, depth_read_only: Option, - stencil_load_value: (), // TODO + stencil_load_value: (), // TODO: mixed types stencil_store_op: String, stencil_read_only: Option, } @@ -81,11 +82,11 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { struct CommandEncoderBeginRenderPassArgs { instance_rid: u32, command_encoder_rid: u32, - label: Option, // TODO + label: Option, color_attachments: [GPURenderPassColorAttachmentDescriptor], depth_stencil_attachment: Option, - occlusion_query_set: (), // TODO + occlusion_query_set: u32, // TODO: wait to be added to wpgu, and add to JS } pub fn op_webgpu_command_encoder_begin_render_pass( @@ -107,6 +108,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( let render_pass = wgc::command::RenderPass::new( *command_encoder, wgc::command::RenderPassDescriptor { + // TODO: should accept label color_attachments: Cow::Owned( args .color_attachments @@ -181,7 +183,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .ok_or_else(bad_resource_id)?; let compute_pass = wgc::command::ComputePass::new(*command_encoder); - + // TODO: should accept label instance.command_encoder_run_compute_pass(*command_encoder, &compute_pass); let rid = state @@ -198,7 +200,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( struct GPUTextureCopyView { texture: u32, mip_level: Option, - origin: (), // TODO + origin: (), // TODO: mixed types } #[derive(Deserialize)] @@ -208,7 +210,7 @@ struct CommandEncoderCopyTextureToTextureArgs { command_encoder_rid: u32, source: GPUTextureCopyView, destination: GPUTextureCopyView, - copy_size: (), // TODO + copy_size: (), // TODO: mixed types } pub fn op_webgpu_command_encoder_copy_texture_to_texture( @@ -262,7 +264,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( struct CommandEncoderFinishArgs { instance_rid: u32, command_encoder_rid: u32, - label: Option, // TODO + label: Option, } pub fn op_webgpu_command_encoder_finish( diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 896f3b0595ec93..92aa15c1cecc70 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -22,6 +22,11 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { + super::reg_json_sync( + rt, + "op_webgpu_create_instance", + op_webgpu_create_instance, + ); super::reg_json_async( rt, "op_webgpu_request_adapter", @@ -147,19 +152,23 @@ fn serialize_features(features: &wgt::Features) -> Vec<&str> { if features.contains(wgt::Features::DEPTH_CLAMPING) { extensions.push("depth-clamping"); } - if features.contains(wgt::Features) { // TODO + if features.contains(wgt::Features) { + // TODO extensions.push("depth24unorm-stencil8"); } - if features.contains(wgt::Features) { // TODO + if features.contains(wgt::Features) { + // TODO extensions.push("depth32float-stencil8"); } - if features.contains(wgt::Features) { // TODO + if features.contains(wgt::Features) { + // TODO extensions.push("pipeline-statistics-query"); } if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) { extensions.push("texture-compression-bc"); } - if features.contains(wgt::Features) { // TODO + if features.contains(wgt::Features) { + // TODO extensions.push("timestamp-query"); } @@ -168,9 +177,30 @@ fn serialize_features(features: &wgt::Features) -> Vec<&str> { pub type WgcInstance = wgc::hub::Global; +pub fn op_webgpu_create_instance( + state: &mut OpState, + _args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let instance = wgc::hub::Global::new( + "webgpu", + wgc::hub::IdentityManagerFactory, + wgt::BackendBit::PRIMARY, + ); + + let rid = state + .resource_table + .add("webGPUInstance", Box::new(adapter)); + + Ok(json!({ + "rid": rid, + })) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestAdapterArgs { + instance_rid: u32, power_preference: Option, } @@ -181,11 +211,12 @@ pub async fn op_webgpu_request_adapter( ) -> Result { let args: RequestAdapterArgs = serde_json::from_value(args)?; - let instance = wgc::hub::Global::new( - "webgpu", - wgc::hub::IdentityManagerFactory, - wgt::BackendBit::PRIMARY, - ); // TODO: own op + let mut state = state.borrow_mut(); + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let adapter = instance.request_adapter( &wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -200,9 +231,8 @@ pub async fn op_webgpu_request_adapter( )?; let name = instance.adapter_get_info(adapter)?.name; - let extensions = serialize_features(&instance.adapter_features(adapter)?); + let features = serialize_features(&instance.adapter_features(adapter)?); - let mut state = state.borrow_mut(); let rid = state .resource_table .add("webGPUInstance", Box::new(instance)); @@ -211,17 +241,32 @@ pub async fn op_webgpu_request_adapter( Ok(json!({ "rid": rid, "name": name, - "extensions": extensions, + "features": features, })) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPULimits { + // TODO: each should be Option + max_bind_groups: u32, + max_dynamic_uniform_buffers_per_pipeline_layout: u32, + max_dynamic_storage_buffers_per_pipeline_layout: u32, + max_sampled_textures_per_shader_stage: u32, + max_samplers_per_shader_stage: u32, + max_storage_buffers_per_shader_stage: u32, + max_storage_textures_per_shader_stage: u32, + max_uniform_buffers_per_shader_stage: u32, + max_uniform_buffer_binding_size: u32, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestDeviceArgs { instance_rid: u32, adapter_rid: u32, - extensions: Option<[String]>, - limits: Option, // TODO + features: Option<[String]>, + limits: Option, } pub async fn op_webgpu_request_device( @@ -246,22 +291,52 @@ pub async fn op_webgpu_request_device( &wgt::DeviceDescriptor { // TODO: should accept label features: Default::default(), // TODO - limits: Default::default(), // TODO - shader_validation: false, // TODO + limits: args.limits.map_or(Default::default(), |limits| { + wgt::Limits { + max_bind_groups: limits.max_bind_groups, + max_dynamic_uniform_buffers_per_pipeline_layout: limits + .max_dynamic_uniform_buffers_per_pipeline_layout, + max_dynamic_storage_buffers_per_pipeline_layout: limits + .max_dynamic_storage_buffers_per_pipeline_layout, + max_sampled_textures_per_shader_stage: limits + .max_sampled_textures_per_shader_stage, + max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage, + max_storage_buffers_per_shader_stage: limits + .max_storage_buffers_per_shader_stage, + max_storage_textures_per_shader_stage: limits + .max_storage_textures_per_shader_stage, + max_uniform_buffers_per_shader_stage: limits + .max_uniform_buffers_per_shader_stage, + max_uniform_buffer_binding_size: limits + .max_uniform_buffer_binding_size, + max_push_constant_size: 0, // TODO + } + }), + shader_validation: false, // TODO }, None, (), // TODO )?; - let extensions = serialize_features(&instance.device_features(device)?); - let limits = instance.device_limits(device)?; // TODO + let features = serialize_features(&instance.device_features(device)?); + let limits = instance.device_limits(device)?; + let json_limits = json!({ + "max_bind_groups": limits.max_bind_groups, + "max_dynamic_uniform_buffers_per_pipeline_layout": limits.max_dynamic_uniform_buffers_per_pipeline_layout, + "max_dynamic_storage_buffers_per_pipeline_layout": limits.max_dynamic_storage_buffers_per_pipeline_layout, + "max_sampled_textures_per_shader_stage": limits.max_sampled_textures_per_shader_stage, + "max_samplers_per_shader_stage": limits.max_samplers_per_shader_stage, + "max_storage_buffers_per_shader_stage": limits.max_storage_buffers_per_shader_stage, + "max_storage_textures_per_shader_stage": limits.max_storage_textures_per_shader_stage, + "max_uniform_buffers_per_shader_stage": limits.max_uniform_buffers_per_shader_stage, + "max_uniform_buffer_binding_size": limits.max_uniform_buffer_binding_size, + }); - let device_rid = state.resource_table.add("webGPUDevice", Box::new(device)); + let rid = state.resource_table.add("webGPUDevice", Box::new(device)); Ok(json!({ - "deviceRid": device_rid, - "queueRid": queue_rid, - "extensions": extensions, - "limits", // TODO + "rid": rid, + "features": features, + "limits": json_limits, })) } diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index db571d1859f2f4..77fe3479cddb1e 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -135,8 +135,8 @@ pub fn op_webgpu_create_compute_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + // TODO: look into what that u8 is let (compute_pipeline, smth) = instance.device_create_compute_pipeline( - // TODO *device, &wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), @@ -151,8 +151,8 @@ pub fn op_webgpu_create_compute_pipeline( args.compute_stage, )?, }, - (), // TODO - (), // TODO + (), // TODO: id_in + (), // TODO: look into what this is )?; let rid = state @@ -370,11 +370,16 @@ pub fn op_webgpu_create_render_pipeline( format: serialize_texture_format(color_state.format.clone())?, alpha_blend: color_state .alpha_blend - .map_or("", serialize_blend_descriptor), // TODO + .map_or(Default::default(), serialize_blend_descriptor), color_blend: color_state .color_blend - .map_or("", serialize_blend_descriptor), // TODO - write_mask: color_state.write_mask, // TODO + .map_or(Default::default(), serialize_blend_descriptor), + write_mask: color_state.write_mask.map_or( + Default::default(), + |mask| { + wgt::ColorWrite::from_bits(mask).unwrap() // TODO: don't unwrap + }, + ), } }) .collect::>(), @@ -400,86 +405,84 @@ pub fn op_webgpu_create_render_pipeline( }, } }), - vertex_state: wgc::pipeline::VertexStateDescriptor { - index_format: args.vertex_state.unwrap().index_format.map_or( - // TODO - "", // TODO - |format| match format { + // TODO: figure out default value + vertex_state: args.vertex_state.map_or("", |state| { + wgc::pipeline::VertexStateDescriptor { + // TODO: figure out default value + index_format: state.index_format.map_or("", |format| match format { &"uint16" => wgt::IndexFormat::Uint16, &"uint32" => wgt::IndexFormat::Uint32, _ => unreachable!(), - }, - ), - vertex_buffers: Cow::Owned( - args - .vertex_state - .unwrap() - .vertex_buffers - .unwrap() // TODO - .iter() - .map(|buffer| wgc::pipeline::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode { - Some(&"vertex") => wgt::InputStepMode::Vertex, - Some(&"instance") => wgt::InputStepMode::Instance, - Some(_) => unreachable!(), - None => wgt::InputStepMode::Vertex, - }, - attributes: Cow::Owned( - buffer - .attributes - .iter() - .map(|attribute| wgt::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format { - &"uchar2" => wgt::VertexFormat::Uchar2, - &"uchar4" => wgt::VertexFormat::Uchar4, - &"char2" => wgt::VertexFormat::Char2, - &"char4" => wgt::VertexFormat::Char4, - &"uchar2norm" => wgt::VertexFormat::Uchar2Norm, - &"uchar4norm" => wgt::VertexFormat::Uchar4, - &"char2norm" => wgt::VertexFormat::Char2Norm, - &"char4norm" => wgt::VertexFormat::Char4Norm, - &"ushort2" => wgt::VertexFormat::Ushort2, - &"ushort4" => wgt::VertexFormat::Ushort4, - &"short2" => wgt::VertexFormat::Short2, - &"short4" => wgt::VertexFormat::Short4, - &"ushort2norm" => wgt::VertexFormat::Ushort2Norm, - &"ushort4norm" => wgt::VertexFormat::Ushort4Norm, - &"short2norm" => wgt::VertexFormat::Short2Norm, - &"short4norm" => wgt::VertexFormat::Short4Norm, - &"half2" => wgt::VertexFormat::Half2, - &"half4" => wgt::VertexFormat::Half4, - &"float" => wgt::VertexFormat::Float, - &"float2" => wgt::VertexFormat::Float2, - &"float3" => wgt::VertexFormat::Float3, - &"float4" => wgt::VertexFormat::Float4, - &"uint" => wgt::VertexFormat::Uint, - &"uint2" => wgt::VertexFormat::Uint2, - &"uint3" => wgt::VertexFormat::Uint3, - &"uint4" => wgt::VertexFormat::Uint4, - &"int" => wgt::VertexFormat::Int, - &"int2" => wgt::VertexFormat::Int2, - &"int3" => wgt::VertexFormat::Int3, - &"int4" => wgt::VertexFormat::Int4, - _ => unreachable!(), - }, - shader_location: attribute.shader_location, - }) - .collect::>(), - ), - }) - .collect::>(), - ), - }, + }), + vertex_buffers: Cow::Owned( + state + .vertex_buffers + .unwrap() // TODO: don't unwrap + .iter() + .map(|buffer| wgc::pipeline::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode { + Some(&"vertex") => wgt::InputStepMode::Vertex, + Some(&"instance") => wgt::InputStepMode::Instance, + Some(_) => unreachable!(), + None => wgt::InputStepMode::Vertex, + }, + attributes: Cow::Owned( + buffer + .attributes + .iter() + .map(|attribute| wgt::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format { + &"uchar2" => wgt::VertexFormat::Uchar2, + &"uchar4" => wgt::VertexFormat::Uchar4, + &"char2" => wgt::VertexFormat::Char2, + &"char4" => wgt::VertexFormat::Char4, + &"uchar2norm" => wgt::VertexFormat::Uchar2Norm, + &"uchar4norm" => wgt::VertexFormat::Uchar4, + &"char2norm" => wgt::VertexFormat::Char2Norm, + &"char4norm" => wgt::VertexFormat::Char4Norm, + &"ushort2" => wgt::VertexFormat::Ushort2, + &"ushort4" => wgt::VertexFormat::Ushort4, + &"short2" => wgt::VertexFormat::Short2, + &"short4" => wgt::VertexFormat::Short4, + &"ushort2norm" => wgt::VertexFormat::Ushort2Norm, + &"ushort4norm" => wgt::VertexFormat::Ushort4Norm, + &"short2norm" => wgt::VertexFormat::Short2Norm, + &"short4norm" => wgt::VertexFormat::Short4Norm, + &"half2" => wgt::VertexFormat::Half2, + &"half4" => wgt::VertexFormat::Half4, + &"float" => wgt::VertexFormat::Float, + &"float2" => wgt::VertexFormat::Float2, + &"float3" => wgt::VertexFormat::Float3, + &"float4" => wgt::VertexFormat::Float4, + &"uint" => wgt::VertexFormat::Uint, + &"uint2" => wgt::VertexFormat::Uint2, + &"uint3" => wgt::VertexFormat::Uint3, + &"uint4" => wgt::VertexFormat::Uint4, + &"int" => wgt::VertexFormat::Int, + &"int2" => wgt::VertexFormat::Int2, + &"int3" => wgt::VertexFormat::Int3, + &"int4" => wgt::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::>(), + ), + }) + .collect::>(), + ), + } + }), sample_count: args.sample_count.unwrap_or(1), sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), alpha_to_coverage_enabled: args .alpha_to_coverage_enabled .unwrap_or(false), }, - (), // TODO - (), // TODO + (), // TODO: id_in + (), // TODO: look into what this is )?; let rid = state diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 8c7035ffef5dbf..b1fe9042de780c 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -61,7 +61,7 @@ struct CreateSamplerArgs { lod_min_clamp: Option, lod_max_clamp: Option, compare: Option, - max_anisotropy: Option, + max_anisotropy: Option, } pub fn op_webgpu_create_sampler( @@ -93,11 +93,15 @@ pub fn op_webgpu_create_sampler( min_filter: serialize_filter_mode(args.min_filter), mipmap_filter: serialize_filter_mode(args.mipmap_filter), lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO + lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO: check if there is a better solution compare: args.compare.map(serialize_compare_function), - anisotropy_clamp: args.max_anisotropy.unwrap_or(1), // TODO + anisotropy_clamp: Some( + args + .max_anisotropy + .unwrap_or(unsafe { std::num::NonZeroU8::new_unchecked(1) }), + ), // TODO: check what None would be }, - (), // TODO + (), // TODO: id_in )?; let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 2004bb9bcaf782..da482afa0f1a7a 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -19,7 +19,7 @@ struct CreateShaderModuleArgs { device_rid: u32, label: Option, code: String, - source_map: (), // TODO + source_map: (), // TODO: https://gpuweb.github.io/gpuweb/#shader-module-creation } pub fn op_webgpu_create_shader_module( @@ -39,9 +39,10 @@ pub fn op_webgpu_create_shader_module( .ok_or_else(bad_resource_id)?; let shader_module = instance.device_create_shader_module( + // TODO: should accept label *device, wgc::pipeline::ShaderModuleSource, // TODO - (), // TODO + (), // TODO: id_in )?; let rid = state diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 2798759ba76ac0..acf5487fea9c47 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -115,11 +115,12 @@ struct CreateTextureArgs { instance_rid: u32, device_rid: u32, label: Option, + size: (), // TODO: mixed types mip_level_count: Option, sample_count: Option, dimension: Option, format: String, - usage: (), // TODO + usage: u32, } pub fn op_webgpu_create_texture( @@ -153,9 +154,9 @@ pub fn op_webgpu_create_texture( None => wgt::TextureDimension::D2, }, format: serialize_texture_format(args.format)?, - usage: (), // TODO + usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), // TODO: don't unwrap }, - (), // TODO + (), // TODO: id_in )?; let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); @@ -175,9 +176,9 @@ struct CreateTextureViewArgs { dimension: Option, aspect: Option, base_mip_level: Option, - mip_level_count: Option, + mip_level_count: Option, base_array_layer: Option, - array_layer_count: Option, + array_layer_count: Option, } pub fn op_webgpu_create_texture_view( @@ -212,11 +213,11 @@ pub fn op_webgpu_create_texture_view( None => wgt::TextureAspect::All, }, base_mip_level: args.base_mip_level.unwrap_or(0), - level_count: args.mip_level_count, // TODO + level_count: args.mip_level_count, base_array_layer: args.base_array_layer.unwrap_or(0), - array_layer_count: args.array_layer_count, // TODO + array_layer_count: args.array_layer_count, }, - (), // TODO + (), // TODO: id_in )?; let rid = state diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 52c6afeca307ef..6bd3fcf0438f91 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -3,56 +3,61 @@ ((window) => { const core = window.Deno.core; + let instanceRid; // TODO: use op_webgpu_create_instance + const GPU = { async requestAdapter(options = {}) { - const { rid, name, extensions } = await core.jsonOpAsync( + const { rid, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", - options, + { + instanceRid, + ...options, + }, ); - return new GPUAdapter(rid, name, extensions); + return new GPUAdapter(rid, data); }, }; - let instanceRid; // TODO define - class GPUAdapter { #rid; #name; get name() { return this.#name; } - #extensions; - get extensions() { - return this.#extensions; + #features; + get features() { + return this.#features; } - // TODO: limits - constructor(rid, name, extensions) { + constructor(rid, data) { this.#rid = rid; - this.#name = name; - this.#extensions = Object.freeze(extensions); + this.#name = data.name; + this.#extensions = Object.freeze(data.features); } async requestDevice(descriptor = {}) { - const data = await core.jsonOpAsync("op_webgpu_request_device", { - instanceRid, - adapterRid: this.#rid, - ...descriptor, - }); + const { rid, ...data } = await core.jsonOpAsync( + "op_webgpu_request_device", + { + instanceRid, + adapterRid: this.#rid, + ...descriptor, + }, + ); return new GPUDevice(this, data); } } class GPUDevice extends EventTarget { - #deviceRid; + #rid; #adapter; get adapter() { return this.#adapter; } - #extensions; - get extensions() { - return this.#extensions; + #features; + get features() { + return this.#features; } #limits; get limits() { @@ -61,21 +66,22 @@ #defaultQueue; get defaultQueue() { return this.#defaultQueue; - } // TODO - - // TODO: should have label + } - constructor(adapter, data) { + constructor(adapter, rid, data) { super(); this.#adapter = adapter; - this.#deviceRid = data.deviceRid; // TODO: properties + this.#rid = rid; + this.#features = Object.freeze(data.features); + this.#limits = data.limits; + this.#defaultQueue = new GPUQueue(); // TODO } createBuffer(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -85,7 +91,7 @@ createTexture(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_texture", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -95,7 +101,7 @@ createSampler(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -107,7 +113,7 @@ createBindGroupLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -119,7 +125,7 @@ createPipelineLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, label: descriptor.label, bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => { return GPUBindGroupLayoutMap.get(bindGroupLayout); @@ -134,7 +140,7 @@ createBindGroup(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, label: descriptor.label, layout: GPUBindGroupLayoutMap.get(descriptor.layout), entries: descriptor.entries.map((entry) => { @@ -149,7 +155,7 @@ resource: GPUTextureViewMap.get(entry), }; } else { - // TODO + // TODO: buffer } }), }); @@ -162,7 +168,7 @@ createShaderModule(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_shader_module", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -174,7 +180,7 @@ createComputePipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, label: descriptor.label, layout: descriptor.layout && GPUPipelineLayoutMap.get(descriptor.layout), @@ -190,7 +196,7 @@ createRenderPipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -204,7 +210,7 @@ createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }); @@ -216,7 +222,7 @@ "op_webgpu_create_render_bundle_encoder", { instanceRid, - deviceRid: this.#deviceRid, + deviceRid: this.#rid, ...descriptor, }, ); @@ -229,6 +235,21 @@ } } + class GPUQueue { + constructor(label) { + this.label = label; + } + + submit(commandBuffers) {} // TODO + createFence(descriptor = {}) {} // TODO + + writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) {} + + writeTexture(destination, data, dataLayout, size) {} // TODO + + copyImageBitmapToTexture(source, destination, copySize) {} // TODO + } + class GPUBuffer { #rid; @@ -241,6 +262,7 @@ await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { instanceRid, bufferRid: this.#rid, + mode, offset, size, }); From cc61da9b9ff36a8a2ae4c5a643ce2264906a041c Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 11 Oct 2020 19:29:25 +0200 Subject: [PATCH 007/144] command encoder debug ops --- cli/ops/webgpu/command_encoding.rs | 86 ++++++++++++++++++++++++++++++ cli/ops/webgpu/mod.rs | 20 +++++++ cli/rt/14_webgpu.js | 55 ++++++++++++------- 3 files changed, 141 insertions(+), 20 deletions(-) diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index c27baf435c9d0d..dae22f3b1e90b7 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -259,6 +259,92 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderPushDebugGroupArgs { + instance_rid: u32, + command_encoder_rid: u32, + group_label: String, +} + +pub fn op_webgpu_command_encoder_push_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderPushDebugGroupArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_push_debug_group(*command_encoder, args.group_label)?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderPopDebugGroupArgs { + instance_rid: u32, + command_encoder_rid: u32, +} + +pub fn op_webgpu_command_encoder_pop_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderPopDebugGroupArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_pop_debug_group(*command_encoder)?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderInsertDebugMarkerArgs { + instance_rid: u32, + command_encoder_rid: u32, + marker_label: String, +} + +pub fn op_webgpu_command_encoder_insert_debug_marker( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_insert_debug_marker(*command_encoder, args.marker_label)?; + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderFinishArgs { diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 92aa15c1cecc70..f41349b7e8c781 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -133,6 +133,26 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_command_encoder_copy_texture_to_texture", command_encoding::op_webgpu_command_encoder_copy_texture_to_texture, ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_push_debug_group", + command_encoding::op_webgpu_command_encoder_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_pop_debug_group", + command_encoding::op_webgpu_command_encoder_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_insert_debug_marker", + command_encoding::op_webgpu_command_encoder_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_finish", + command_encoding::op_webgpu_command_encoder_finish, + ); super::reg_json_sync( rt, diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 6bd3fcf0438f91..f6d2f115a3b8c9 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -231,7 +231,7 @@ } createQuerySet(descriptor) { - throw new Error("Not yet implemented"); + throw new Error("Not yet implemented"); // wgpu#721 } } @@ -352,7 +352,7 @@ this.label = label; } - async compilationInfo() {} // TODO + async compilationInfo() {} // TODO: missing? } class GPUComputePipeline { @@ -373,7 +373,7 @@ }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO + const bindGroupLayout = new GPUBindGroupLayout(); // TODO: label? GPUBindGroupLayoutMap.set(bindGroupLayout, rid); return bindGroupLayout; } @@ -397,7 +397,7 @@ }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO + const bindGroupLayout = new GPUBindGroupLayout(); // TODO: label? GPUBindGroupLayoutMap.set(bindGroupLayout, rid); return bindGroupLayout; } @@ -437,17 +437,11 @@ return new GPUComputePassEncoder(rid, descriptor.label); } - copyBufferToBuffer( - source, - sourceOffset, - destination, - destinationOffset, - size, - ) {} // TODO + copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {} // TODO: buffer - copyBufferToTexture(source, destination, copySize) {} // TODO + copyBufferToTexture(source, destination, copySize) {} // TODO: buffer - copyTextureToBuffer(source, destination, copySize) {} // TODO + copyTextureToBuffer(source, destination, copySize) {} // TODO: buffer copyTextureToTexture(source, destination, copySize) { const { rid } = core.jsonOpSync( @@ -462,11 +456,30 @@ ); } - pushDebugGroup(groupLabel) {} // TODO - popDebugGroup() {} // TODO - insertDebugMarker(markerLabel) {} // TODO + pushDebugGroup(groupLabel) { + core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { + instanceRid, + commandEncoderRid: this.#rid, + groupLabel, + }); + } + popDebugGroup() { + core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { + instanceRid, + commandEncoderRid: this.#rid, + }); + } + insertDebugMarker(markerLabel) { + core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { + instanceRid, + commandEncoderRid: this.#rid, + markerLabel, + }); + } - writeTimestamp(querySet, queryIndex) {} // TODO + writeTimestamp(querySet, queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } resolveQuerySet( querySet, @@ -474,7 +487,9 @@ queryCount, destination, destinationOffset, - ) {} // TODO + ) { + throw new Error("Not yet implemented"); // wgpu#721 + } finish(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { @@ -483,7 +498,7 @@ ...descriptor, }); - return new GPUCommandBuffer(descriptor.label); + return new GPUCommandBuffer(descriptor.label); // TODO } } @@ -584,7 +599,7 @@ this.label = label; } - get executionTime() {} // TODO + get executionTime() {} // TODO: missing? } class GPURenderBundleEncoder { From 512ae294fc4fa4bb59798d9cb3abb40b68d55d76 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 12 Oct 2020 16:33:09 +0200 Subject: [PATCH 008/144] add render pass --- cli/ops/webgpu/command_encoding.rs | 4 +- cli/ops/webgpu/mod.rs | 59 ++++- cli/ops/webgpu/render_pass.rs | 351 +++++++++++++++++++++++++++++ cli/rt/14_webgpu.js | 168 ++++++++++---- 4 files changed, 531 insertions(+), 51 deletions(-) create mode 100644 cli/ops/webgpu/render_pass.rs diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index dae22f3b1e90b7..41061459f78ea4 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -283,7 +283,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_push_debug_group(*command_encoder, args.group_label)?; + instance.command_encoder_push_debug_group(*command_encoder, &args.group_label)?; Ok(json!({})) } @@ -340,7 +340,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_insert_debug_marker(*command_encoder, args.marker_label)?; + instance.command_encoder_insert_debug_marker(*command_encoder, &args.marker_label)?; Ok(json!({})) } diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index f41349b7e8c781..04d4b3ed00a17b 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -8,6 +8,7 @@ mod pipeline; mod sampler; mod shader; mod texture; +mod render_pass; use deno_core::error::bad_resource_id; use deno_core::error::type_error; @@ -154,6 +155,62 @@ pub fn init(rt: &mut deno_core::JsRuntime) { command_encoding::op_webgpu_command_encoder_finish, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_viewport", + render_pass::op_webgpu_render_pass_set_viewport, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_scissor_rect", + render_pass::op_webgpu_render_pass_set_scissor_rect, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_blend_color", + render_pass::op_webgpu_render_pass_set_blend_color, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_stencil_reference", + render_pass::op_webgpu_render_pass_set_stencil_reference, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_execute_bundles", + render_pass::op_webgpu_render_pass_execute_bundles, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_push_debug_group", + render_pass::op_webgpu_render_pass_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_pop_debug_group", + render_pass::op_webgpu_render_pass_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_insert_debug_marker", + render_pass::op_webgpu_render_pass_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_pipeline", + render_pass::op_webgpu_render_pass_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw", + render_pass::op_webgpu_render_pass_draw, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed", + render_pass::op_webgpu_render_pass_draw_indexed, + ); + super::reg_json_sync( rt, "op_webgpu_create_render_bundle_encoder", @@ -335,7 +392,7 @@ pub async fn op_webgpu_request_device( shader_validation: false, // TODO }, None, - (), // TODO + (), // TODO: id_in )?; let features = serialize_features(&instance.device_features(device)?); diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs new file mode 100644 index 00000000000000..cb3ba0b132ddd1 --- /dev/null +++ b/cli/ops/webgpu/render_pass.rs @@ -0,0 +1,351 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetViewportArgs { + render_pass_rid: u32, + x: f32, + y: f32, + width: f32, + height: f32, + min_depth: f32, + max_depth: f32, +} + +pub fn op_webgpu_render_pass_set_viewport( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetViewportArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_viewport( + render_pass, + args.x, + args.y, + args.width, + args.height, + args.min_depth, + args.max_depth, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetScissorRectArgs { + render_pass_rid: u32, + x: u32, + y: u32, + width: u32, + height: u32, +} + +pub fn op_webgpu_render_pass_set_scissor_rect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetScissorRectArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_scissor_rect( + render_pass, + args.x, + args.y, + args.width, + args.height, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetBlendColorArgs { + render_pass_rid: u32, + color: (), // TODO: mixed types +} + +pub fn op_webgpu_render_pass_set_blend_color( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetBlendColorArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_blend_color( + render_pass, + &wgt::Color { // TODO + r: 0.0, + g: 0.0, + b: 0.0, + a: 0.0, + } + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetStencilReferenceArgs { + render_pass_rid: u32, + reference: u32, +} + +pub fn op_webgpu_render_pass_set_stencil_reference( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetStencilReferenceArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_stencil_reference( + render_pass, + args.reference, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassExecuteBundlesArgs { + render_pass_rid: u32, + bundles: [u32], +} + +pub fn op_webgpu_render_pass_execute_bundles( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassExecuteBundlesArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::render_ffi::wgpu_render_pass_execute_bundles( + render_pass, + // TODO + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassPushDebugGroupArgs { + render_pass_rid: u32, + group_label: String, +} + +pub fn op_webgpu_render_pass_push_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassPushDebugGroupArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::render_ffi::wgpu_render_pass_push_debug_group( + render_pass, + std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + // TODO: color? + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassPopDebugGroupArgs { + render_pass_rid: u32, +} + +pub fn op_webgpu_render_pass_pop_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassPopDebugGroupArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_pop_debug_group(render_pass); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassInsertDebugMarkerArgs { + render_pass_rid: u32, + marker_label: String, +} + +pub fn op_webgpu_render_pass_insert_debug_marker( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassInsertDebugMarkerArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::render_ffi::wgpu_render_pass_insert_debug_marker( + render_pass, + std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + // TODO: color? + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetPipelineArgs { + render_pass_rid: u32, + pipeline: u32, +} + +pub fn op_webgpu_render_pass_set_pipeline( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetPipelineArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_pipeline( + render_pass, + *state + .resource_table + .get_mut::(args.pipeline) + .ok_or_else(bad_resource_id)?, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassDrawArgs { + render_pass_rid: u32, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, +} + +pub fn op_webgpu_render_pass_draw( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassDrawArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_draw( + render_pass, + args.vertex_count, + args.instance_count, + args.first_vertex, + args.first_instance, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassDrawIndexedArgs { + render_pass_rid: u32, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, +} + +pub fn op_webgpu_render_pass_draw_indexed( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassDrawIndexedArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_draw_indexed( + render_pass, + args.index_count, + args.instance_count, + args.first_index, + args.base_vertex, + args.first_instance, + ); + + Ok(json!({})) +} diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index f6d2f115a3b8c9..0ab02a2fdee256 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -200,12 +200,14 @@ ...descriptor, }); - return new GPURenderPipeline(rid, descriptor.label); + const pipeline = new GPURenderPipeline(rid, descriptor.label); + GPURenderPipelineMap.set(pipeline, rid); + return pipeline; } - async createReadyComputePipeline(descriptor) {} // TODO + async createReadyComputePipeline(descriptor) {} // TODO: missing? - async createReadyRenderPipeline(descriptor) {} // TODO + async createReadyRenderPipeline(descriptor) {} // TODO: missing? createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { @@ -237,7 +239,7 @@ class GPUQueue { constructor(label) { - this.label = label; + this.label = label ?? null; } submit(commandBuffers) {} // TODO @@ -255,7 +257,7 @@ constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } async mapAsync(mode, offset = 0, size = undefined) { @@ -274,7 +276,7 @@ bufferRid: this.#rid, offset, size, - }); // TODO + }); } unmap() { @@ -284,14 +286,14 @@ }); } - destroy() {} // TODO + destroy() {} // TODO: missing? } class GPUTexture { #rid; constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } createView(descriptor = {}) { @@ -306,41 +308,41 @@ return view; } - destroy() {} // TODO + destroy() {} // TODO: missing? } const GPUTextureViewMap = new WeakMap(); class GPUTextureView { constructor(label) { - this.label = label; + this.label = label ?? null; } } const GPUSamplerMap = new WeakMap(); class GPUSampler { constructor(label) { - this.label = label; + this.label = label ?? null; } } const GPUBindGroupLayoutMap = new WeakMap(); class GPUBindGroupLayout { constructor(label) { - this.label = label; + this.label = label ?? null; } } const GPUPipelineLayoutMap = new WeakMap(); class GPUPipelineLayout { constructor(label) { - this.label = label; + this.label = label ?? null; } } const GPUBindGroupMap = new WeakMap(); class GPUBindGroup { constructor(label) { - this.label = label; + this.label = label ?? null; } } @@ -349,7 +351,7 @@ #rid; constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } async compilationInfo() {} // TODO: missing? @@ -360,7 +362,7 @@ constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } getBindGroupLayout(index) { @@ -379,12 +381,13 @@ } } + const GPURenderPipelineMap = new WeakMap(); class GPURenderPipeline { #rid; constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } getBindGroupLayout(index) { @@ -408,7 +411,7 @@ constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } beginRenderPass(descriptor) { @@ -507,26 +510,59 @@ constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; + } + + setViewport(x, y, width, height, minDepth, maxDepth) { + core.jsonOpSync("op_webgpu_render_pass_set_viewport", { + renderPassRid: this.#rid, + x, + y, + width, + height, + minDepth, + maxDepth, + }); } - setViewport(x, y, width, height, minDepth, maxDepth) {} // TODO - - setScissorRect(x, y, width, height) {} // TODO + setScissorRect(x, y, width, height) { + core.jsonOpSync("op_webgpu_render_pass_set_scissor_rect", { + renderPassRid: this.#rid, + x, + y, + width, + height, + }); + } - setBlendColor(color) {} // TODO - setStencilReference(reference) {} // TODO + setBlendColor(color) { + core.jsonOpSync("op_webgpu_render_pass_set_blend_color", { + renderPassRid: this.#rid, + color, + }); + } + setStencilReference(reference) { + core.jsonOpSync("op_webgpu_render_pass_set_stencil_reference", { + renderPassRid: this.#rid, + reference, + }); + } - beginOcclusionQuery(queryIndex) {} // TODO - endOcclusionQuery() {} // TODO + beginOcclusionQuery(queryIndex) {} // TODO: missing? + endOcclusionQuery() {} // TODO: missing? - beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO - endPipelineStatisticsQuery() {} // TODO + beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO: missing? + endPipelineStatisticsQuery() {} // TODO: missing? - writeTimestamp(querySet, queryIndex) {} // TODO + writeTimestamp(querySet, queryIndex) {} // TODO: missing? - executeBundles(bundles) {} // TODO - endPass() {} // TODO + executeBundles(bundles) { + core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { + renderPassRid: this.#rid, + bundles, + }); + } + endPass() {} // TODO: missing? setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO @@ -538,26 +574,62 @@ dynamicOffsetsDataLength, ) {} // TODO - pushDebugGroup(groupLabel) {} // TODO - popDebugGroup() {} // TODO - insertDebugMarker(markerLabel) {} // TODO + pushDebugGroup(groupLabel) { + core.jsonOpSync("op_webgpu_render_pass_push_debug_group", { + renderPassRid: this.#rid, + groupLabel, + }); + } + popDebugGroup() { + core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { + renderPassRid: this.#rid, + }); + } + insertDebugMarker(markerLabel) { + core.jsonOpSync("op_webgpu_render_pass_insert_debug_marker", { + renderPassRid: this.#rid, + markerLabel, + }); + } - setPipeline(pipeline) {} // TODO + setPipeline(pipeline) { + core.jsonOpSync("op_webgpu_render_pass_set_pipeline", { + renderPassRid: this.#rid, + pipeline: GPURenderPipelineMap.get(pipeline), + }); + } - setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO - setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO: buffer + setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO: buffer - draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + core.jsonOpSync("op_webgpu_render_pass_draw", { + renderPassRid: this.#rid, + vertexCount, + instanceCount, + firstVertex, + firstInstance, + }); + } drawIndexed( indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0, - ) {} // TODO + ) { + core.jsonOpSync("op_webgpu_render_pass_draw_indexed", { + renderPassRid: this.#rid, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance, + }); + } - drawIndirect(indirectBuffer, indirectOffset) {} // TODO - drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO + drawIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer + drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer } class GPUComputePassEncoder { @@ -565,17 +637,17 @@ constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } setPipeline(pipeline) {} // TODO dispatch(x, y = 1, z = 1) {} // TODO dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO - beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO - endPipelineStatisticsQuery() {} // TODO + beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO: missing? + endPipelineStatisticsQuery() {} // TODO: missing? - writeTimestamp(querySet, queryIndex) {} // TODO + writeTimestamp(querySet, queryIndex) {} // TODO: missing? endPass() {} // TODO @@ -596,7 +668,7 @@ class GPUCommandBuffer { constructor(label) { - this.label = label; + this.label = label ?? null; } get executionTime() {} // TODO: missing? @@ -606,7 +678,7 @@ #rid; constructor(rid, label) { this.#rid = rid; - this.label = label; + this.label = label ?? null; } finish(descriptor = {}) { @@ -656,7 +728,7 @@ class GPURenderBundle { constructor(label) { - this.label = label; + this.label = label ?? null; } } From c426657d46d865cbc415b5e04fb3b81ba489fc76 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 12 Oct 2020 20:23:54 +0200 Subject: [PATCH 009/144] cleanup --- cli/ops/webgpu/binding.rs | 4 +-- cli/ops/webgpu/bundle.rs | 1 + cli/ops/webgpu/command_encoding.rs | 10 ++---- cli/ops/webgpu/mod.rs | 2 +- cli/ops/webgpu/pipeline.rs | 5 ++- cli/ops/webgpu/render_pass.rs | 5 +-- cli/ops/webgpu/sampler.rs | 6 +--- cli/ops/webgpu/shader.rs | 3 +- cli/rt/14_webgpu.js | 58 ++++++++++++++++++++++-------- 9 files changed, 57 insertions(+), 37 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 1e4c36bbeb6032..3c1c275660d2a9 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -135,7 +135,7 @@ pub fn op_webgpu_create_bind_group_layout( } _ => unreachable!(), }, - count: None, // TODO: look into what this is + count: None, } }) .collect::>(), @@ -194,7 +194,7 @@ pub fn op_webgpu_create_pipeline_layout( }) .collect::>(), ), - push_constant_ranges: Default::default(), // TODO: look into what this is + push_constant_ranges: Default::default(), }, (), // TODO: id_in )?; diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index cebcbe70ecd1d9..f65fa85b39906d 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -41,6 +41,7 @@ pub fn op_webgpu_create_render_bundle_encoder( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + wgc::command::RenderBundleEncoder::new let render_bundle_encoder = instance.device_create_render_bundle_encoder( *device, &wgc::command::RenderBundleEncoderDescriptor { diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index 41061459f78ea4..f37ae2b5e12fa8 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -19,7 +19,7 @@ struct CreateCommandEncoderArgs { instance_rid: u32, device_rid: u32, label: Option, - measure_execution_time: Option, + measure_execution_time: Option, // waiting for wgpu to add measure_execution_time } pub fn op_webgpu_create_command_encoder( @@ -41,7 +41,6 @@ pub fn op_webgpu_create_command_encoder( let command_encoder = instance.device_create_command_encoder( *device, &wgt::CommandEncoderDescriptor { - // TODO: should accept measure_execution_time label: args.label.map(|label| Cow::Borrowed(&label)), }, (), // TODO: id_in @@ -82,11 +81,11 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { struct CommandEncoderBeginRenderPassArgs { instance_rid: u32, command_encoder_rid: u32, - label: Option, + label: Option, // wgpu#974 color_attachments: [GPURenderPassColorAttachmentDescriptor], depth_stencil_attachment: Option, - occlusion_query_set: u32, // TODO: wait to be added to wpgu, and add to JS + occlusion_query_set: u32, // wgpu#721 } pub fn op_webgpu_command_encoder_begin_render_pass( @@ -108,7 +107,6 @@ pub fn op_webgpu_command_encoder_begin_render_pass( let render_pass = wgc::command::RenderPass::new( *command_encoder, wgc::command::RenderPassDescriptor { - // TODO: should accept label color_attachments: Cow::Owned( args .color_attachments @@ -147,8 +145,6 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }, ); - instance.command_encoder_run_render_pass(*command_encoder, &render_pass)?; - let rid = state .resource_table .add("webGPURenderPass", Box::new(render_pass)); diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 04d4b3ed00a17b..9dc9eded629d20 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -342,6 +342,7 @@ struct GPULimits { struct RequestDeviceArgs { instance_rid: u32, adapter_rid: u32, + label: Option, // wgpu#976 features: Option<[String]>, limits: Option, } @@ -366,7 +367,6 @@ pub async fn op_webgpu_request_device( let device = instance.adapter_request_device( *adapter, &wgt::DeviceDescriptor { - // TODO: should accept label features: Default::default(), // TODO limits: args.limits.map_or(Default::default(), |limits| { wgt::Limits { diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 77fe3479cddb1e..1d6a2c68120825 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -135,8 +135,7 @@ pub fn op_webgpu_create_compute_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - // TODO: look into what that u8 is - let (compute_pipeline, smth) = instance.device_create_compute_pipeline( + let (compute_pipeline, _) = instance.device_create_compute_pipeline( *device, &wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), @@ -308,7 +307,7 @@ pub fn op_webgpu_create_render_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let (render_pipeline, smth) = instance.device_create_render_pipeline( + let (render_pipeline, _) = instance.device_create_render_pipeline( *device, &wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index cb3ba0b132ddd1..9837668a6c6dc4 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -165,6 +165,7 @@ pub fn op_webgpu_render_pass_execute_bundles( // TODO ); } + wgc::command::render_ffi::end_pass Ok(json!({})) } @@ -192,7 +193,7 @@ pub fn op_webgpu_render_pass_push_debug_group( wgc::command::render_ffi::wgpu_render_pass_push_debug_group( render_pass, std::ffi::CString::new(args.group_label).unwrap().as_ptr(), - // TODO: color? + 0, // wgpu#975 ); } @@ -245,7 +246,7 @@ pub fn op_webgpu_render_pass_insert_debug_marker( wgc::command::render_ffi::wgpu_render_pass_insert_debug_marker( render_pass, std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), - // TODO: color? + 0, // wgpu#975 ); } diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index b1fe9042de780c..f333758d30fa08 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -95,11 +95,7 @@ pub fn op_webgpu_create_sampler( lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO: check if there is a better solution compare: args.compare.map(serialize_compare_function), - anisotropy_clamp: Some( - args - .max_anisotropy - .unwrap_or(unsafe { std::num::NonZeroU8::new_unchecked(1) }), - ), // TODO: check what None would be + anisotropy_clamp: args.max_anisotropy, }, (), // TODO: id_in )?; diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index da482afa0f1a7a..cb600c07a9d549 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -17,7 +17,7 @@ use std::rc::Rc; struct CreateShaderModuleArgs { instance_rid: u32, device_rid: u32, - label: Option, + label: Option, // wgpu#977 code: String, source_map: (), // TODO: https://gpuweb.github.io/gpuweb/#shader-module-creation } @@ -39,7 +39,6 @@ pub fn op_webgpu_create_shader_module( .ok_or_else(bad_resource_id)?; let shader_module = instance.device_create_shader_module( - // TODO: should accept label *device, wgc::pipeline::ShaderModuleSource, // TODO (), // TODO: id_in diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 0ab02a2fdee256..964443fe6cbeaf 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -205,9 +205,13 @@ return pipeline; } - async createReadyComputePipeline(descriptor) {} // TODO: missing? + async createReadyComputePipeline(descriptor) { + throw new Error("Not yet implemented"); // easy polyfill + } - async createReadyRenderPipeline(descriptor) {} // TODO: missing? + async createReadyRenderPipeline(descriptor) { + throw new Error("Not yet implemented"); // easy polyfill + } createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { @@ -286,7 +290,9 @@ }); } - destroy() {} // TODO: missing? + destroy() { + throw new Error("Not yet implemented"); // master + } } class GPUTexture { @@ -308,7 +314,9 @@ return view; } - destroy() {} // TODO: missing? + destroy() { + throw new Error("Not yet implemented"); // master + } } const GPUTextureViewMap = new WeakMap(); @@ -354,7 +362,9 @@ this.label = label ?? null; } - async compilationInfo() {} // TODO: missing? + async compilationInfo() { + throw new Error("Not yet implemented"); // wgpu#977 + } } class GPUComputePipeline { @@ -548,13 +558,23 @@ }); } - beginOcclusionQuery(queryIndex) {} // TODO: missing? - endOcclusionQuery() {} // TODO: missing? + beginOcclusionQuery(queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } + endOcclusionQuery() { + throw new Error("Not yet implemented"); // wgpu#721 + } - beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO: missing? - endPipelineStatisticsQuery() {} // TODO: missing? + beginPipelineStatisticsQuery(querySet, queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } + endPipelineStatisticsQuery() { + throw new Error("Not yet implemented"); // wgpu#721 + } - writeTimestamp(querySet, queryIndex) {} // TODO: missing? + writeTimestamp(querySet, queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } executeBundles(bundles) { core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { @@ -562,7 +582,7 @@ bundles, }); } - endPass() {} // TODO: missing? + endPass() {} // TODO setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO @@ -644,10 +664,16 @@ dispatch(x, y = 1, z = 1) {} // TODO dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO - beginPipelineStatisticsQuery(querySet, queryIndex) {} // TODO: missing? - endPipelineStatisticsQuery() {} // TODO: missing? + beginPipelineStatisticsQuery(querySet, queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } + endPipelineStatisticsQuery() { + throw new Error("Not yet implemented"); // wgpu#721 + } - writeTimestamp(querySet, queryIndex) {} // TODO: missing? + writeTimestamp(querySet, queryIndex) { + throw new Error("Not yet implemented"); // wgpu#721 + } endPass() {} // TODO @@ -671,7 +697,9 @@ this.label = label ?? null; } - get executionTime() {} // TODO: missing? + get executionTime() { + throw new Error("Not yet implemented"); + } } class GPURenderBundleEncoder { From 11032e755199b28c1828cdc07ad57b6baa2c9a4d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 04:49:00 +0200 Subject: [PATCH 010/144] compute pass --- cli/ops/webgpu/command_encoding.rs | 3 +- cli/ops/webgpu/compute_pass.rs | 192 +++++++++++++++++++++++++++++ cli/ops/webgpu/mod.rs | 37 ++++++ cli/ops/webgpu/render_pass.rs | 36 ++++++ cli/rt/14_webgpu.js | 71 +++++++++-- 5 files changed, 324 insertions(+), 15 deletions(-) create mode 100644 cli/ops/webgpu/compute_pass.rs diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoding.rs index f37ae2b5e12fa8..7b6abf83b8897f 100644 --- a/cli/ops/webgpu/command_encoding.rs +++ b/cli/ops/webgpu/command_encoding.rs @@ -178,9 +178,8 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let compute_pass = wgc::command::ComputePass::new(*command_encoder); // TODO: should accept label - instance.command_encoder_run_compute_pass(*command_encoder, &compute_pass); + let compute_pass = wgc::command::ComputePass::new(*command_encoder); let rid = state .resource_table diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs new file mode 100644 index 00000000000000..d7f051242225f4 --- /dev/null +++ b/cli/ops/webgpu/compute_pass.rs @@ -0,0 +1,192 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassSetPipelineArgs { + compute_pass_rid: u32, + pipeline: u32, +} + +pub fn op_webgpu_compute_pass_set_pipeline( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassSetPipelineArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::compute_ffi::wgpu_compute_pass_set_pipeline( + compute_pass, + *state + .resource_table + .get_mut::(args.pipeline) + .ok_or_else(bad_resource_id)?, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassDispatchArgs { + compute_pass_rid: u32, + x: u32, + y: u32, + z: u32, +} + +pub fn op_webgpu_compute_pass_dispatch( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassDispatchArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::compute_ffi::wgpu_compute_pass_dispatch( + compute_pass, + args.x, + args.y, + args.z, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassEndPassArgs { + instance_rid: u32, + command_encoder_rid: u32, + compute_pass_rid: u32, +} + +pub fn op_webgpu_compute_pass_end_pass( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassEndPassArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_run_compute_pass( + *command_encoder, + compute_pass, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassPushDebugGroupArgs { + compute_pass_rid: u32, + group_label: String, +} + +pub fn op_webgpu_compute_pass_push_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassPushDebugGroupArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::compute_ffi::wgpu_compute_pass_push_debug_group( + compute_pass, + std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + 0, // wgpu#975 + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassPopDebugGroupArgs { + compute_pass_rid: u32, +} + +pub fn op_webgpu_compute_pass_pop_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassPopDebugGroupArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::compute_ffi::wgpu_compute_pass_pop_debug_group(compute_pass); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassInsertDebugMarkerArgs { + compute_pass_rid: u32, + marker_label: String, +} + +pub fn op_webgpu_compute_pass_insert_debug_marker( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassInsertDebugMarkerArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( + compute_pass, + std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + 0, // wgpu#975 + ); + } + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 9dc9eded629d20..1be88834b9dfc2 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -9,6 +9,7 @@ mod sampler; mod shader; mod texture; mod render_pass; +mod compute_pass; use deno_core::error::bad_resource_id; use deno_core::error::type_error; @@ -180,6 +181,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pass_execute_bundles", render_pass::op_webgpu_render_pass_execute_bundles, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_end_pass", + render_pass::op_webgpu_render_pass_end_pass, + ); super::reg_json_sync( rt, "op_webgpu_render_pass_push_debug_group", @@ -211,6 +217,37 @@ pub fn init(rt: &mut deno_core::JsRuntime) { render_pass::op_webgpu_render_pass_draw_indexed, ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_pipeline", + compute_pass::op_webgpu_compute_pass_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch", + compute_pass::op_webgpu_compute_pass_dispatch, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_end_pass", + compute_pass::op_webgpu_compute_pass_end_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_push_debug_group", + compute_pass::op_webgpu_compute_pass_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_pop_debug_group", + compute_pass::op_webgpu_compute_pass_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_insert_debug_marker", + compute_pass::op_webgpu_compute_pass_insert_debug_marker, + ); + super::reg_json_sync( rt, "op_webgpu_create_render_bundle_encoder", diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 9837668a6c6dc4..4a6750bef18683 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -170,6 +170,42 @@ pub fn op_webgpu_render_pass_execute_bundles( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassEndPassArgs { + instance_rid: u32, + command_encoder_rid: u32, + render_pass_rid: u32, +} + +pub fn op_webgpu_render_pass_end_pass( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassEndPassArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_run_render_pass( + *command_encoder, + render_pass, + )?; + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassPushDebugGroupArgs { diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 964443fe6cbeaf..b1d28cafe437dc 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -190,7 +190,9 @@ }, }); - return new GPUComputePipeline(rid, descriptor.label); + const pipeline = new GPUComputePipeline(rid, descriptor.label); + GPUComputePipelineMap.set(pipeline, rid); + return pipeline; } createRenderPipeline(descriptor) { @@ -367,6 +369,7 @@ } } + const GPUComputePipelineMap = new WeakMap(); class GPUComputePipeline { #rid; @@ -434,7 +437,7 @@ }, ); - return new GPURenderPassEncoder(rid, descriptor.label); + return new GPURenderPassEncoder(this.#rid, rid, descriptor.label); } beginComputePass(descriptor = {}) { @@ -447,7 +450,7 @@ }, ); - return new GPUComputePassEncoder(rid, descriptor.label); + return new GPUComputePassEncoder(this.#rid, rid, descriptor.label); } copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {} // TODO: buffer @@ -516,9 +519,11 @@ } class GPURenderPassEncoder { + #commandEncoderRid; #rid; - constructor(rid, label) { + constructor(commandEncoderRid, rid, label) { + this.#commandEncoderRid = commandEncoderRid; this.#rid = rid; this.label = label ?? null; } @@ -582,7 +587,13 @@ bundles, }); } - endPass() {} // TODO + endPass() { + core.jsonOpSync("op_webgpu_render_pass_end_pass", { + instanceRid, + commandEncoderRid: this.#commandEncoderRid, + renderPassRid: this.#rid, + }); + } setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO @@ -653,16 +664,30 @@ } class GPUComputePassEncoder { + #commandEncoderRid; #rid; - constructor(rid, label) { + constructor(commandEncoderRid, rid, label) { + this.#commandEncoderRid = commandEncoderRid; this.#rid = rid; this.label = label ?? null; } - setPipeline(pipeline) {} // TODO - dispatch(x, y = 1, z = 1) {} // TODO - dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO + setPipeline(pipeline) { + core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { + computePassRid: this.#rid, + pipeline: GPUComputePipelineMap.get(pipeline), + }); + } + dispatch(x, y = 1, z = 1) { + core.jsonOpSync("op_webgpu_compute_pass_dispatch", { + computePassRid: this.#rid, + x, + y, + z, + }); + } + dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer beginPipelineStatisticsQuery(querySet, queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 @@ -675,7 +700,13 @@ throw new Error("Not yet implemented"); // wgpu#721 } - endPass() {} // TODO + endPass() { + core.jsonOpSync("op_webgpu_compute_pass_end_pass", { + instanceRid, + commandEncoderRid: this.#commandEncoderRid, + computePassRid: this.#rid, + }); + } setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO @@ -687,9 +718,23 @@ dynamicOffsetsDataLength, ) {} // TODO - pushDebugGroup(groupLabel) {} // TODO - popDebugGroup() {} // TODO - insertDebugMarker(markerLabel) {} // TODO + pushDebugGroup(groupLabel) { + core.jsonOpSync("op_webgpu_compute_pass_push_debug_group", { + computePassRid: this.#rid, + groupLabel, + }); + } + popDebugGroup() { + core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { + computePassRid: this.#rid, + }); + } + insertDebugMarker(markerLabel) { + core.jsonOpSync("op_webgpu_compute_pass_insert_debug_marker", { + computePassRid: this.#rid, + markerLabel, + }); + } } class GPUCommandBuffer { From 49c82d03b4237725a1823ddbecfaad328e70adf1 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:08:43 +0200 Subject: [PATCH 011/144] render_bundle_encoder --- cli/ops/webgpu/bundle.rs | 194 +++++++++++++++++- ...command_encoding.rs => command_encoder.rs} | 0 cli/ops/webgpu/mod.rs | 48 ++++- cli/rt/14_webgpu.js | 58 +++++- 4 files changed, 271 insertions(+), 29 deletions(-) rename cli/ops/webgpu/{command_encoding.rs => command_encoder.rs} (100%) diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index f65fa85b39906d..6f072357135a2c 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -17,7 +17,6 @@ use std::rc::Rc; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderBundleEncoderArgs { - instance_rid: u32, device_rid: u32, label: Option, color_formats: [String], @@ -32,18 +31,12 @@ pub fn op_webgpu_create_render_bundle_encoder( ) -> Result { let args: CreateRenderBundleEncoderArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; let device = state .resource_table .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - wgc::command::RenderBundleEncoder::new - let render_bundle_encoder = instance.device_create_render_bundle_encoder( - *device, + let render_bundle_encoder = wgc::command::RenderBundleEncoder::new( &wgc::command::RenderBundleEncoderDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), color_formats: Cow::Owned( @@ -58,6 +51,8 @@ pub fn op_webgpu_create_render_bundle_encoder( .map(|format| serialize_texture_format(format)?), sample_count: args.sample_count.unwrap_or(1), }, + *device, + None, // TODO: check what this is )?; let rid = state @@ -90,7 +85,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; let render_bundle = instance.render_bundle_encoder_finish( @@ -109,3 +104,184 @@ pub fn op_webgpu_render_bundle_encoder_finish( "rid": rid, })) } + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderPushDebugGroupArgs { + render_bundle_encoder_rid: u32, + group_label: String, +} + +pub fn op_webgpu_render_bundle_encoder_push_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderPushDebugGroupArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::bundle_ffi::wgpu_render_bundle_push_debug_group( + render_bundle_encoder, + std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderPopDebugGroupArgs { + render_bundle_encoder_rid: u32, +} + +pub fn op_webgpu_render_bundle_encoder_pop_debug_group( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderPopDebugGroupArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::bundle_ffi::wgpu_render_bundle_pop_debug_group(render_bundle_encoder); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderInsertDebugMarkerArgs { + render_bundle_encoder_rid: u32, + marker_label: String, +} + +pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( + render_bundle_encoder, + std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderSetPipelineArgs { + render_bundle_encoder_rid: u32, + pipeline: u32, +} + +pub fn op_webgpu_render_bundle_encoder_set_pipeline( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderSetPipelineArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_set_pipeline( + render_bundle_encoder, + *state + .resource_table + .get_mut::(args.pipeline) + .ok_or_else(bad_resource_id)? + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderDrawArgs { + render_bundle_encoder_rid: u32, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, +} + +pub fn op_webgpu_render_bundle_encoder_draw( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderDrawArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_draw( + render_bundle_encoder, + args.vertex_count, + args.instance_count, + args.first_vertex, + args.first_instance, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderDrawIndexedArgs { + render_bundle_encoder_rid: u32, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, +} + +pub fn op_webgpu_render_bundle_encoder_draw_indexed( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderDrawIndexedArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_draw_indexed( + render_pass, + args.index_count, + args.instance_count, + args.first_index, + args.base_vertex, + args.first_instance, + ); + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/command_encoding.rs b/cli/ops/webgpu/command_encoder.rs similarity index 100% rename from cli/ops/webgpu/command_encoding.rs rename to cli/ops/webgpu/command_encoder.rs diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 1be88834b9dfc2..a4014bc499d23f 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -3,7 +3,7 @@ mod binding; mod buffer; mod bundle; -mod command_encoding; +mod command_encoder; mod pipeline; mod sampler; mod shader; @@ -118,42 +118,42 @@ pub fn init(rt: &mut deno_core::JsRuntime) { super::reg_json_sync( rt, "op_webgpu_create_command_encoder", - command_encoding::op_webgpu_create_command_encoder, + command_encoder::op_webgpu_create_command_encoder, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_begin_render_pass", - command_encoding::op_webgpu_command_encoder_begin_render_pass, + command_encoder::op_webgpu_command_encoder_begin_render_pass, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_begin_compute_pass", - command_encoding::op_webgpu_command_encoder_begin_compute_pass, + command_encoder::op_webgpu_command_encoder_begin_compute_pass, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_copy_texture_to_texture", - command_encoding::op_webgpu_command_encoder_copy_texture_to_texture, + command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_push_debug_group", - command_encoding::op_webgpu_command_encoder_push_debug_group, + command_encoder::op_webgpu_command_encoder_push_debug_group, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_pop_debug_group", - command_encoding::op_webgpu_command_encoder_pop_debug_group, + command_encoder::op_webgpu_command_encoder_pop_debug_group, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_insert_debug_marker", - command_encoding::op_webgpu_command_encoder_insert_debug_marker, + command_encoder::op_webgpu_command_encoder_insert_debug_marker, ); super::reg_json_sync( rt, "op_webgpu_command_encoder_finish", - command_encoding::op_webgpu_command_encoder_finish, + command_encoder::op_webgpu_command_encoder_finish, ); super::reg_json_sync( @@ -258,6 +258,36 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_finish", bundle::op_webgpu_render_bundle_encoder_finish, ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_push_debug_group", + bundle::op_webgpu_render_bundle_encoder_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_pop_debug_group", + bundle::op_webgpu_render_bundle_encoder_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_insert_debug_marker", + bundle::op_webgpu_render_bundle_encoder_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_pipeline", + bundle::op_webgpu_render_bundle_encoder_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw", + bundle::op_webgpu_render_bundle_encoder_draw, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indexed", + bundle::op_webgpu_render_bundle_encoder_draw_indexed, + ); } fn serialize_features(features: &wgt::Features) -> Vec<&str> { diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index b1d28cafe437dc..3722418afbaca9 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -229,7 +229,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { - instanceRid, deviceRid: this.#rid, ...descriptor, }, @@ -777,26 +776,63 @@ dynamicOffsetsDataLength, ) {} // TODO - pushDebugGroup(groupLabel) {} // TODO - popDebugGroup() {} // TODO - insertDebugMarker(markerLabel) {} // TODO + pushDebugGroup(groupLabel) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { + renderBundleEncoderRid: this.#rid, + groupLabel, + }); + } + popDebugGroup() { + core.jsonOpSync("op_webgpu_render_bundle_encoder_pop_debug_group", { + renderBundleEncoderRid: this.#rid, + }); + } + insertDebugMarker(markerLabel) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { + renderBundleEncoderRid: this.#rid, + markerLabel, + }); + } - setPipeline(pipeline) {} // TODO - setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO - setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO + setPipeline(pipeline) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { + renderBundleEncoderRid: this.#rid, + pipeline: GPURenderPipelineMap.get(pipeline), + }); + } + + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO: buffer + setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO: buffer - draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {} // TODO + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw", { + renderBundleEncoderRid: this.#rid, + vertexCount, + instanceCount, + firstVertex, + firstInstance, + }); + } drawIndexed( indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0, - ) {} // TODO + ) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indexed", { + renderBundleEncoderRid: this.#rid, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance, + }); + } - drawIndirect(indirectBuffer, indirectOffset) {} // TODO - drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO + drawIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer + drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer } class GPURenderBundle { From 477e15f8a7e9fde4f17980df0a8f6d13353f19c0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:10:07 +0200 Subject: [PATCH 012/144] fmt --- cli/ops/webgpu/bundle.rs | 43 ++++++++++++++++++++++--------- cli/ops/webgpu/command_encoder.rs | 8 ++++-- cli/ops/webgpu/compute_pass.rs | 5 +--- cli/ops/webgpu/mod.rs | 4 +-- cli/ops/webgpu/render_pass.rs | 11 +++----- cli/rt/14_webgpu.js | 9 +++++-- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 6f072357135a2c..fadf737ecfbd47 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -85,7 +85,9 @@ pub fn op_webgpu_render_bundle_encoder_finish( .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; let render_bundle = instance.render_bundle_encoder_finish( @@ -117,11 +119,14 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderPushDebugGroupArgs = serde_json::from_value(args)?; + let args: RenderBundleEncoderPushDebugGroupArgs = + serde_json::from_value(args)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; unsafe { @@ -145,15 +150,20 @@ pub fn op_webgpu_render_bundle_encoder_pop_debug_group( args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderPopDebugGroupArgs = serde_json::from_value(args)?; + let args: RenderBundleEncoderPopDebugGroupArgs = + serde_json::from_value(args)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::bundle_ffi::wgpu_render_bundle_pop_debug_group(render_bundle_encoder); + wgc::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( + render_bundle_encoder, + ); } Ok(json!({})) @@ -171,11 +181,14 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; + let args: RenderBundleEncoderInsertDebugMarkerArgs = + serde_json::from_value(args)?; let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; unsafe { @@ -204,7 +217,9 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_set_pipeline( @@ -212,7 +227,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( *state .resource_table .get_mut::(args.pipeline) - .ok_or_else(bad_resource_id)? + .ok_or_else(bad_resource_id)?, ); Ok(json!({})) @@ -237,7 +252,9 @@ pub fn op_webgpu_render_bundle_encoder_draw( let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw( @@ -271,7 +288,9 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( let render_bundle_encoder = state .resource_table - .get_mut::(args.render_bundle_encoder_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw_indexed( diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 7b6abf83b8897f..827f1684113ac7 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -278,7 +278,8 @@ pub fn op_webgpu_command_encoder_push_debug_group( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_push_debug_group(*command_encoder, &args.group_label)?; + instance + .command_encoder_push_debug_group(*command_encoder, &args.group_label)?; Ok(json!({})) } @@ -335,7 +336,10 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_insert_debug_marker(*command_encoder, &args.marker_label)?; + instance.command_encoder_insert_debug_marker( + *command_encoder, + &args.marker_label, + )?; Ok(json!({})) } diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index d7f051242225f4..b35458751a4390 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -100,10 +100,7 @@ pub fn op_webgpu_compute_pass_end_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_run_compute_pass( - *command_encoder, - compute_pass, - ); + instance.command_encoder_run_compute_pass(*command_encoder, compute_pass); Ok(json!({})) } diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index a4014bc499d23f..1aaa5dcd22590f 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -4,12 +4,12 @@ mod binding; mod buffer; mod bundle; mod command_encoder; +mod compute_pass; mod pipeline; +mod render_pass; mod sampler; mod shader; mod texture; -mod render_pass; -mod compute_pass; use deno_core::error::bad_resource_id; use deno_core::error::type_error; diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 4a6750bef18683..47cc84bf12d4e0 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -102,12 +102,13 @@ pub fn op_webgpu_render_pass_set_blend_color( wgc::command::render_ffi::wgpu_render_pass_set_blend_color( render_pass, - &wgt::Color { // TODO + &wgt::Color { + // TODO r: 0.0, g: 0.0, b: 0.0, a: 0.0, - } + }, ); Ok(json!({})) @@ -165,7 +166,6 @@ pub fn op_webgpu_render_pass_execute_bundles( // TODO ); } - wgc::command::render_ffi::end_pass Ok(json!({})) } @@ -198,10 +198,7 @@ pub fn op_webgpu_render_pass_end_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_run_render_pass( - *command_encoder, - render_pass, - )?; + instance.command_encoder_run_render_pass(*command_encoder, render_pass)?; Ok(json!({})) } diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 3722418afbaca9..4d24c9f58ab967 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -452,7 +452,13 @@ return new GPUComputePassEncoder(this.#rid, rid, descriptor.label); } - copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {} // TODO: buffer + copyBufferToBuffer( + source, + sourceOffset, + destination, + destinationOffset, + size, + ) {} // TODO: buffer copyBufferToTexture(source, destination, copySize) {} // TODO: buffer @@ -794,7 +800,6 @@ }); } - setPipeline(pipeline) { core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { renderBundleEncoderRid: this.#rid, From 0ca3900af42b7492d5f119878c344bd3a75934e9 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 07:09:18 +0200 Subject: [PATCH 013/144] queue --- cli/ops/webgpu/command_encoder.rs | 8 +-- cli/ops/webgpu/mod.rs | 12 ++++ cli/ops/webgpu/queue.rs | 115 ++++++++++++++++++++++++++++++ cli/ops/webgpu/render_pass.rs | 13 +++- cli/rt/14_webgpu.js | 49 ++++++++++--- 5 files changed, 182 insertions(+), 15 deletions(-) create mode 100644 cli/ops/webgpu/queue.rs diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 827f1684113ac7..181eaa9e66b3a1 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -192,10 +192,10 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUTextureCopyView { - texture: u32, - mip_level: Option, - origin: (), // TODO: mixed types +pub struct GPUTextureCopyView { + pub texture: u32, + pub mip_level: Option, + pub origin: (), // TODO: mixed types } #[derive(Deserialize)] diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 1aaa5dcd22590f..d9f0f4444832fe 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -6,6 +6,7 @@ mod bundle; mod command_encoder; mod compute_pass; mod pipeline; +mod queue; mod render_pass; mod sampler; mod shader; @@ -288,6 +289,17 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_draw_indexed", bundle::op_webgpu_render_bundle_encoder_draw_indexed, ); + + super::reg_json_sync( + rt, + "op_webgpu_queue_submit", + queue::op_webgpu_queue_submit, + ); + super::reg_json_sync( + rt, + "op_webgpu_write_texture", + queue::op_webgpu_write_texture, + ); } fn serialize_features(features: &wgt::Features) -> Vec<&str> { diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs new file mode 100644 index 00000000000000..e843c8ffada17a --- /dev/null +++ b/cli/ops/webgpu/queue.rs @@ -0,0 +1,115 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::BufVec; +use deno_core::OpState; +use deno_core::{serde_json, ZeroCopyBuf}; +use serde::Deserialize; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct QueueSubmitArgs { + instance_rid: u32, + queue_rid: u32, + command_buffers: [u32], +} + +pub fn op_webgpu_queue_submit( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: QueueSubmitArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let queue = state + .resource_table + .get_mut::(args.queue_rid) + .ok_or_else(bad_resource_id)?; + + instance.queue_submit( + *queue, + &args + .command_buffers + .iter() + .map(|rid| { + *state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::<[wgc::id::CommandBufferId]>(), + )?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUTextureDataLayout { + offset: Option, + bytes_per_row: Option, + rows_per_image: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct QueueWriteTextureArgs { + instance_rid: u32, + queue_rid: u32, + destination: super::command_encoder::GPUTextureCopyView, + data: (), // TODO + data_layout: GPUTextureDataLayout, + size: (), // TODO: mixed types +} + +pub fn op_webgpu_write_texture( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: QueueWriteTextureArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let queue = state + .resource_table + .get_mut::(args.queue_rid) + .ok_or_else(bad_resource_id)?; + + instance.queue_write_texture( + *queue, + &wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: Default::default(), + }, + (), + &wgt::TextureDataLayout { + offset: args.data_layout.offset.unwrap_or(0), + bytes_per_row: args.data_layout.bytes_per_row, + rows_per_image: args.data_layout.rows_per_image, + }, + &wgt::Extent3d { + width: 0, + height: 0, + depth: 0, + }, + )?; + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 47cc84bf12d4e0..f86c2bdf10407f 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -163,7 +163,18 @@ pub fn op_webgpu_render_pass_execute_bundles( unsafe { wgc::command::render_ffi::wgpu_render_pass_execute_bundles( render_pass, - // TODO + args + .bundles + .iter() + .map(|rid| { + *state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::<[wgc::id::RenderBundleId]>() + .as_ptr(), + args.bundles.len(), ); } diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 4d24c9f58ab967..8e8ce3609e0874 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -49,6 +49,7 @@ } } + // TODO: https://gpuweb.github.io/gpuweb/#telemetry class GPUDevice extends EventTarget { #rid; #adapter; @@ -85,7 +86,7 @@ ...descriptor, }); - return new GPUBuffer(rid, descriptor.label); // TODO + return new GPUBuffer(rid, descriptor.label); } createTexture(descriptor) { @@ -95,7 +96,7 @@ ...descriptor, }); - return new GPUTexture(rid, descriptor.label); // TODO + return new GPUTexture(rid, descriptor.label); } createSampler(descriptor = {}) { @@ -247,16 +248,38 @@ this.label = label ?? null; } - submit(commandBuffers) {} // TODO - createFence(descriptor = {}) {} // TODO + submit(commandBuffers) { + core.jsonOpSync("op_webgpu_queue_submit", { + instanceRid, + queueRid: this.#rid, + commandBuffers: commandBuffers.map((buffer) => + GPUCommandBufferMap.get(buffer) + ), + }); + } + createFence(descriptor = {}) { + throw new Error("Not yet implemented"); + } - writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) {} + writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) {} // TODO: buffer - writeTexture(destination, data, dataLayout, size) {} // TODO + writeTexture(destination, data, dataLayout, size) { + core.jsonOpSync("op_webgpu_write_texture", { + instanceRid, + queueRid: this.#rid, + destination, + data, + dataLayout, + size, + }); + } - copyImageBitmapToTexture(source, destination, copySize) {} // TODO + copyImageBitmapToTexture(source, destination, copySize) { + throw new Error("Not yet implemented"); + } } + // TODO: https://gpuweb.github.io/gpuweb/#buffer-interface class GPUBuffer { #rid; @@ -519,7 +542,9 @@ ...descriptor, }); - return new GPUCommandBuffer(descriptor.label); // TODO + const buffer = new GPUCommandBuffer(descriptor.label); + GPUCommandBufferMap.set(buffer, rid); + return buffer; } } @@ -589,7 +614,7 @@ executeBundles(bundles) { core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { renderPassRid: this.#rid, - bundles, + bundles: bundles.map((bundle) => GPURenderBundleMap.get(bundle)), }); } endPass() { @@ -742,6 +767,7 @@ } } + const GPUCommandBufferMap = new WeakMap(); class GPUCommandBuffer { constructor(label) { this.label = label ?? null; @@ -769,7 +795,9 @@ }, ); - return new GPURenderBundle(descriptor.label); + const bundle = new GPURenderBundle(descriptor.label); + GPURenderBundleMap.set(bundle, rid); + return bundle; } setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO @@ -840,6 +868,7 @@ drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer } + const GPURenderBundleMap = new WeakMap(); class GPURenderBundle { constructor(label) { this.label = label ?? null; From fbd21ab55aaf3eb8de90b93ed28ac0bc748bb9cb Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 21:00:15 +0200 Subject: [PATCH 014/144] buffer --- cli/ops/webgpu/binding.rs | 66 +++++---- cli/ops/webgpu/buffer.rs | 23 ++- cli/ops/webgpu/bundle.rs | 153 +++++++++++++++++++- cli/ops/webgpu/command_encoder.rs | 174 +++++++++++++++++++++- cli/ops/webgpu/compute_pass.rs | 32 +++++ cli/ops/webgpu/mod.rs | 62 +++++++- cli/ops/webgpu/queue.rs | 49 ++++++- cli/ops/webgpu/render_pass.rs | 143 ++++++++++++++++++ cli/ops/webgpu/sampler.rs | 2 +- cli/ops/webgpu/shader.rs | 2 +- cli/ops/webgpu/texture.rs | 4 +- cli/rt/14_webgpu.js | 231 +++++++++++++++++++++++++----- 12 files changed, 851 insertions(+), 90 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 3c1c275660d2a9..7b06da68c7cabe 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -141,7 +141,7 @@ pub fn op_webgpu_create_bind_group_layout( .collect::>(), ), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state @@ -196,7 +196,7 @@ pub fn op_webgpu_create_pipeline_layout( ), push_constant_ranges: Default::default(), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state @@ -212,8 +212,10 @@ pub fn op_webgpu_create_pipeline_layout( #[serde(rename_all = "camelCase")] struct GPUBindGroupEntry { binding: u32, - resource_kind: String, - resource: u32, // TODO: buffer + kind: String, + resource: u32, + offset: Option, + size: Option, } #[derive(Deserialize)] @@ -254,34 +256,42 @@ pub fn op_webgpu_create_bind_group( args .entries .iter() - .map(|entry| { - let resource = state - .resource_table - .get_mut(entry.resource) - .ok_or_else(bad_resource_id)?; - - wgc::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.resource_kind { - &"GPUSampler" => wgc::binding_model::BindingResource::Sampler( - *resource as wgc::id::SamplerId, - ), - &"GPUTextureView" => { - wgc::binding_model::BindingResource::TextureView( - *resource as wgc::id::TextureViewId, - ) - } - &"GPUBufferBinding" => { - wgc::binding_model::BindingResource::Buffer() // TODO: buffer - } - _ => unreachable!(), - }, - } + .map(|entry| wgc::binding_model::BindGroupEntry { + binding: entry.binding, + resource: match entry.resource_kind { + &"GPUSampler" => wgc::binding_model::BindingResource::Sampler( + *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + ), + &"GPUTextureView" => { + wgc::binding_model::BindingResource::TextureView( + *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + ) + } + &"GPUBufferBinding" => { + wgc::binding_model::BindingResource::Buffer( + wgc::binding_model::BufferBinding { + buffer_id: *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + offset: entry.offset.unwrap_or(0), + size: entry.size, + }, + ) + } + _ => unreachable!(), + }, }) .collect::>(), ), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 0008415b448edd..05a520095794cf 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -45,10 +45,10 @@ pub fn op_webgpu_create_buffer( &wgc::resource::BufferDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), size: args.size, - usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), // TODO: don't unwrap + usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); @@ -64,8 +64,8 @@ struct BufferGetMapAsyncArgs { instance_rid: u32, buffer_rid: u32, mode: u32, - offset: Option, - size: Option, + offset: u64, + size: u64, } pub async fn op_webgpu_buffer_get_map_async( @@ -87,7 +87,7 @@ pub async fn op_webgpu_buffer_get_map_async( instance.buffer_map_async( *buffer, - (), // TODO + args.offset..args.size, wgc::resource::BufferMapOperation { host: match args.mode { 1 => wgc::device::HostMap::Read, @@ -108,13 +108,13 @@ struct BufferGetMappedRangeArgs { instance_rid: u32, buffer_rid: u32, offset: u64, - size: Option, + size: std::num::NonZeroU64, } pub fn op_webgpu_buffer_get_mapped_range( state: &mut OpState, args: Value, - _zero_copy: &mut [ZeroCopyBuf], + zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; @@ -127,12 +127,9 @@ pub fn op_webgpu_buffer_get_mapped_range( .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let slice = instance.buffer_get_mapped_range( - // TODO: use - *buffer, - args.offset, - args.size, - )?; + // TODO: use + let slice_pointer = + instance.buffer_get_mapped_range(*buffer, args.offset, Some(args.size))?; Ok(json!({})) } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index fadf737ecfbd47..cf265d8dd8a4af 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -95,7 +95,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( &wgc::command::RenderBundleDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state @@ -233,6 +233,91 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderSetIndexBufferArgs { + render_bundle_encoder_rid: u32, + buffer: u32, + index_format: String, // wgpu#978 + offset: u64, + size: u64, +} + +pub fn op_webgpu_render_bundle_encoder_set_index_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderSetIndexBufferArgs = + serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::( + args.render_bundle_encoder_rid, + ) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_set_index_buffer( + render_bundle_encoder, + *state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?, + args.offset, + if args.size == 0 { + None + } else { + Some(args.size as std::num::NonZeroU64) // TODO: check + }, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderSetVertexBufferArgs { + render_bundle_encoder_rid: u32, + slot: u32, + buffer: u32, + offset: u64, + size: u64, +} + +pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderSetVertexBufferArgs = + serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::( + args.render_bundle_encoder_rid, + ) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( + render_bundle_encoder, + args.slot, + *state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?, + args.offset, + if args.size == 0 { + None + } else { + Some(args.size as std::num::NonZeroU64) // TODO: check + }, + ); + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderBundleEncoderDrawArgs { @@ -304,3 +389,69 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( Ok(json!({})) } + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderDrawIndirectArgs { + render_bundle_encoder_rid: u32, + indirect_buffer: u32, + indirect_offset: u64, +} + +pub fn op_webgpu_render_bundle_encoder_draw_indirect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderDrawIndirectArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::( + args.render_bundle_encoder_rid, + ) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_bundle_draw_indirect( + render_bundle_encoder, + *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?, + args.indirect_offset, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderDrawIndexedIndirectArgs { + render_pass_rid: u32, + indirect_buffer: u32, + indirect_offset: u64, +} + +pub fn op_webgpu_render_bundle_encoder_draw_indexed_indirect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::bundle_ffi::wgpu_render_pass_draw_indexed_indirect( + render_pass, + *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?, + args.indirect_offset, + ); + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 181eaa9e66b3a1..b9d6670cd01f30 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -43,7 +43,7 @@ pub fn op_webgpu_create_command_encoder( &wgt::CommandEncoderDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state @@ -190,6 +190,62 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( })) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderCopyBufferToBufferArgs { + instance_rid: u32, + command_encoder_rid: u32, + source: u32, + source_offset: u64, + destination: u32, + destination_offset: u64, + size: u64, +} + +pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderCopyBufferToBufferArgs = + serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_copy_buffer_to_buffer( + *command_encoder, + *state + .resource_table + .get_mut::(args.source) + .ok_or_else(bad_resource_id)?, + args.source_offset, + *state + .resource_table + .get_mut::(args.destination) + .ok_or_else(bad_resource_id)?, + args.destination_offset, + args.size, + )?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GPUBufferCopyView { + buffer: u32, + offset: Option, + bytes_per_row: Option, + rows_per_image: Option, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct GPUTextureCopyView { @@ -198,6 +254,122 @@ pub struct GPUTextureCopyView { pub origin: (), // TODO: mixed types } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderCopyBufferToTextureArgs { + instance_rid: u32, + command_encoder_rid: u32, + source: GPUBufferCopyView, + destination: GPUTextureCopyView, + copy_size: (), // TODO: mixed types +} + +pub fn op_webgpu_command_encoder_copy_buffer_to_texture( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderCopyBufferToTextureArgs = + serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_copy_buffer_to_texture( + *command_encoder, + &wgc::command::BufferCopyView { + buffer: *state + .resource_table + .get_mut::(args.source.buffer) + .ok_or_else(bad_resource_id)?, + layout: wgt::TextureDataLayout { + offset: args.source.offset.unwrap_or(0), + bytes_per_row: args.source.bytes_per_row, // TODO: default value? + rows_per_image: args.source.rows_per_image, // TODO: default value? + }, + }, + &wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: Default::default(), // TODO + }, + &wgt::Extent3d { + width: 0, // TODO + height: 0, // TODO + depth: 0, // TODO + }, + )?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderCopyTextureToBufferArgs { + instance_rid: u32, + command_encoder_rid: u32, + source: GPUTextureCopyView, + destination: GPUBufferCopyView, + copy_size: (), // TODO: mixed types +} + +pub fn op_webgpu_command_encoder_copy_texture_to_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderCopyTextureToBufferArgs = + serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = state + .resource_table + .get_mut::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + + instance.command_encoder_copy_texture_to_buffer( + *command_encoder, + &wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.source.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.source.mip_level.unwrap_or(0), + origin: Default::default(), // TODO + }, + &wgc::command::BufferCopyView { + buffer: *state + .resource_table + .get_mut::(args.destination.buffer) + .ok_or_else(bad_resource_id)?, + layout: wgt::TextureDataLayout { + offset: args.destination.offset.unwrap_or(0), + bytes_per_row: args.destination.bytes_per_row, // TODO: default value? + rows_per_image: args.destination.rows_per_image, // TODO: default value? + }, + }, + &wgt::Extent3d { + width: 0, // TODO + height: 0, // TODO + depth: 0, // TODO + }, + )?; + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyTextureToTextureArgs { diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index b35458751a4390..e5ae0573f0e4f2 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -72,6 +72,38 @@ pub fn op_webgpu_compute_pass_dispatch( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassDispatchIndirectArgs { + compute_pass_rid: u32, + indirect_buffer: u32, + indirect_offset: uu64, +} + +pub fn op_webgpu_compute_pass_dispatch_indirect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassDispatchIndirectArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( + compute_pass, + *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?, + args.indirect_offset, + ); + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassEndPassArgs { diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index d9f0f4444832fe..71ee3ca26c2de6 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -131,6 +131,21 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_command_encoder_begin_compute_pass", command_encoder::op_webgpu_command_encoder_begin_compute_pass, ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_buffer", + command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_texture", + command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_buffer", + command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, + ); super::reg_json_sync( rt, "op_webgpu_command_encoder_copy_texture_to_texture", @@ -207,6 +222,16 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pass_set_pipeline", render_pass::op_webgpu_render_pass_set_pipeline, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_index_buffer", + render_pass::op_webgpu_render_pass_set_index_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_vertex_buffer", + render_pass::op_webgpu_render_pass_set_vertex_buffer, + ); super::reg_json_sync( rt, "op_webgpu_render_pass_draw", @@ -217,6 +242,16 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pass_draw_indexed", render_pass::op_webgpu_render_pass_draw_indexed, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indirect", + render_pass::op_webgpu_render_pass_draw_indirect, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed_indirect", + render_pass::op_webgpu_render_pass_draw_indexed_indirect, + ); super::reg_json_sync( rt, @@ -228,6 +263,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_compute_pass_dispatch", compute_pass::op_webgpu_compute_pass_dispatch, ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch_indirect", + compute_pass::op_webgpu_compute_pass_dispatch_indirect, + ); super::reg_json_sync( rt, "op_webgpu_compute_pass_end_pass", @@ -279,6 +319,16 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_set_pipeline", bundle::op_webgpu_render_bundle_encoder_set_pipeline, ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_index_buffer", + bundle::op_webgpu_render_bundle_encoder_set_index_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_vertex_buffer", + bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer, + ); super::reg_json_sync( rt, "op_webgpu_render_bundle_encoder_draw", @@ -289,12 +339,22 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_draw_indexed", bundle::op_webgpu_render_bundle_encoder_draw_indexed, ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indirect", + bundle::op_webgpu_render_bundle_encoder_draw_indirect, + ); super::reg_json_sync( rt, "op_webgpu_queue_submit", queue::op_webgpu_queue_submit, ); + super::reg_json_sync( + rt, + "op_webgpu_write_buffer", + queue::op_webgpu_write_buffer, + ); super::reg_json_sync( rt, "op_webgpu_write_texture", @@ -471,7 +531,7 @@ pub async fn op_webgpu_request_device( shader_validation: false, // TODO }, None, - (), // TODO: id_in + std::marker::PhantomData, )?; let features = serialize_features(&instance.device_features(device)?); diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index e843c8ffada17a..ce381dbf74ce7c 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -61,13 +61,56 @@ struct GPUTextureDataLayout { rows_per_image: Option, } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct QueueWriteBufferArgs { + instance_rid: u32, + queue_rid: u32, + buffer: u32, + buffer_offset: u64, + data_offset: u64, + size: Option, +} + +pub fn op_webgpu_write_buffer( + state: &mut OpState, + args: Value, + zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: QueueWriteBufferArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let queue = state + .resource_table + .get_mut::(args.queue_rid) + .ok_or_else(bad_resource_id)?; + + instance.queue_write_buffer( + *queue, + *state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?, + args.buffer_offset, + &zero_copy[0][if let Some(size) = args.size { + args.data_offset..(args.data_offset + size) + } else { + args.data_offset.. + }], + )?; + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueWriteTextureArgs { instance_rid: u32, queue_rid: u32, destination: super::command_encoder::GPUTextureCopyView, - data: (), // TODO data_layout: GPUTextureDataLayout, size: (), // TODO: mixed types } @@ -75,7 +118,7 @@ struct QueueWriteTextureArgs { pub fn op_webgpu_write_texture( state: &mut OpState, args: Value, - _zero_copy: &mut [ZeroCopyBuf], + zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: QueueWriteTextureArgs = serde_json::from_value(args)?; @@ -98,7 +141,7 @@ pub fn op_webgpu_write_texture( mip_level: args.destination.mip_level.unwrap_or(0), origin: Default::default(), }, - (), + &zero_copy[0][..], &wgt::TextureDataLayout { offset: args.data_layout.offset.unwrap_or(0), bytes_per_row: args.data_layout.bytes_per_row, diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index f86c2bdf10407f..5f312fda558a21 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -327,6 +327,85 @@ pub fn op_webgpu_render_pass_set_pipeline( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetIndexBufferArgs { + render_pass_rid: u32, + buffer: u32, + index_format: String, // wgpu#978 + offset: u64, + size: u64, +} + +pub fn op_webgpu_render_pass_set_index_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetIndexBufferArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_index_buffer( + render_pass, + *state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?, + args.offset, + if args.size == 0 { + None + } else { + Some(args.size as std::num::NonZeroU64) // TODO: check + }, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetVertexBufferArgs { + render_pass_rid: u32, + slot: u32, + buffer: u32, + offset: u64, + size: u64, +} + +pub fn op_webgpu_render_pass_set_vertex_buffer( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetVertexBufferArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_set_vertex_buffer( + render_pass, + args.slot, + *state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?, + args.offset, + if args.size == 0 { + None + } else { + Some(args.size as std::num::NonZeroU64) // TODO: check + }, + ); + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassDrawArgs { @@ -394,3 +473,67 @@ pub fn op_webgpu_render_pass_draw_indexed( Ok(json!({})) } + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassDrawIndirectArgs { + render_pass_rid: u32, + indirect_buffer: u32, + indirect_offset: u64, +} + +pub fn op_webgpu_render_pass_draw_indirect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassDrawIndirectArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_draw_indirect( + render_pass, + *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?, + args.indirect_offset, + ); + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassDrawIndexedIndirectArgs { + render_pass_rid: u32, + indirect_buffer: u32, + indirect_offset: u64, +} + +pub fn op_webgpu_render_pass_draw_indexed_indirect( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + wgc::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( + render_pass, + *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?, + args.indirect_offset, + ); + + Ok(json!({})) +} diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index f333758d30fa08..f6b3bd555f7d05 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -97,7 +97,7 @@ pub fn op_webgpu_create_sampler( compare: args.compare.map(serialize_compare_function), anisotropy_clamp: args.max_anisotropy, }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index cb600c07a9d549..448b7ed412573a 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -41,7 +41,7 @@ pub fn op_webgpu_create_shader_module( let shader_module = instance.device_create_shader_module( *device, wgc::pipeline::ShaderModuleSource, // TODO - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index acf5487fea9c47..87a6b500e117aa 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -156,7 +156,7 @@ pub fn op_webgpu_create_texture( format: serialize_texture_format(args.format)?, usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), // TODO: don't unwrap }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); @@ -217,7 +217,7 @@ pub fn op_webgpu_create_texture_view( base_array_layer: args.base_array_layer.unwrap_or(0), array_layer_count: args.array_layer_count, }, - (), // TODO: id_in + std::marker::PhantomData, )?; let rid = state diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 8e8ce3609e0874..ce032f01264b10 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -76,7 +76,7 @@ this.#rid = rid; this.#features = Object.freeze(data.features); this.#limits = data.limits; - this.#defaultQueue = new GPUQueue(); // TODO + this.#defaultQueue = new GPUQueue(rid); // TODO: label? } createBuffer(descriptor) { @@ -86,7 +86,9 @@ ...descriptor, }); - return new GPUBuffer(rid, descriptor.label); + const buffer = new GPUBuffer(rid, descriptor.label, descriptor.size); + GPUBufferMap.set(buffer, rid); + return buffer; } createTexture(descriptor) { @@ -96,7 +98,9 @@ ...descriptor, }); - return new GPUTexture(rid, descriptor.label); + const texture = new GPUTexture(rid, descriptor.label); + GPUTextureMap.set(texture, rid); + return texture; } createSampler(descriptor = {}) { @@ -156,7 +160,12 @@ resource: GPUTextureViewMap.get(entry), }; } else { - // TODO: buffer + return { + kind: "GPUBuffer", + resource: GPUBufferMap.get(entry.buffer), + offset: entry.offset, + size: entry.size, + }; } }), }); @@ -244,7 +253,9 @@ } class GPUQueue { - constructor(label) { + #rid; + constructor(rid, label) { + this.#rid = rid; this.label = label ?? null; } @@ -261,17 +272,33 @@ throw new Error("Not yet implemented"); } - writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) {} // TODO: buffer + writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { + core.jsonOpSync( + "op_webgpu_write_texture", + { + instanceRid, + queueRid: this.#rid, + buffer: GPUBufferMap.get(buffer), + bufferOffset, + dataOffset, + size, + }, + data, + ); + } writeTexture(destination, data, dataLayout, size) { - core.jsonOpSync("op_webgpu_write_texture", { - instanceRid, - queueRid: this.#rid, - destination, + core.jsonOpSync( + "op_webgpu_write_texture", + { + instanceRid, + queueRid: this.#rid, + destination, + dataLayout, + size, + }, data, - dataLayout, - size, - }); + ); } copyImageBitmapToTexture(source, destination, copySize) { @@ -280,31 +307,45 @@ } // TODO: https://gpuweb.github.io/gpuweb/#buffer-interface + const GPUBufferMap = new WeakMap(); class GPUBuffer { #rid; + #size; + #mappedSize; // TODO: is this OK? - constructor(rid, label) { + constructor(rid, label, size) { this.#rid = rid; this.label = label ?? null; + this.#size = size; } async mapAsync(mode, offset = 0, size = undefined) { + this.#mappedSize = size ?? this.#size; // TODO: is this OK? await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { instanceRid, bufferRid: this.#rid, mode, offset, - size, - }); + size: this.#mappedSize, + } // TODO: is this OK? + ); } getMappedRange(offset = 0, size = undefined) { - core.jsonOpSync("op_webgpu_buffer_get_mapped_range", { - instanceRid, - bufferRid: this.#rid, - offset, - size, - }); + const buf = new ArrayBuffer(size ?? this.#mappedSize); // TODO: is this OK? + + core.jsonOpSync( + "op_webgpu_buffer_get_mapped_range", + { + instanceRid, + bufferRid: this.#rid, + offset, + size, + }, + buf, + ); + + return buf; } unmap() { @@ -315,10 +356,11 @@ } destroy() { - throw new Error("Not yet implemented"); // master + throw new Error("Not yet implemented"); // wgpu master } } + const GPUTextureMap = new WeakMap(); class GPUTexture { #rid; constructor(rid, label) { @@ -339,7 +381,7 @@ } destroy() { - throw new Error("Not yet implemented"); // master + throw new Error("Not yet implemented"); // wgpu master } } @@ -481,20 +523,73 @@ destination, destinationOffset, size, - ) {} // TODO: buffer + ) { + core.jsonOpSync( + "op_webgpu_command_encoder_copy_buffer_to_buffer", + { + instanceRid, + commandEncoderRid: this.#rid, + source: GPUBufferMap.get(source), + sourceOffset, + destination: GPUBufferMap.get(destination), + destinationOffset, + size, + }, + ); + } - copyBufferToTexture(source, destination, copySize) {} // TODO: buffer + copyBufferToTexture(source, destination, copySize) { + core.jsonOpSync( + "op_webgpu_command_encoder_copy_buffer_to_texture", + { + instanceRid, + commandEncoderRid: this.#rid, + source: { + ...source, // TODO: check + buffer: GPUBufferMap.get(source.buffer), + }, + destination: { + ...destination, // TODO: check + texture: GPUTextureMap.get(destination.texture), + }, + copySize, + }, + ); + } - copyTextureToBuffer(source, destination, copySize) {} // TODO: buffer + copyTextureToBuffer(source, destination, copySize) { + core.jsonOpSync( + "op_webgpu_command_encoder_copy_texture_to_buffer", + { + instanceRid, + commandEncoderRid: this.#rid, + source: { + ...source, // TODO: check + texture: GPUTextureMap.get(source.texture), + }, + destination: { + ...destination, // TODO: check + buffer: GPUBufferMap.get(destination.buffer), + }, + copySize, + }, + ); + } copyTextureToTexture(source, destination, copySize) { - const { rid } = core.jsonOpSync( + core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { instanceRid, commandEncoderRid: this.#rid, - source, - destination, + source: { + ...source, // TODO: check + texture: GPUTextureMap.get(source.texture), + }, + destination: { + ...destination, // TODO: check + texture: GPUTextureMap.get(destination.texture), + }, copySize, }, ); @@ -660,8 +755,24 @@ }); } - setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO: buffer - setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO: buffer + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + core.jsonOpSync("op_webgpu_render_pass_set_index_buffer", { + renderPassRid: this.#rid, + buffer: GPUBufferMap.get(buffer), + indexFormat, + offset, + size, + }); + } + setVertexBuffer(slot, buffer, offset = 0, size = 0) { + core.jsonOpSync("op_webgpu_render_pass_set_vertex_buffer", { + renderPassRid: this.#rid, + slot, + buffer: GPUBufferMap.get(buffer), + offset, + size, + }); + } draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { core.jsonOpSync("op_webgpu_render_pass_draw", { @@ -689,8 +800,20 @@ }); } - drawIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer - drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer + drawIndirect(indirectBuffer, indirectOffset) { + core.jsonOpSync("op_webgpu_render_pass_draw_indirect", { + renderPassRid: this.#rid, + indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectOffset, + }); + } + drawIndexedIndirect(indirectBuffer, indirectOffset) { + core.jsonOpSync("op_webgpu_render_pass_draw_indexed_indirect", { + renderPassRid: this.#rid, + indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectOffset, + }); + } } class GPUComputePassEncoder { @@ -717,7 +840,13 @@ z, }); } - dispatchIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer + dispatchIndirect(indirectBuffer, indirectOffset) { + core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { + computePassRid: this.#rid, + indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectOffset, + }); + } beginPipelineStatisticsQuery(querySet, queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 @@ -835,8 +964,24 @@ }); } - setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {} // TODO: buffer - setVertexBuffer(slot, buffer, offset = 0, size = 0) {} // TODO: buffer + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { + renderBundleEncoderRid: this.#rid, + buffer: GPUBufferMap.get(buffer), + indexFormat, + offset, + size, + }); + } + setVertexBuffer(slot, buffer, offset = 0, size = 0) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { + renderBundleEncoderRid: this.#rid, + slot, + buffer: GPUBufferMap.get(buffer), + offset, + size, + }); + } draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { core.jsonOpSync("op_webgpu_render_bundle_encoder_draw", { @@ -864,8 +1009,16 @@ }); } - drawIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer - drawIndexedIndirect(indirectBuffer, indirectOffset) {} // TODO: buffer + drawIndirect(indirectBuffer, indirectOffset) { + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { + renderBundleEncoderRid: this.#rid, + indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectOffset, + }); + } + drawIndexedIndirect(indirectBuffer, indirectOffset) { + throw new Error("Not yet implemented"); + } } const GPURenderBundleMap = new WeakMap(); From 39cb0eab4fc1fb9d8461add20eac17d45bbeeb83 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 22:41:18 +0200 Subject: [PATCH 015/144] setBindGroup --- cli/ops/webgpu/binding.rs | 18 +++--- cli/ops/webgpu/bundle.rs | 47 +++++++++++++++ cli/ops/webgpu/compute_pass.rs | 47 +++++++++++++++ cli/ops/webgpu/mod.rs | 21 +++++++ cli/ops/webgpu/queue.rs | 2 +- cli/ops/webgpu/render_pass.rs | 47 +++++++++++++++ cli/ops/webgpu/shader.rs | 18 ++++-- cli/rt/14_webgpu.js | 103 ++++++++++++++++++++++++++++----- 8 files changed, 274 insertions(+), 29 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 7b06da68c7cabe..f8e53225fa80ae 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -77,7 +77,7 @@ pub fn op_webgpu_create_bind_group_layout( wgt::BindGroupLayoutEntry { binding: entry.binding, visibility: wgt::ShaderStage::from_bits(entry.visibility) - .unwrap(), // TODO: dont unwrap + .unwrap(), ty: match entry.kind { &"uniform-buffer" => wgt::BindingType::UniformBuffer { dynamic: entry.has_dynamic_offset.unwrap_or(false), @@ -98,26 +98,26 @@ pub fn op_webgpu_create_bind_group_layout( wgt::BindingType::Sampler { comparison: true } } &"sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO: dont unwrap + dimension: serialize_dimension(entry.view_dimension.unwrap()), component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), // TODO: dont unwrap + entry.texture_component_type.unwrap(), )?, multisampled: false, }, &"multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), // TODO: dont unwrap + dimension: serialize_dimension(entry.view_dimension.unwrap()), component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), // TODO: dont unwrap + entry.texture_component_type.unwrap(), )?, multisampled: true, }, &"readonly-storage-texture" => { wgt::BindingType::StorageTexture { dimension: serialize_dimension( - entry.view_dimension.unwrap(), // TODO: dont unwrap + entry.view_dimension.unwrap(), ), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), // TODO: dont unwrap + entry.storage_texture_format.unwrap(), )?, readonly: true, } @@ -125,10 +125,10 @@ pub fn op_webgpu_create_bind_group_layout( &"writeonly-storage-texture" => { wgt::BindingType::StorageTexture { dimension: serialize_dimension( - entry.view_dimension.unwrap(), // TODO: dont unwrap + entry.view_dimension.unwrap(), ), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), // TODO: dont unwrap + entry.storage_texture_format.unwrap(), )?, readonly: false, } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index cf265d8dd8a4af..3958fea5b02caa 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -107,6 +107,53 @@ pub fn op_webgpu_render_bundle_encoder_finish( })) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderBundleEncoderSetBindGroupArgs { + render_bundle_encoder_rid: u32, + index: u32, + bind_group: u32, + dynamic_offsets_data: Option<[u32]>, + dynamic_offsets_data_start: u64, + dynamic_offsets_data_length: usize, +} + +pub fn op_webgpu_render_bundle_encoder_set_bind_group( + state: &mut OpState, + args: Value, + zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderBundleEncoderSetBindGroupArgs = serde_json::from_value(args)?; + + let render_bundle_encoder = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + render_bundle_encoder, + args.index, + *state + .resource_table + .get_mut::(args.bind_group) + .ok_or_else(bad_resource_id)?, + match args.dynamic_offsets_data { + Some(data) => data.as_ptr(), + None => unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data[args.dynamic_offsets_data_start..].as_ptr() + } + }, + args.dynamic_offsets_data_length, + ); + } + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderBundleEncoderPushDebugGroupArgs { diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index e5ae0573f0e4f2..f50cb6923e9c2f 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -137,6 +137,53 @@ pub fn op_webgpu_compute_pass_end_pass( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassSetBindGroupArgs { + compute_pass_rid: u32, + index: u32, + bind_group: u32, + dynamic_offsets_data: Option<[u32]>, + dynamic_offsets_data_start: u64, + dynamic_offsets_data_length: usize, +} + +pub fn op_webgpu_compute_pass_set_bind_group( + state: &mut OpState, + args: Value, + zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassSetBindGroupArgs = serde_json::from_value(args)?; + + let compute_pass = state + .resource_table + .get_mut::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::compute_ffi::wgpu_compute_pass_set_bind_group( + compute_pass, + args.index, + *state + .resource_table + .get_mut::(args.bind_group) + .ok_or_else(bad_resource_id)?, + match args.dynamic_offsets_data { + Some(data) => data.as_ptr(), + None => unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data[args.dynamic_offsets_data_start..].as_ptr() + } + }, + args.dynamic_offsets_data_length, + ); + } + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassPushDebugGroupArgs { diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 71ee3ca26c2de6..b383e81f8ea11e 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -202,6 +202,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pass_end_pass", render_pass::op_webgpu_render_pass_end_pass, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_bind_group", + render_pass::op_webgpu_render_pass_set_bind_group, + ); super::reg_json_sync( rt, "op_webgpu_render_pass_push_debug_group", @@ -273,6 +278,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_compute_pass_end_pass", compute_pass::op_webgpu_compute_pass_end_pass, ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_bind_group", + compute_pass::op_webgpu_compute_pass_set_bind_group, + ); super::reg_json_sync( rt, "op_webgpu_compute_pass_push_debug_group", @@ -299,6 +309,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_finish", bundle::op_webgpu_render_bundle_encoder_finish, ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_bind_group", + bundle::op_webgpu_render_bundle_encoder_set_bind_group, + ); super::reg_json_sync( rt, "op_webgpu_render_bundle_encoder_push_debug_group", @@ -360,6 +375,12 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_write_texture", queue::op_webgpu_write_texture, ); + + super::reg_json_sync( + rt, + "op_webgpu_create_shader_module", + shader::op_webgpu_create_shader_module, + ); } fn serialize_features(features: &wgt::Features) -> Vec<&str> { diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index ce381dbf74ce7c..8cc68ab8892659 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -141,7 +141,7 @@ pub fn op_webgpu_write_texture( mip_level: args.destination.mip_level.unwrap_or(0), origin: Default::default(), }, - &zero_copy[0][..], + &*zero_copy[0], &wgt::TextureDataLayout { offset: args.data_layout.offset.unwrap_or(0), bytes_per_row: args.data_layout.bytes_per_row, diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 5f312fda558a21..95db4843c08e82 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -214,6 +214,53 @@ pub fn op_webgpu_render_pass_end_pass( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassSetBindGroupArgs { + render_pass_rid: u32, + index: u32, + bind_group: u32, + dynamic_offsets_data: Option<[u32]>, + dynamic_offsets_data_start: u64, + dynamic_offsets_data_length: usize, +} + +pub fn op_webgpu_render_pass_set_bind_group( + state: &mut OpState, + args: Value, + zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassSetBindGroupArgs = serde_json::from_value(args)?; + + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgc::command::render_ffi::wgpu_render_pass_set_bind_group( + render_pass, + args.index, + *state + .resource_table + .get_mut::(args.bind_group) + .ok_or_else(bad_resource_id)?, + match args.dynamic_offsets_data { + Some(data) => data.as_ptr(), + None => unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data[args.dynamic_offsets_data_start..].as_ptr() + } + }, + args.dynamic_offsets_data_length, + ); + } + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassPushDebugGroupArgs { diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 448b7ed412573a..e919382fd7d347 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -11,6 +11,8 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; +use std::borrow::Cow; +use std::ops::Deref; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -18,14 +20,14 @@ struct CreateShaderModuleArgs { instance_rid: u32, device_rid: u32, label: Option, // wgpu#977 - code: String, - source_map: (), // TODO: https://gpuweb.github.io/gpuweb/#shader-module-creation + code: Option, + source_map: (), // not in wgpu } pub fn op_webgpu_create_shader_module( state: &mut OpState, args: Value, - _zero_copy: &mut [ZeroCopyBuf], + zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: CreateShaderModuleArgs = serde_json::from_value(args)?; @@ -40,7 +42,15 @@ pub fn op_webgpu_create_shader_module( let shader_module = instance.device_create_shader_module( *device, - wgc::pipeline::ShaderModuleSource, // TODO + match args.code { + Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), + None => wgc::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data + })), + }, std::marker::PhantomData, )?; diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index ce032f01264b10..827bd8251144b8 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -176,11 +176,16 @@ } createShaderModule(descriptor) { - const { rid } = core.jsonOpSync("op_webgpu_create_shader_module", { - instanceRid, - deviceRid: this.#rid, - ...descriptor, - }); + const { rid } = core.jsonOpSync( + "op_webgpu_create_shader_module", + { + instanceRid, + deviceRid: this.#rid, + label: descriptor.label, + code: (typeof descriptor.code === "string") && descriptor.code, + }, + (descriptor.code instanceof Uint32Array) && descriptor.code, + ); const shaderModule = new GPUShaderModule(rid, descriptor.label); GPUShaderModuleMap.set(shaderModule, rid); @@ -306,7 +311,6 @@ } } - // TODO: https://gpuweb.github.io/gpuweb/#buffer-interface const GPUBufferMap = new WeakMap(); class GPUBuffer { #rid; @@ -720,15 +724,38 @@ }); } - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup( index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength, - ) {} // TODO + ) { + const bind = GPUBindGroupMap.get(bindGroup); + if (dynamicOffsetsData instanceof Uint32Array) { + core.jsonOpSync( + "op_webgpu_render_pass_set_bind_group", + { + renderPassRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }, + dynamicOffsetsData, + ); + } else { + dynamicOffsetsData ??= []; + core.jsonOpSync("op_webgpu_render_pass_set_bind_group", { + renderPassRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsData, + dynamicOffsetsDataStart: 0, + dynamicOffsetsDataLength: dynamicOffsetsData.length, + }); + } + } pushDebugGroup(groupLabel) { core.jsonOpSync("op_webgpu_render_pass_push_debug_group", { @@ -867,15 +894,38 @@ }); } - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup( index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength, - ) {} // TODO + ) { + const bind = GPUBindGroupMap.get(bindGroup); + if (dynamicOffsetsData instanceof Uint32Array) { + core.jsonOpSync( + "op_webgpu_compute_pass_set_bind_group", + { + computePassRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }, + dynamicOffsetsData, + ); + } else { + dynamicOffsetsData ??= []; + core.jsonOpSync("op_webgpu_compute_pass_set_bind_group", { + computePassRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsData, + dynamicOffsetsDataStart: 0, + dynamicOffsetsDataLength: dynamicOffsetsData.length, + }); + } + } pushDebugGroup(groupLabel) { core.jsonOpSync("op_webgpu_compute_pass_push_debug_group", { @@ -929,15 +979,38 @@ return bundle; } - setBindGroup(index, bindGroup, dynamicOffsets = []) {} // TODO - setBindGroup( index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength, - ) {} // TODO + ) { + const bind = GPUBindGroupMap.get(bindGroup); + if (dynamicOffsetsData instanceof Uint32Array) { + core.jsonOpSync( + "op_webgpu_render_bundle_encoder_set_bind_group", + { + renderBundleEncoderRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }, + dynamicOffsetsData, + ); + } else { + dynamicOffsetsData ??= []; + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_bind_group", { + renderBundleEncoderRid: this.#rid, + index, + bindGroup: bind, + dynamicOffsetsData, + dynamicOffsetsDataStart: 0, + dynamicOffsetsDataLength: dynamicOffsetsData.length, + }); + } + } pushDebugGroup(groupLabel) { core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { From 5aeca9489fe279db6437913537120ed71dcd2598 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 13 Oct 2020 23:14:43 +0200 Subject: [PATCH 016/144] split up init --- cli/ops/webgpu/binding.rs | 6 + cli/ops/webgpu/buffer.rs | 7 + cli/ops/webgpu/bundle.rs | 16 ++ cli/ops/webgpu/command_encoder.rs | 14 ++ cli/ops/webgpu/compute_pass.rs | 11 + cli/ops/webgpu/mod.rs | 351 +----------------------------- cli/ops/webgpu/pipeline.rs | 7 + cli/ops/webgpu/queue.rs | 6 + cli/ops/webgpu/render_pass.rs | 20 ++ cli/ops/webgpu/sampler.rs | 4 + cli/ops/webgpu/shader.rs | 4 + cli/ops/webgpu/texture.rs | 5 + 12 files changed, 111 insertions(+), 340 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index f8e53225fa80ae..81c2c45232119d 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -14,6 +14,12 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_bind_group_layout", op_webgpu_create_bind_group_layout); + super::super::reg_json_sync(rt, "op_webgpu_create_pipeline_layout", op_webgpu_create_pipeline_layout); + super::super::reg_json_sync(rt, "op_webgpu_create_bind_group", op_webgpu_create_bind_group); +} + fn serialize_texture_component_type( component_type: String, ) -> Result { diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 05a520095794cf..1420eca3216ebf 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -13,6 +13,13 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_buffer", op_webgpu_create_buffer); + super::super::reg_json_sync(rt, "op_webgpu_buffer_get_map_async", op_webgpu_buffer_get_map_async); + super::super::reg_json_sync(rt, "op_webgpu_buffer_get_mapped_range", op_webgpu_buffer_get_mapped_range); + super::super::reg_json_sync(rt, "op_webgpu_buffer_unmap", op_webgpu_buffer_unmap); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBufferArgs { diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 3958fea5b02caa..1fd7ac478fd467 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -14,6 +14,22 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_render_bundle_encoder", op_webgpu_create_render_bundle_encoder); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_finish", op_webgpu_render_bundle_encoder_finish); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_bind_group", op_webgpu_render_bundle_encoder_set_bind_group); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_push_debug_group", op_webgpu_render_bundle_encoder_push_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_pop_debug_group", op_webgpu_render_bundle_encoder_pop_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_insert_debug_marker", op_webgpu_render_bundle_encoder_insert_debug_marker); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_pipeline", op_webgpu_render_bundle_encoder_set_pipeline); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_index_buffer", op_webgpu_render_bundle_encoder_set_index_buffer); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_vertex_buffer", op_webgpu_render_bundle_encoder_set_vertex_buffer); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw", op_webgpu_render_bundle_encoder_draw); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indexed", op_webgpu_render_bundle_encoder_draw_indexed); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indirect", op_webgpu_render_bundle_encoder_draw_indirect); + super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indexed_indirect", op_webgpu_render_bundle_encoder_draw_indexed_indirect); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderBundleEncoderArgs { diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index b9d6670cd01f30..73a9fd848f38cc 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -13,6 +13,20 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_command_encoder", op_webgpu_create_command_encoder); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_begin_render_pass", op_webgpu_command_encoder_begin_render_pass); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_begin_compute_pass", op_webgpu_command_encoder_begin_compute_pass); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_buffer_to_buffer", op_webgpu_command_encoder_copy_buffer_to_buffer); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_buffer_to_texture", op_webgpu_command_encoder_copy_buffer_to_texture); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_texture_to_buffer", op_webgpu_command_encoder_copy_texture_to_buffer); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_texture_to_texture", op_webgpu_command_encoder_copy_texture_to_texture); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_push_debug_group", op_webgpu_command_encoder_push_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_pop_debug_group", op_webgpu_command_encoder_pop_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_insert_debug_marker", op_webgpu_command_encoder_insert_debug_marker); + super::super::reg_json_sync(rt, "op_webgpu_command_encoder_finish", op_webgpu_command_encoder_finish); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateCommandEncoderArgs { diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index f50cb6923e9c2f..c93bfb645f156b 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -11,6 +11,17 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_set_pipeline", op_webgpu_compute_pass_set_pipeline); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_dispatch", op_webgpu_compute_pass_dispatch); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_dispatch_indirect", op_webgpu_compute_pass_dispatch_indirect); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_end_pass", op_webgpu_compute_pass_end_pass); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_set_bind_group", op_webgpu_compute_pass_set_bind_group); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_push_debug_group", op_webgpu_compute_pass_push_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_pop_debug_group", op_webgpu_compute_pass_pop_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_compute_pass_insert_debug_marker", op_webgpu_compute_pass_insert_debug_marker); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassSetPipelineArgs { diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index b383e81f8ea11e..2551960f898d5c 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -41,346 +41,17 @@ pub fn init(rt: &mut deno_core::JsRuntime) { op_webgpu_request_device, ); - super::reg_json_sync( - rt, - "op_webgpu_create_buffer", - buffer::op_webgpu_create_buffer, - ); - super::reg_json_async( - rt, - "op_webgpu_buffer_get_map_async", - buffer::op_webgpu_buffer_get_map_async, - ); - super::reg_json_async( - rt, - "op_webgpu_buffer_get_mapped_range", - buffer::op_webgpu_buffer_get_mapped_range, - ); - super::reg_json_sync( - rt, - "op_webgpu_buffer_unmap", - buffer::op_webgpu_buffer_unmap, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_texture", - texture::op_webgpu_create_texture, - ); - super::reg_json_sync( - rt, - "op_webgpu_create_texture_view", - texture::op_webgpu_create_texture_view, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_sampler", - sampler::op_webgpu_create_sampler, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_bind_group_layout", - binding::op_webgpu_create_bind_group_layout, - ); - super::reg_json_sync( - rt, - "op_webgpu_create_pipeline_layout", - binding::op_webgpu_create_pipeline_layout, - ); - super::reg_json_sync( - rt, - "op_webgpu_create_bind_group", - binding::op_webgpu_create_bind_group, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_compute_pipeline", - pipeline::op_webgpu_create_compute_pipeline, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pipeline_get_bind_group_layout", - pipeline::op_webgpu_compute_pipeline_get_bind_group_layout, - ); - super::reg_json_sync( - rt, - "op_webgpu_create_render_pipeline", - pipeline::op_webgpu_create_render_pipeline, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pipeline_get_bind_group_layout", - pipeline::op_webgpu_render_pipeline_get_bind_group_layout, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_command_encoder", - command_encoder::op_webgpu_create_command_encoder, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_begin_render_pass", - command_encoder::op_webgpu_command_encoder_begin_render_pass, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_begin_compute_pass", - command_encoder::op_webgpu_command_encoder_begin_compute_pass, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_buffer", - command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_texture", - command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_buffer", - command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_texture", - command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_push_debug_group", - command_encoder::op_webgpu_command_encoder_push_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_pop_debug_group", - command_encoder::op_webgpu_command_encoder_pop_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_insert_debug_marker", - command_encoder::op_webgpu_command_encoder_insert_debug_marker, - ); - super::reg_json_sync( - rt, - "op_webgpu_command_encoder_finish", - command_encoder::op_webgpu_command_encoder_finish, - ); - - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_viewport", - render_pass::op_webgpu_render_pass_set_viewport, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_scissor_rect", - render_pass::op_webgpu_render_pass_set_scissor_rect, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_blend_color", - render_pass::op_webgpu_render_pass_set_blend_color, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_stencil_reference", - render_pass::op_webgpu_render_pass_set_stencil_reference, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_execute_bundles", - render_pass::op_webgpu_render_pass_execute_bundles, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_end_pass", - render_pass::op_webgpu_render_pass_end_pass, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_bind_group", - render_pass::op_webgpu_render_pass_set_bind_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_push_debug_group", - render_pass::op_webgpu_render_pass_push_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_pop_debug_group", - render_pass::op_webgpu_render_pass_pop_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_insert_debug_marker", - render_pass::op_webgpu_render_pass_insert_debug_marker, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_pipeline", - render_pass::op_webgpu_render_pass_set_pipeline, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_index_buffer", - render_pass::op_webgpu_render_pass_set_index_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_vertex_buffer", - render_pass::op_webgpu_render_pass_set_vertex_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw", - render_pass::op_webgpu_render_pass_draw, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indexed", - render_pass::op_webgpu_render_pass_draw_indexed, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indirect", - render_pass::op_webgpu_render_pass_draw_indirect, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indexed_indirect", - render_pass::op_webgpu_render_pass_draw_indexed_indirect, - ); - - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_set_pipeline", - compute_pass::op_webgpu_compute_pass_set_pipeline, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_dispatch", - compute_pass::op_webgpu_compute_pass_dispatch, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_dispatch_indirect", - compute_pass::op_webgpu_compute_pass_dispatch_indirect, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_end_pass", - compute_pass::op_webgpu_compute_pass_end_pass, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_set_bind_group", - compute_pass::op_webgpu_compute_pass_set_bind_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_push_debug_group", - compute_pass::op_webgpu_compute_pass_push_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_pop_debug_group", - compute_pass::op_webgpu_compute_pass_pop_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_compute_pass_insert_debug_marker", - compute_pass::op_webgpu_compute_pass_insert_debug_marker, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_render_bundle_encoder", - bundle::op_webgpu_create_render_bundle_encoder, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_finish", - bundle::op_webgpu_render_bundle_encoder_finish, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_bind_group", - bundle::op_webgpu_render_bundle_encoder_set_bind_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_push_debug_group", - bundle::op_webgpu_render_bundle_encoder_push_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_pop_debug_group", - bundle::op_webgpu_render_bundle_encoder_pop_debug_group, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_insert_debug_marker", - bundle::op_webgpu_render_bundle_encoder_insert_debug_marker, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_pipeline", - bundle::op_webgpu_render_bundle_encoder_set_pipeline, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_index_buffer", - bundle::op_webgpu_render_bundle_encoder_set_index_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_vertex_buffer", - bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw", - bundle::op_webgpu_render_bundle_encoder_draw, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indexed", - bundle::op_webgpu_render_bundle_encoder_draw_indexed, - ); - super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indirect", - bundle::op_webgpu_render_bundle_encoder_draw_indirect, - ); - - super::reg_json_sync( - rt, - "op_webgpu_queue_submit", - queue::op_webgpu_queue_submit, - ); - super::reg_json_sync( - rt, - "op_webgpu_write_buffer", - queue::op_webgpu_write_buffer, - ); - super::reg_json_sync( - rt, - "op_webgpu_write_texture", - queue::op_webgpu_write_texture, - ); - - super::reg_json_sync( - rt, - "op_webgpu_create_shader_module", - shader::op_webgpu_create_shader_module, - ); + buffer::init(rt); + texture::init(rt); + sampler::init(rt); + binding::init(rt); + pipeline::init(rt); + command_encoder::init(rt); + render_pass::init(rt); + compute_pass::init(rt); + bundle::init(rt); + queue::init(rt); + shader::init(rt); } fn serialize_features(features: &wgt::Features) -> Vec<&str> { diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 1d6a2c68120825..7f9d303c2970a5 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -15,6 +15,13 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_compute_pipeline", op_webgpu_create_compute_pipeline); + super::super::reg_json_sync(rt, "op_webgpu_compute_pipeline_get_bind_group_layout", op_webgpu_compute_pipeline_get_bind_group_layout); + super::super::reg_json_sync(rt, "op_webgpu_create_render_pipeline", op_webgpu_create_render_pipeline); + super::super::reg_json_sync(rt, "op_webgpu_render_pipeline_get_bind_group_layout", op_webgpu_render_pipeline_get_bind_group_layout); +} + fn serialize_programmable_stage_descriptor( state: &mut OpState, programmable_stage_descriptor: GPUProgrammableStageDescriptor, diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index 8cc68ab8892659..ead35ffea9200d 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -12,6 +12,12 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_queue_submit", op_webgpu_queue_submit); + super::super::reg_json_sync(rt, "op_webgpu_write_buffer", op_webgpu_write_buffer); + super::super::reg_json_sync(rt, "op_webgpu_write_texture", op_webgpu_write_texture); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueSubmitArgs { diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 95db4843c08e82..b599b998d79a11 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -11,6 +11,26 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_viewport", op_webgpu_render_pass_set_viewport); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_scissor_rect", op_webgpu_render_pass_set_scissor_rect); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_blend_color", op_webgpu_render_pass_set_blend_color); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_stencil_reference", op_webgpu_render_pass_set_stencil_reference); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_execute_bundles", op_webgpu_render_pass_execute_bundles); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_end_pass", op_webgpu_render_pass_end_pass); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_bind_group", op_webgpu_render_pass_set_bind_group); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_push_debug_group", op_webgpu_render_pass_push_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_pop_debug_group", op_webgpu_render_pass_pop_debug_group); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_insert_debug_marker", op_webgpu_render_pass_insert_debug_marker); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_pipeline", op_webgpu_render_pass_set_pipeline); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_index_buffer", op_webgpu_render_pass_set_index_buffer); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_vertex_buffer", op_webgpu_render_pass_set_vertex_buffer); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw", op_webgpu_render_pass_draw); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indexed", op_webgpu_render_pass_draw_indexed); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indirect", op_webgpu_render_pass_draw_indirect); + super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indexed_indirect", op_webgpu_render_pass_draw_indexed_indirect); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassSetViewportArgs { diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index f6b3bd555f7d05..5415ac4b811e42 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -13,6 +13,10 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_sampler", op_webgpu_create_sampler); +} + fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { match address_mode { Some(&"clamp-to-edge") => wgt::AddressMode::ClampToEdge, diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index e919382fd7d347..ee614b6ff91fa3 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -14,6 +14,10 @@ use std::rc::Rc; use std::borrow::Cow; use std::ops::Deref; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_shader_module", op_webgpu_create_shader_module); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateShaderModuleArgs { diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 87a6b500e117aa..09518a6aa4cee4 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -13,6 +13,11 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub fn init(rt: &mut deno_core::JsRuntime) { + super::super::reg_json_sync(rt, "op_webgpu_create_texture", op_webgpu_create_texture); + super::super::reg_json_sync(rt, "op_webgpu_create_texture_view", op_webgpu_create_texture_view); +} + pub fn serialize_texture_format( format: String, ) -> Result { From 28d1f965180aeb383687b9f95d5cb5419f881019 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 14 Oct 2020 07:21:41 +0200 Subject: [PATCH 017/144] cleanup --- cli/ops/webgpu/bundle.rs | 6 +- cli/ops/webgpu/command_encoder.rs | 99 ++++++++++++++++++++++++------- cli/ops/webgpu/mod.rs | 2 +- cli/ops/webgpu/pipeline.rs | 27 +++++---- cli/ops/webgpu/queue.rs | 25 ++++---- cli/ops/webgpu/render_pass.rs | 24 +++++--- cli/ops/webgpu/sampler.rs | 2 +- cli/ops/webgpu/texture.rs | 18 +++++- cli/rt/14_webgpu.js | 70 ++++++++++++++++++---- 9 files changed, 202 insertions(+), 71 deletions(-) diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 1fd7ac478fd467..5a4f7e7f2451cf 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -68,7 +68,7 @@ pub fn op_webgpu_create_render_bundle_encoder( sample_count: args.sample_count.unwrap_or(1), }, *device, - None, // TODO: check what this is + None, )?; let rid = state @@ -331,7 +331,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( if args.size == 0 { None } else { - Some(args.size as std::num::NonZeroU64) // TODO: check + Some(args.size as std::num::NonZeroU64) }, ); @@ -374,7 +374,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( if args.size == 0 { None } else { - Some(args.size as std::num::NonZeroU64) // TODO: check + Some(args.size as std::num::NonZeroU64) }, ); diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 73a9fd848f38cc..3ce0872b1d6f33 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -27,6 +27,14 @@ pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync(rt, "op_webgpu_command_encoder_finish", op_webgpu_command_encoder_finish); } +fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { + match store_op { + &"store" => wgc::command::StoreOp::Store, + &"clear" => wgc::command::StoreOp::Clear, + _ => unreachable!(), + } +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateCommandEncoderArgs { @@ -137,7 +145,12 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .get_mut::(rid) .ok_or_else(bad_resource_id)? }), - channel: PassChannel {}, // TODO + channel: wgc::command::PassChannel { + load_op: LoadOp::Clear, // TODO + store_op: color_attachment.store_op.map_or(wgc::command::StoreOp::Store, serialize_store_op), + clear_value: (), // TODO + read_only: false // TODO + }, } }) .collect::>(), @@ -151,8 +164,18 @@ pub fn op_webgpu_command_encoder_begin_render_pass( depth_stencil_attachment.attachment, ) .ok_or_else(bad_resource_id)?, - depth: PassChannel {}, // TODO - stencil: PassChannel {}, // TODO + depth: wgc::command::PassChannel { + load_op: LoadOp::Clear, // TODO + store_op: serialize_store_op(depth_stencil_attachment.depth_store_op), + clear_value: (), // TODO + read_only: false // TODO + }, + stencil: wgc::command::PassChannel { + load_op: LoadOp::Clear, // TODO + store_op: serialize_store_op(depth_stencil_attachment.stencil_store_op), + clear_value: (), // TODO + read_only: false // TODO + }, } }, ), @@ -173,7 +196,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( struct CommandEncoderBeginComputePassArgs { instance_rid: u32, command_encoder_rid: u32, - label: Option, // TODO + label: Option, // wgpu#974 } pub fn op_webgpu_command_encoder_begin_compute_pass( @@ -192,7 +215,6 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - // TODO: should accept label let compute_pass = wgc::command::ComputePass::new(*command_encoder); let rid = state @@ -260,12 +282,20 @@ pub struct GPUBufferCopyView { rows_per_image: Option, } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GPUOrigin3D { + pub x: Option, + pub y: Option, + pub z: Option, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct GPUTextureCopyView { pub texture: u32, pub mip_level: Option, - pub origin: (), // TODO: mixed types + pub origin: Option, } #[derive(Deserialize)] @@ -275,7 +305,7 @@ struct CommandEncoderCopyBufferToTextureArgs { command_encoder_rid: u32, source: GPUBufferCopyView, destination: GPUTextureCopyView, - copy_size: (), // TODO: mixed types + copy_size: super::texture::GPUExtent3D, } pub fn op_webgpu_command_encoder_copy_buffer_to_texture( @@ -314,12 +344,18 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: Default::default(), // TODO + origin: args.destination.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), }, &wgt::Extent3d { - width: 0, // TODO - height: 0, // TODO - depth: 0, // TODO + width: args.copy_size.width, + height: args.copy_size.height, + depth: args.copy_size.depth, }, )?; @@ -333,7 +369,7 @@ struct CommandEncoderCopyTextureToBufferArgs { command_encoder_rid: u32, source: GPUTextureCopyView, destination: GPUBufferCopyView, - copy_size: (), // TODO: mixed types + copy_size: super::texture::GPUExtent3D, } pub fn op_webgpu_command_encoder_copy_texture_to_buffer( @@ -361,7 +397,13 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .get_mut::(args.source.texture) .ok_or_else(bad_resource_id)?, mip_level: args.source.mip_level.unwrap_or(0), - origin: Default::default(), // TODO + origin: args.source.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }) }, &wgc::command::BufferCopyView { buffer: *state @@ -375,9 +417,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( }, }, &wgt::Extent3d { - width: 0, // TODO - height: 0, // TODO - depth: 0, // TODO + width: args.copy_size.width, + height: args.copy_size.height, + depth: args.copy_size.depth, }, )?; @@ -391,7 +433,7 @@ struct CommandEncoderCopyTextureToTextureArgs { command_encoder_rid: u32, source: GPUTextureCopyView, destination: GPUTextureCopyView, - copy_size: (), // TODO: mixed types + copy_size: super::texture::GPUExtent3D, } pub fn op_webgpu_command_encoder_copy_texture_to_texture( @@ -419,7 +461,13 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .get_mut::(args.source.texture) .ok_or_else(bad_resource_id)?, mip_level: args.source.mip_level.unwrap_or(0), - origin: Default::default(), // TODO + origin: args.source.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), }, &wgc::command::TextureCopyView { texture: *state @@ -427,13 +475,18 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: Default::default(), // TODO + origin: args.destination.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), }, &wgt::Extent3d { - // TODO - width: 0, - height: 0, - depth: 0, + width: args.copy_size.width, + height: args.copy_size.height, + depth: args.copy_size.depth, }, )?; diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 2551960f898d5c..de443187b1b809 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -55,7 +55,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { } fn serialize_features(features: &wgt::Features) -> Vec<&str> { - let mut extensions: Vec<&str> = vec![]; + let mut extensions: Vec<&str> = vec![];5 if features.contains(wgt::Features::DEPTH_CLAMPING) { extensions.push("depth-clamping"); diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 7f9d303c2970a5..58dabc9c478a7e 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -157,8 +157,14 @@ pub fn op_webgpu_create_compute_pipeline( args.compute_stage, )?, }, - (), // TODO: id_in - (), // TODO: look into what this is + std::marker::PhantomData, + match args.layout { // TODO: check + Some(_) => None, + None => Some(wgc::device::ImplicitPipelineIds { + root_id: std::marker::PhantomData, + group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + }), + } )?; let rid = state @@ -380,12 +386,7 @@ pub fn op_webgpu_create_render_pipeline( color_blend: color_state .color_blend .map_or(Default::default(), serialize_blend_descriptor), - write_mask: color_state.write_mask.map_or( - Default::default(), - |mask| { - wgt::ColorWrite::from_bits(mask).unwrap() // TODO: don't unwrap - }, - ), + write_mask: color_state.write_mask.map_or(Default::default(), |mask| wgt::ColorWrite::from_bits(mask).unwrap()), } }) .collect::>(), @@ -487,8 +488,14 @@ pub fn op_webgpu_create_render_pipeline( .alpha_to_coverage_enabled .unwrap_or(false), }, - (), // TODO: id_in - (), // TODO: look into what this is + std::marker::PhantomData, + match args.layout { // TODO: check + Some(_) => None, + None => Some(wgc::device::ImplicitPipelineIds { + root_id: std::marker::PhantomData, + group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + }), + } )?; let rid = state diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index ead35ffea9200d..b61dd6c2809679 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -101,11 +101,10 @@ pub fn op_webgpu_write_buffer( .get_mut::(args.buffer) .ok_or_else(bad_resource_id)?, args.buffer_offset, - &zero_copy[0][if let Some(size) = args.size { - args.data_offset..(args.data_offset + size) - } else { - args.data_offset.. - }], + match args.size { + Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], + None => &zero_copy[0][args.data_offset..], + }, )?; Ok(json!({})) @@ -118,7 +117,7 @@ struct QueueWriteTextureArgs { queue_rid: u32, destination: super::command_encoder::GPUTextureCopyView, data_layout: GPUTextureDataLayout, - size: (), // TODO: mixed types + size: super::texture::GPUExtent3D, } pub fn op_webgpu_write_texture( @@ -145,7 +144,13 @@ pub fn op_webgpu_write_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: Default::default(), + origin: args.destination.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), }, &*zero_copy[0], &wgt::TextureDataLayout { @@ -154,9 +159,9 @@ pub fn op_webgpu_write_texture( rows_per_image: args.data_layout.rows_per_image, }, &wgt::Extent3d { - width: 0, - height: 0, - depth: 0, + width: args.size.width, + height: args.size.height, + depth: args.size.depth, }, )?; diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index b599b998d79a11..4363f4d6b3a884 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -101,11 +101,20 @@ pub fn op_webgpu_render_pass_set_scissor_rect( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUColor { + r: f64, + g: f64, + b: f64, + a: f64, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassSetBlendColorArgs { render_pass_rid: u32, - color: (), // TODO: mixed types + color: GPUColor, } pub fn op_webgpu_render_pass_set_blend_color( @@ -123,11 +132,10 @@ pub fn op_webgpu_render_pass_set_blend_color( wgc::command::render_ffi::wgpu_render_pass_set_blend_color( render_pass, &wgt::Color { - // TODO - r: 0.0, - g: 0.0, - b: 0.0, - a: 0.0, + r: args.color.r, + g: args.color.g, + b: args.color.b, + a: args.color.a, }, ); @@ -426,7 +434,7 @@ pub fn op_webgpu_render_pass_set_index_buffer( if args.size == 0 { None } else { - Some(args.size as std::num::NonZeroU64) // TODO: check + Some(args.size as std::num::NonZeroU64) }, ); @@ -466,7 +474,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( if args.size == 0 { None } else { - Some(args.size as std::num::NonZeroU64) // TODO: check + Some(args.size as std::num::NonZeroU64) }, ); diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 5415ac4b811e42..4bb655d6cc1dc0 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -97,7 +97,7 @@ pub fn op_webgpu_create_sampler( min_filter: serialize_filter_mode(args.min_filter), mipmap_filter: serialize_filter_mode(args.mipmap_filter), lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args.lod_max_clamp.unwrap_or(0xffffffff as f32), // TODO: check if there is a better solution + lod_max_clamp: args.lod_max_clamp.unwrap_or(f32::MAX), // TODO: check compare: args.compare.map(serialize_compare_function), anisotropy_clamp: args.max_anisotropy, }, diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 09518a6aa4cee4..ced211bba77169 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -114,13 +114,21 @@ pub fn serialize_dimension(dimension: String) -> wgt::TextureViewDimension { } } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GPUExtent3D { + pub width: u32, + pub height: u32, + pub depth: u32, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureArgs { instance_rid: u32, device_rid: u32, label: Option, - size: (), // TODO: mixed types + size: GPUExtent3D, mip_level_count: Option, sample_count: Option, dimension: Option, @@ -148,7 +156,11 @@ pub fn op_webgpu_create_texture( *device, &wgc::resource::TextureDescriptor { label: args.label.map(|label| Cow::Borrowed(&label)), - size: Default::default(), // TODO + size: wgt::Extent3d { + width: args.size.width, + height: args.size.height, + depth: args.size.depth, + }, mip_level_count: args.mip_level_count.unwrap_or(1), sample_count: args.sample_count.unwrap_or(1), dimension: match args.dimension { @@ -159,7 +171,7 @@ pub fn op_webgpu_create_texture( None => wgt::TextureDimension::D2, }, format: serialize_texture_format(args.format)?, - usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), // TODO: don't unwrap + usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), }, std::marker::PhantomData, )?; diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 827bd8251144b8..ff45a43336d5a9 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -3,6 +3,43 @@ ((window) => { const core = window.Deno.core; + function normalizeGPUExtent3D(data) { + if (Array.isArray(data)) { + return { + width: data[0], + height: data[1], + depth: data[2], + }; + } else { + return data; + } + } + + function normalizeGPUOrigin3D(data) { + if (Array.isArray(data)) { + return { + x: data[0], + y: data[1], + z: data[2], + }; + } else { + return data; + } + } + + function normalizeGPUColor(data) { + if (Array.isArray(data)) { + return { + r: data[0], + g: data[1], + b: data[2], + a: data[3], + }; + } else { + return data; + } + } + let instanceRid; // TODO: use op_webgpu_create_instance const GPU = { @@ -96,6 +133,7 @@ instanceRid, deviceRid: this.#rid, ...descriptor, + size: normalizeGPUExtent3D(descriptor.size), }); const texture = new GPUTexture(rid, descriptor.label); @@ -298,9 +336,13 @@ { instanceRid, queueRid: this.#rid, - destination, + destination: { + texture: GPUTextureMap.get(destination.texture), + mipLevel: destination.mipLevel, + origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), + }, dataLayout, - size, + size: normalizeGPUExtent3D(size), }, data, ); @@ -549,14 +591,15 @@ instanceRid, commandEncoderRid: this.#rid, source: { - ...source, // TODO: check + ...source, buffer: GPUBufferMap.get(source.buffer), }, destination: { - ...destination, // TODO: check texture: GPUTextureMap.get(destination.texture), + mipLevel: destination.mipLevel, + origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), }, - copySize, + copySize: normalizeGPUExtent3D(copySize), }, ); } @@ -568,14 +611,15 @@ instanceRid, commandEncoderRid: this.#rid, source: { - ...source, // TODO: check texture: GPUTextureMap.get(source.texture), + mipLevel: source.mipLevel, + origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { - ...destination, // TODO: check + ...destination, buffer: GPUBufferMap.get(destination.buffer), }, - copySize, + copySize: normalizeGPUExtent3D(copySize), }, ); } @@ -587,14 +631,16 @@ instanceRid, commandEncoderRid: this.#rid, source: { - ...source, // TODO: check texture: GPUTextureMap.get(source.texture), + mipLevel: source.mipLevel, + origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { - ...destination, // TODO: check texture: GPUTextureMap.get(destination.texture), + mipLevel: destination.mipLevel, + origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), }, - copySize, + copySize: normalizeGPUExtent3D(copySize), }, ); } @@ -682,7 +728,7 @@ setBlendColor(color) { core.jsonOpSync("op_webgpu_render_pass_set_blend_color", { renderPassRid: this.#rid, - color, + color: normalizeGPUColor(color), }); } setStencilReference(reference) { From 3a2ef8b274d89391532d25e6aeca20ef3ff975d5 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 14 Oct 2020 07:42:28 +0200 Subject: [PATCH 018/144] fmt --- cli/ops/webgpu/binding.rs | 131 +++++++++++++++--------------- cli/ops/webgpu/buffer.rs | 24 +++++- cli/ops/webgpu/bundle.rs | 80 ++++++++++++++---- cli/ops/webgpu/command_encoder.rs | 110 ++++++++++++++++++------- cli/ops/webgpu/compute_pass.rs | 50 ++++++++++-- cli/ops/webgpu/mod.rs | 2 +- cli/ops/webgpu/pipeline.rs | 58 ++++++++----- cli/ops/webgpu/queue.rs | 27 ++++-- cli/ops/webgpu/render_pass.rs | 104 ++++++++++++++++++++---- cli/ops/webgpu/sampler.rs | 6 +- cli/ops/webgpu/shader.rs | 10 ++- cli/ops/webgpu/texture.rs | 12 ++- cli/rt/14_webgpu.js | 49 +++++------ 13 files changed, 469 insertions(+), 194 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 81c2c45232119d..a3259ef8401227 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -15,9 +15,21 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_bind_group_layout", op_webgpu_create_bind_group_layout); - super::super::reg_json_sync(rt, "op_webgpu_create_pipeline_layout", op_webgpu_create_pipeline_layout); - super::super::reg_json_sync(rt, "op_webgpu_create_bind_group", op_webgpu_create_bind_group); + super::super::reg_json_sync( + rt, + "op_webgpu_create_bind_group_layout", + op_webgpu_create_bind_group_layout, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_create_pipeline_layout", + op_webgpu_create_pipeline_layout, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_create_bind_group", + op_webgpu_create_bind_group, + ); } fn serialize_texture_component_type( @@ -79,70 +91,61 @@ pub fn op_webgpu_create_bind_group_layout( args .entries .iter() - .map(|entry| { - wgt::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgt::ShaderStage::from_bits(entry.visibility) - .unwrap(), - ty: match entry.kind { - &"uniform-buffer" => wgt::BindingType::UniformBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - }, - &"storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: false, - }, - &"readonly-storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: true, - }, - &"sampler" => wgt::BindingType::Sampler { comparison: false }, - &"comparison-sampler" => { - wgt::BindingType::Sampler { comparison: true } - } - &"sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, - multisampled: false, - }, - &"multisampled-texture" => wgt::BindingType::SampledTexture { + .map(|entry| wgt::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), + ty: match entry.kind { + &"uniform-buffer" => wgt::BindingType::UniformBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + }, + &"storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: false, + }, + &"readonly-storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: entry.min_buffer_binding_size, + readonly: true, + }, + &"sampler" => wgt::BindingType::Sampler { comparison: false }, + &"comparison-sampler" => { + wgt::BindingType::Sampler { comparison: true } + } + &"sampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: false, + }, + &"multisampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: true, + }, + &"readonly-storage-texture" => wgt::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, + readonly: true, + }, + &"writeonly-storage-texture" => { + wgt::BindingType::StorageTexture { dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), )?, - multisampled: true, - }, - &"readonly-storage-texture" => { - wgt::BindingType::StorageTexture { - dimension: serialize_dimension( - entry.view_dimension.unwrap(), - ), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: true, - } - } - &"writeonly-storage-texture" => { - wgt::BindingType::StorageTexture { - dimension: serialize_dimension( - entry.view_dimension.unwrap(), - ), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: false, - } + readonly: false, } - _ => unreachable!(), - }, - count: None, - } + } + _ => unreachable!(), + }, + count: None, }) .collect::>(), ), diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 1420eca3216ebf..320b4e6765c662 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -14,10 +14,26 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_buffer", op_webgpu_create_buffer); - super::super::reg_json_sync(rt, "op_webgpu_buffer_get_map_async", op_webgpu_buffer_get_map_async); - super::super::reg_json_sync(rt, "op_webgpu_buffer_get_mapped_range", op_webgpu_buffer_get_mapped_range); - super::super::reg_json_sync(rt, "op_webgpu_buffer_unmap", op_webgpu_buffer_unmap); + super::super::reg_json_sync( + rt, + "op_webgpu_create_buffer", + op_webgpu_create_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_buffer_get_map_async", + op_webgpu_buffer_get_map_async, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_buffer_get_mapped_range", + op_webgpu_buffer_get_mapped_range, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_buffer_unmap", + op_webgpu_buffer_unmap, + ); } #[derive(Deserialize)] diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 5a4f7e7f2451cf..3b21612cb3a20c 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -15,19 +15,71 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_render_bundle_encoder", op_webgpu_create_render_bundle_encoder); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_finish", op_webgpu_render_bundle_encoder_finish); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_bind_group", op_webgpu_render_bundle_encoder_set_bind_group); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_push_debug_group", op_webgpu_render_bundle_encoder_push_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_pop_debug_group", op_webgpu_render_bundle_encoder_pop_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_insert_debug_marker", op_webgpu_render_bundle_encoder_insert_debug_marker); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_pipeline", op_webgpu_render_bundle_encoder_set_pipeline); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_index_buffer", op_webgpu_render_bundle_encoder_set_index_buffer); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_set_vertex_buffer", op_webgpu_render_bundle_encoder_set_vertex_buffer); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw", op_webgpu_render_bundle_encoder_draw); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indexed", op_webgpu_render_bundle_encoder_draw_indexed); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indirect", op_webgpu_render_bundle_encoder_draw_indirect); - super::super::reg_json_sync(rt, "op_webgpu_render_bundle_encoder_draw_indexed_indirect", op_webgpu_render_bundle_encoder_draw_indexed_indirect); + super::super::reg_json_sync( + rt, + "op_webgpu_create_render_bundle_encoder", + op_webgpu_create_render_bundle_encoder, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_finish", + op_webgpu_render_bundle_encoder_finish, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_bind_group", + op_webgpu_render_bundle_encoder_set_bind_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_push_debug_group", + op_webgpu_render_bundle_encoder_push_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_pop_debug_group", + op_webgpu_render_bundle_encoder_pop_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_insert_debug_marker", + op_webgpu_render_bundle_encoder_insert_debug_marker, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_pipeline", + op_webgpu_render_bundle_encoder_set_pipeline, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_index_buffer", + op_webgpu_render_bundle_encoder_set_index_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_vertex_buffer", + op_webgpu_render_bundle_encoder_set_vertex_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw", + op_webgpu_render_bundle_encoder_draw, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indexed", + op_webgpu_render_bundle_encoder_draw_indexed, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indirect", + op_webgpu_render_bundle_encoder_draw_indirect, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indexed_indirect", + op_webgpu_render_bundle_encoder_draw_indexed_indirect, + ); } #[derive(Deserialize)] @@ -161,7 +213,7 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - } + }, }, args.dynamic_offsets_data_length, ); diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 3ce0872b1d6f33..e51bb77859a8f2 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -14,17 +14,61 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_command_encoder", op_webgpu_create_command_encoder); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_begin_render_pass", op_webgpu_command_encoder_begin_render_pass); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_begin_compute_pass", op_webgpu_command_encoder_begin_compute_pass); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_buffer_to_buffer", op_webgpu_command_encoder_copy_buffer_to_buffer); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_buffer_to_texture", op_webgpu_command_encoder_copy_buffer_to_texture); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_texture_to_buffer", op_webgpu_command_encoder_copy_texture_to_buffer); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_copy_texture_to_texture", op_webgpu_command_encoder_copy_texture_to_texture); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_push_debug_group", op_webgpu_command_encoder_push_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_pop_debug_group", op_webgpu_command_encoder_pop_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_insert_debug_marker", op_webgpu_command_encoder_insert_debug_marker); - super::super::reg_json_sync(rt, "op_webgpu_command_encoder_finish", op_webgpu_command_encoder_finish); + super::super::reg_json_sync( + rt, + "op_webgpu_create_command_encoder", + op_webgpu_create_command_encoder, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_render_pass", + op_webgpu_command_encoder_begin_render_pass, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_compute_pass", + op_webgpu_command_encoder_begin_compute_pass, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_buffer", + op_webgpu_command_encoder_copy_buffer_to_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_texture", + op_webgpu_command_encoder_copy_buffer_to_texture, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_buffer", + op_webgpu_command_encoder_copy_texture_to_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_texture", + op_webgpu_command_encoder_copy_texture_to_texture, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_push_debug_group", + op_webgpu_command_encoder_push_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_pop_debug_group", + op_webgpu_command_encoder_pop_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_insert_debug_marker", + op_webgpu_command_encoder_insert_debug_marker, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_command_encoder_finish", + op_webgpu_command_encoder_finish, + ); } fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { @@ -147,9 +191,11 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }), channel: wgc::command::PassChannel { load_op: LoadOp::Clear, // TODO - store_op: color_attachment.store_op.map_or(wgc::command::StoreOp::Store, serialize_store_op), - clear_value: (), // TODO - read_only: false // TODO + store_op: color_attachment + .store_op + .map_or(wgc::command::StoreOp::Store, serialize_store_op), + clear_value: (), // TODO + read_only: false, // TODO }, } }) @@ -166,15 +212,19 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .ok_or_else(bad_resource_id)?, depth: wgc::command::PassChannel { load_op: LoadOp::Clear, // TODO - store_op: serialize_store_op(depth_stencil_attachment.depth_store_op), - clear_value: (), // TODO - read_only: false // TODO + store_op: serialize_store_op( + depth_stencil_attachment.depth_store_op, + ), + clear_value: (), // TODO + read_only: false, // TODO }, stencil: wgc::command::PassChannel { load_op: LoadOp::Clear, // TODO - store_op: serialize_store_op(depth_stencil_attachment.stencil_store_op), - clear_value: (), // TODO - read_only: false // TODO + store_op: serialize_store_op( + depth_stencil_attachment.stencil_store_op, + ), + clear_value: (), // TODO + read_only: false, // TODO }, } }, @@ -344,13 +394,14 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: args.destination.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), - } - }), + }), }, &wgt::Extent3d { width: args.copy_size.width, @@ -403,7 +454,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), } - }) + }), }, &wgc::command::BufferCopyView { buffer: *state @@ -475,13 +526,14 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: args.destination.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), - } - }), + }), }, &wgt::Extent3d { width: args.copy_size.width, diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index c93bfb645f156b..a84eacb9f27148 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -12,14 +12,46 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_set_pipeline", op_webgpu_compute_pass_set_pipeline); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_dispatch", op_webgpu_compute_pass_dispatch); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_dispatch_indirect", op_webgpu_compute_pass_dispatch_indirect); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_end_pass", op_webgpu_compute_pass_end_pass); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_set_bind_group", op_webgpu_compute_pass_set_bind_group); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_push_debug_group", op_webgpu_compute_pass_push_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_pop_debug_group", op_webgpu_compute_pass_pop_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_compute_pass_insert_debug_marker", op_webgpu_compute_pass_insert_debug_marker); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_pipeline", + op_webgpu_compute_pass_set_pipeline, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch", + op_webgpu_compute_pass_dispatch, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch_indirect", + op_webgpu_compute_pass_dispatch_indirect, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_end_pass", + op_webgpu_compute_pass_end_pass, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_bind_group", + op_webgpu_compute_pass_set_bind_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_push_debug_group", + op_webgpu_compute_pass_push_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_pop_debug_group", + op_webgpu_compute_pass_pop_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pass_insert_debug_marker", + op_webgpu_compute_pass_insert_debug_marker, + ); } #[derive(Deserialize)] @@ -186,7 +218,7 @@ pub fn op_webgpu_compute_pass_set_bind_group( assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - } + }, }, args.dynamic_offsets_data_length, ); diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index de443187b1b809..2551960f898d5c 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -55,7 +55,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { } fn serialize_features(features: &wgt::Features) -> Vec<&str> { - let mut extensions: Vec<&str> = vec![];5 + let mut extensions: Vec<&str> = vec![]; if features.contains(wgt::Features::DEPTH_CLAMPING) { extensions.push("depth-clamping"); diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 58dabc9c478a7e..6b70ff4271620f 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -16,10 +16,26 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_compute_pipeline", op_webgpu_create_compute_pipeline); - super::super::reg_json_sync(rt, "op_webgpu_compute_pipeline_get_bind_group_layout", op_webgpu_compute_pipeline_get_bind_group_layout); - super::super::reg_json_sync(rt, "op_webgpu_create_render_pipeline", op_webgpu_create_render_pipeline); - super::super::reg_json_sync(rt, "op_webgpu_render_pipeline_get_bind_group_layout", op_webgpu_render_pipeline_get_bind_group_layout); + super::super::reg_json_sync( + rt, + "op_webgpu_create_compute_pipeline", + op_webgpu_create_compute_pipeline, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_compute_pipeline_get_bind_group_layout", + op_webgpu_compute_pipeline_get_bind_group_layout, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_create_render_pipeline", + op_webgpu_create_render_pipeline, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pipeline_get_bind_group_layout", + op_webgpu_render_pipeline_get_bind_group_layout, + ); } fn serialize_programmable_stage_descriptor( @@ -158,13 +174,14 @@ pub fn op_webgpu_create_compute_pipeline( )?, }, std::marker::PhantomData, - match args.layout { // TODO: check + match args.layout { + // TODO: check Some(_) => None, None => Some(wgc::device::ImplicitPipelineIds { root_id: std::marker::PhantomData, group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], }), - } + }, )?; let rid = state @@ -377,17 +394,19 @@ pub fn op_webgpu_create_render_pipeline( args .color_states .iter() - .map(|color_state| { - wgt::ColorStateDescriptor { - format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state - .alpha_blend - .map_or(Default::default(), serialize_blend_descriptor), - color_blend: color_state - .color_blend - .map_or(Default::default(), serialize_blend_descriptor), - write_mask: color_state.write_mask.map_or(Default::default(), |mask| wgt::ColorWrite::from_bits(mask).unwrap()), - } + .map(|color_state| wgt::ColorStateDescriptor { + format: serialize_texture_format(color_state.format.clone())?, + alpha_blend: color_state + .alpha_blend + .map_or(Default::default(), serialize_blend_descriptor), + color_blend: color_state + .color_blend + .map_or(Default::default(), serialize_blend_descriptor), + write_mask: color_state + .write_mask + .map_or(Default::default(), |mask| { + wgt::ColorWrite::from_bits(mask).unwrap() + }), }) .collect::>(), ), @@ -489,13 +508,14 @@ pub fn op_webgpu_create_render_pipeline( .unwrap_or(false), }, std::marker::PhantomData, - match args.layout { // TODO: check + match args.layout { + // TODO: check Some(_) => None, None => Some(wgc::device::ImplicitPipelineIds { root_id: std::marker::PhantomData, group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], }), - } + }, )?; let rid = state diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index b61dd6c2809679..0dee3e0f63cdf1 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -13,9 +13,21 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_queue_submit", op_webgpu_queue_submit); - super::super::reg_json_sync(rt, "op_webgpu_write_buffer", op_webgpu_write_buffer); - super::super::reg_json_sync(rt, "op_webgpu_write_texture", op_webgpu_write_texture); + super::super::reg_json_sync( + rt, + "op_webgpu_queue_submit", + op_webgpu_queue_submit, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_write_buffer", + op_webgpu_write_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_write_texture", + op_webgpu_write_texture, + ); } #[derive(Deserialize)] @@ -144,13 +156,14 @@ pub fn op_webgpu_write_texture( .get_mut::(args.destination.texture) .ok_or_else(bad_resource_id)?, mip_level: args.destination.mip_level.unwrap_or(0), - origin: args.destination.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), - } - }), + }), }, &*zero_copy[0], &wgt::TextureDataLayout { diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 4363f4d6b3a884..a6e81fb66902fd 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -12,23 +12,91 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_viewport", op_webgpu_render_pass_set_viewport); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_scissor_rect", op_webgpu_render_pass_set_scissor_rect); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_blend_color", op_webgpu_render_pass_set_blend_color); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_stencil_reference", op_webgpu_render_pass_set_stencil_reference); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_execute_bundles", op_webgpu_render_pass_execute_bundles); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_end_pass", op_webgpu_render_pass_end_pass); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_bind_group", op_webgpu_render_pass_set_bind_group); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_push_debug_group", op_webgpu_render_pass_push_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_pop_debug_group", op_webgpu_render_pass_pop_debug_group); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_insert_debug_marker", op_webgpu_render_pass_insert_debug_marker); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_pipeline", op_webgpu_render_pass_set_pipeline); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_index_buffer", op_webgpu_render_pass_set_index_buffer); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_set_vertex_buffer", op_webgpu_render_pass_set_vertex_buffer); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw", op_webgpu_render_pass_draw); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indexed", op_webgpu_render_pass_draw_indexed); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indirect", op_webgpu_render_pass_draw_indirect); - super::super::reg_json_sync(rt, "op_webgpu_render_pass_draw_indexed_indirect", op_webgpu_render_pass_draw_indexed_indirect); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_viewport", + op_webgpu_render_pass_set_viewport, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_scissor_rect", + op_webgpu_render_pass_set_scissor_rect, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_blend_color", + op_webgpu_render_pass_set_blend_color, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_stencil_reference", + op_webgpu_render_pass_set_stencil_reference, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_execute_bundles", + op_webgpu_render_pass_execute_bundles, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_end_pass", + op_webgpu_render_pass_end_pass, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_bind_group", + op_webgpu_render_pass_set_bind_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_push_debug_group", + op_webgpu_render_pass_push_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_pop_debug_group", + op_webgpu_render_pass_pop_debug_group, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_insert_debug_marker", + op_webgpu_render_pass_insert_debug_marker, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_pipeline", + op_webgpu_render_pass_set_pipeline, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_index_buffer", + op_webgpu_render_pass_set_index_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_vertex_buffer", + op_webgpu_render_pass_set_vertex_buffer, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw", + op_webgpu_render_pass_draw, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed", + op_webgpu_render_pass_draw_indexed, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indirect", + op_webgpu_render_pass_draw_indirect, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed_indirect", + op_webgpu_render_pass_draw_indexed_indirect, + ); } #[derive(Deserialize)] @@ -280,7 +348,7 @@ pub fn op_webgpu_render_pass_set_bind_group( assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - } + }, }, args.dynamic_offsets_data_length, ); diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 4bb655d6cc1dc0..23b84fdd0e9af7 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -14,7 +14,11 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_sampler", op_webgpu_create_sampler); + super::super::reg_json_sync( + rt, + "op_webgpu_create_sampler", + op_webgpu_create_sampler, + ); } fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index ee614b6ff91fa3..36adbe9adaec75 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -9,13 +9,17 @@ use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -use std::cell::RefCell; -use std::rc::Rc; use std::borrow::Cow; +use std::cell::RefCell; use std::ops::Deref; +use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_shader_module", op_webgpu_create_shader_module); + super::super::reg_json_sync( + rt, + "op_webgpu_create_shader_module", + op_webgpu_create_shader_module, + ); } #[derive(Deserialize)] diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index ced211bba77169..fa77f5409253fb 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -14,8 +14,16 @@ use std::cell::RefCell; use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync(rt, "op_webgpu_create_texture", op_webgpu_create_texture); - super::super::reg_json_sync(rt, "op_webgpu_create_texture_view", op_webgpu_create_texture_view); + super::super::reg_json_sync( + rt, + "op_webgpu_create_texture", + op_webgpu_create_texture, + ); + super::super::reg_json_sync( + rt, + "op_webgpu_create_texture_view", + op_webgpu_create_texture_view, + ); } pub fn serialize_texture_format( diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index ff45a43336d5a9..3f7cd39630dee1 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -69,7 +69,7 @@ constructor(rid, data) { this.#rid = rid; this.#name = data.name; - this.#extensions = Object.freeze(data.features); + this.#features = Object.freeze(data.features); } async requestDevice(descriptor = {}) { @@ -82,7 +82,7 @@ }, ); - return new GPUDevice(this, data); + return new GPUDevice(this, rid, data); } } @@ -260,11 +260,11 @@ return pipeline; } - async createReadyComputePipeline(descriptor) { + createReadyComputePipeline(_descriptor) { throw new Error("Not yet implemented"); // easy polyfill } - async createReadyRenderPipeline(descriptor) { + createReadyRenderPipeline(_descriptor) { throw new Error("Not yet implemented"); // easy polyfill } @@ -290,7 +290,7 @@ return new GPURenderBundleEncoder(rid, descriptor.label); } - createQuerySet(descriptor) { + createQuerySet(_descriptor) { throw new Error("Not yet implemented"); // wgpu#721 } } @@ -311,7 +311,7 @@ ), }); } - createFence(descriptor = {}) { + createFence(_descriptor = {}) { throw new Error("Not yet implemented"); } @@ -339,7 +339,8 @@ destination: { texture: GPUTextureMap.get(destination.texture), mipLevel: destination.mipLevel, - origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), + origin: destination.origin ?? + normalizeGPUOrigin3D(destination.origin), }, dataLayout, size: normalizeGPUExtent3D(size), @@ -348,7 +349,7 @@ ); } - copyImageBitmapToTexture(source, destination, copySize) { + copyImageBitmapToTexture(_source, _destination, _copySize) { throw new Error("Not yet implemented"); } } @@ -474,7 +475,7 @@ this.label = label ?? null; } - async compilationInfo() { + compilationInfo() { throw new Error("Not yet implemented"); // wgpu#977 } } @@ -597,7 +598,8 @@ destination: { texture: GPUTextureMap.get(destination.texture), mipLevel: destination.mipLevel, - origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), + origin: destination.origin ?? + normalizeGPUOrigin3D(destination.origin), }, copySize: normalizeGPUExtent3D(copySize), }, @@ -638,7 +640,8 @@ destination: { texture: GPUTextureMap.get(destination.texture), mipLevel: destination.mipLevel, - origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), + origin: destination.origin ?? + normalizeGPUOrigin3D(destination.origin), }, copySize: normalizeGPUExtent3D(copySize), }, @@ -666,16 +669,16 @@ }); } - writeTimestamp(querySet, queryIndex) { + writeTimestamp(_querySet, _queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } resolveQuerySet( - querySet, - firstQuery, - queryCount, - destination, - destinationOffset, + _querySet, + _firstQuery, + _queryCount, + _destination, + _destinationOffset, ) { throw new Error("Not yet implemented"); // wgpu#721 } @@ -738,21 +741,21 @@ }); } - beginOcclusionQuery(queryIndex) { + beginOcclusionQuery(_queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } endOcclusionQuery() { throw new Error("Not yet implemented"); // wgpu#721 } - beginPipelineStatisticsQuery(querySet, queryIndex) { + beginPipelineStatisticsQuery(_querySet, _queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } endPipelineStatisticsQuery() { throw new Error("Not yet implemented"); // wgpu#721 } - writeTimestamp(querySet, queryIndex) { + writeTimestamp(_querySet, _queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } @@ -921,14 +924,14 @@ }); } - beginPipelineStatisticsQuery(querySet, queryIndex) { + beginPipelineStatisticsQuery(_querySet, _queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } endPipelineStatisticsQuery() { throw new Error("Not yet implemented"); // wgpu#721 } - writeTimestamp(querySet, queryIndex) { + writeTimestamp(_querySet, _queryIndex) { throw new Error("Not yet implemented"); // wgpu#721 } @@ -1135,7 +1138,7 @@ indirectOffset, }); } - drawIndexedIndirect(indirectBuffer, indirectOffset) { + drawIndexedIndirect(_indirectBuffer, _indirectOffset) { throw new Error("Not yet implemented"); } } From 1b881c76ee6ddbdf261bf312f643f3919c556e4b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 14 Oct 2020 08:17:39 +0200 Subject: [PATCH 019/144] cleanup --- cli/ops/webgpu/binding.rs | 4 --- cli/ops/webgpu/buffer.rs | 1 - cli/ops/webgpu/bundle.rs | 45 ++----------------------------- cli/ops/webgpu/command_encoder.rs | 6 +---- cli/ops/webgpu/compute_pass.rs | 7 ++--- cli/ops/webgpu/mod.rs | 3 +-- cli/ops/webgpu/pipeline.rs | 6 +---- cli/ops/webgpu/queue.rs | 6 +---- cli/ops/webgpu/render_pass.rs | 5 +--- cli/ops/webgpu/sampler.rs | 6 +---- cli/ops/webgpu/shader.rs | 7 +---- cli/ops/webgpu/texture.rs | 4 --- 12 files changed, 11 insertions(+), 89 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index a3259ef8401227..a640586de81139 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -1,18 +1,14 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::texture::{serialize_dimension, serialize_texture_format}; -use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 320b4e6765c662..01a7742d1301e6 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; -use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 3b21612cb3a20c..d9bfff8a535f6c 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -1,18 +1,14 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::texture::serialize_texture_format; -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( @@ -75,11 +71,6 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_bundle_encoder_draw_indirect", op_webgpu_render_bundle_encoder_draw_indirect, ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indexed_indirect", - op_webgpu_render_bundle_encoder_draw_indexed_indirect, - ); } #[derive(Deserialize)] @@ -494,7 +485,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw_indexed( - render_pass, + render_bundle_encoder, args.index_count, args.instance_count, args.first_index, @@ -538,35 +529,3 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect( Ok(json!({})) } - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct RenderBundleEncoderDrawIndexedIndirectArgs { - render_pass_rid: u32, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_bundle_encoder_draw_indexed_indirect( - state: &mut OpState, - args: Value, - _zero_copy: &mut [ZeroCopyBuf], -) -> Result { - let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; - - let render_pass = state - .resource_table - .get_mut::(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgc::command::bundle_ffi::wgpu_render_pass_draw_indexed_indirect( - render_pass, - *state - .resource_table - .get_mut::(args.indirect_buffer) - .ok_or_else(bad_resource_id)?, - args.indirect_offset, - ); - - Ok(json!({})) -} diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index e51bb77859a8f2..5148ac46547b34 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -1,17 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index a84eacb9f27148..fc685278a3019d 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -1,15 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( @@ -120,7 +117,7 @@ pub fn op_webgpu_compute_pass_dispatch( struct ComputePassDispatchIndirectArgs { compute_pass_rid: u32, indirect_buffer: u32, - indirect_offset: uu64, + indirect_offset: u64, } pub fn op_webgpu_compute_pass_dispatch_indirect( diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 2551960f898d5c..648334f9602b40 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -13,7 +13,6 @@ mod shader; mod texture; use deno_core::error::bad_resource_id; -use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; @@ -98,7 +97,7 @@ pub fn op_webgpu_create_instance( let rid = state .resource_table - .add("webGPUInstance", Box::new(adapter)); + .add("webGPUInstance", Box::new(instance)); Ok(json!({ "rid": rid, diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 6b70ff4271620f..c6a152f19ac29d 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -2,18 +2,14 @@ use super::sampler::serialize_compare_function; use super::texture::serialize_texture_format; -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index 0dee3e0f63cdf1..2108660f9be82a 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -1,16 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index a6e81fb66902fd..fdcdee55795493 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -1,15 +1,12 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 23b84fdd0e9af7..05d9d8b747f5ae 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -1,17 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 36adbe9adaec75..c6404f79a157c3 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -1,18 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::ops::Deref; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index fa77f5409253fb..c6090d64fb88a3 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -1,17 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub fn init(rt: &mut deno_core::JsRuntime) { super::super::reg_json_sync( From 1275b03a1784e42dedb3ea73e9cb95e16ac889be Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:43:37 +0200 Subject: [PATCH 020/144] use gfx_select and cleanup --- cli/ops/webgpu/binding.rs | 291 +++++++++--------- cli/ops/webgpu/buffer.rs | 55 +++- cli/ops/webgpu/bundle.rs | 69 ++--- cli/ops/webgpu/command_encoder.rs | 279 ++++++++--------- cli/ops/webgpu/compute_pass.rs | 11 +- cli/ops/webgpu/mod.rs | 161 +++++----- cli/ops/webgpu/pipeline.rs | 480 ++++++++++++++++-------------- cli/ops/webgpu/queue.rs | 103 +++---- cli/ops/webgpu/render_pass.rs | 24 +- cli/ops/webgpu/sampler.rs | 77 ++--- cli/ops/webgpu/shader.rs | 27 +- cli/ops/webgpu/texture.rs | 225 +++++++------- cli/rt/14_webgpu.js | 10 +- 13 files changed, 943 insertions(+), 869 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index a640586de81139..8db28c5e8211c2 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -31,11 +31,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { fn serialize_texture_component_type( component_type: String, ) -> Result { - Ok(match component_type { - &"float" => wgt::TextureComponentType::Float, - &"sint" => wgt::TextureComponentType::Sint, - &"uint" => wgt::TextureComponentType::Uint, - &"depth-comparison" => return Err(not_supported()), + Ok(match component_type.as_str() { + "float" => wgt::TextureComponentType::Float, + "sint" => wgt::TextureComponentType::Sint, + "uint" => wgt::TextureComponentType::Uint, + "depth-comparison" => return Err(not_supported()), _ => unreachable!(), }) } @@ -48,7 +48,7 @@ struct GPUBindGroupLayoutEntry { #[serde(rename = "type")] kind: String, has_dynamic_offset: Option, - min_buffer_binding_size: Option, + min_buffer_binding_size: Option, view_dimension: Option, texture_component_type: Option, storage_texture_format: Option, @@ -60,7 +60,7 @@ struct CreateBindGroupLayoutArgs { instance_rid: u32, device_rid: u32, label: Option, - entries: [GPUBindGroupLayoutEntry], + entries: Vec, } pub fn op_webgpu_create_bind_group_layout( @@ -79,75 +79,80 @@ pub fn op_webgpu_create_bind_group_layout( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = instance.device_create_bind_group_layout( - *device, - &wgc::binding_model::BindGroupLayoutDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - entries: Cow::Owned( - args - .entries - .iter() - .map(|entry| wgt::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), - ty: match entry.kind { - &"uniform-buffer" => wgt::BindingType::UniformBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - }, - &"storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: false, - }, - &"readonly-storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: entry.min_buffer_binding_size, - readonly: true, - }, - &"sampler" => wgt::BindingType::Sampler { comparison: false }, - &"comparison-sampler" => { - wgt::BindingType::Sampler { comparison: true } - } - &"sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, - multisampled: false, - }, - &"multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, - multisampled: true, - }, - &"readonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: true, - }, - &"writeonly-storage-texture" => { - wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: false, - } - } - _ => unreachable!(), + let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + entries: Cow::Owned( + args + .entries + .iter() + .map(|entry| wgt::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), + ty: match entry.kind.as_str() { + "uniform-buffer" => wgt::BindingType::UniformBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + }, + "storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + readonly: false, + }, + "readonly-storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + readonly: true, }, - count: None, - }) - .collect::>(), - ), - }, - std::marker::PhantomData, - )?; + "sampler" => wgt::BindingType::Sampler { comparison: false }, + "comparison-sampler" => { + wgt::BindingType::Sampler { comparison: true } + } + "sampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: false, + }, + "multisampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: true, + }, + "readonly-storage-texture" => wgt::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, + readonly: true, + }, + "writeonly-storage-texture" => wgt::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, + readonly: false, + }, + _ => unreachable!(), + }, + count: None, + }) + .collect::>(), + ), + }; + let bind_group_layout = wgc::gfx_select!(*device => instance.device_create_bind_group_layout( + *device, + &descriptor, + std::marker::PhantomData + ))?; let rid = state .resource_table @@ -164,7 +169,7 @@ struct CreatePipelineLayoutArgs { instance_rid: u32, device_rid: u32, label: Option, - bind_group_layouts: [u32], + bind_group_layouts: Vec, } pub fn op_webgpu_create_pipeline_layout( @@ -183,26 +188,27 @@ pub fn op_webgpu_create_pipeline_layout( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let pipeline_layout = instance.device_create_pipeline_layout( + let descriptor = wgc::binding_model::PipelineLayoutDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + bind_group_layouts: Cow::Owned( + args + .bind_group_layouts + .iter() + .map(|rid| { + state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::>(), + ), + push_constant_ranges: Default::default(), + }; + let pipeline_layout = wgc::gfx_select!(*device => instance.device_create_pipeline_layout( *device, - &wgc::binding_model::PipelineLayoutDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - bind_group_layouts: Cow::Owned( - args - .bind_group_layouts - .iter() - .map(|rid| { - state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::>(), - ), - push_constant_ranges: Default::default(), - }, - std::marker::PhantomData, - )?; + &descriptor, + std::marker::PhantomData + ))?; let rid = state .resource_table @@ -220,7 +226,7 @@ struct GPUBindGroupEntry { kind: String, resource: u32, offset: Option, - size: Option, + size: Option, } #[derive(Deserialize)] @@ -230,7 +236,7 @@ struct CreateBindGroupArgs { device_rid: u32, label: Option, layout: u32, - entries: [GPUBindGroupEntry], + entries: Vec, } pub fn op_webgpu_create_bind_group( @@ -249,55 +255,54 @@ pub fn op_webgpu_create_bind_group( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let bind_group = instance.device_create_bind_group( - *device, - &wgc::binding_model::BindGroupDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - layout: *state - .resource_table - .get_mut::(args.layout) - .ok_or_else(bad_resource_id)?, - entries: Cow::Owned( - args - .entries - .iter() - .map(|entry| wgc::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.resource_kind { - &"GPUSampler" => wgc::binding_model::BindingResource::Sampler( + let descriptor = wgc::binding_model::BindGroupDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + layout: *state + .resource_table + .get_mut::(args.layout) + .ok_or_else(bad_resource_id)?, + entries: Cow::Owned( + args + .entries + .iter() + .map(|entry| wgc::binding_model::BindGroupEntry { + binding: entry.binding, + resource: match entry.kind.as_str() { + "GPUSampler" => wgc::binding_model::BindingResource::Sampler( + *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + ), + "GPUTextureView" => { + wgc::binding_model::BindingResource::TextureView( *state .resource_table - .get_mut::(entry.resource) + .get_mut::(entry.resource) .ok_or_else(bad_resource_id)?, - ), - &"GPUTextureView" => { - wgc::binding_model::BindingResource::TextureView( - *state - .resource_table - .get_mut::(entry.resource) - .ok_or_else(bad_resource_id)?, - ) - } - &"GPUBufferBinding" => { - wgc::binding_model::BindingResource::Buffer( - wgc::binding_model::BufferBinding { - buffer_id: *state - .resource_table - .get_mut::(entry.resource) - .ok_or_else(bad_resource_id)?, - offset: entry.offset.unwrap_or(0), - size: entry.size, - }, - ) - } - _ => unreachable!(), - }, - }) - .collect::>(), - ), - }, - std::marker::PhantomData, - )?; + ) + } + "GPUBufferBinding" => wgc::binding_model::BindingResource::Buffer( + wgc::binding_model::BufferBinding { + buffer_id: *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + offset: entry.offset.unwrap_or(0), + size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), + }, + ), + _ => unreachable!(), + }, + }) + .collect::>(), + ), + }; + let bind_group = wgc::gfx_select!(*device => instance.device_create_bind_group( + *device, + &descriptor, + std::marker::PhantomData + ))?; let rid = state .resource_table diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 01a7742d1301e6..d545756cf945f0 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -2,6 +2,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; +use deno_core::futures::channel::oneshot; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::BufVec; @@ -18,7 +19,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_create_buffer", op_webgpu_create_buffer, ); - super::super::reg_json_sync( + super::super::reg_json_async( rt, "op_webgpu_buffer_get_map_async", op_webgpu_buffer_get_map_async, @@ -62,16 +63,17 @@ pub fn op_webgpu_create_buffer( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let buffer = instance.device_create_buffer( + let descriptor = wgc::resource::BufferDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + size: args.size, + usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), + mapped_at_creation: args.mapped_at_creation.unwrap_or(false), + }; + let buffer = wgc::gfx_select!(*device => instance.device_create_buffer( *device, - &wgc::resource::BufferDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - size: args.size, - usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), - mapped_at_creation: args.mapped_at_creation.unwrap_or(false), - }, - std::marker::PhantomData, - )?; + &descriptor, + std::marker::PhantomData + ))?; let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); @@ -107,6 +109,18 @@ pub async fn op_webgpu_buffer_get_map_async( .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; + let (sender, receiver) = oneshot::channel::>(); + + extern "C" fn buffer_map_future_wrapper( + status: wgc::resource::BufferMapAsyncStatus, + user_data: *mut u8, + ) { + sender.send(match status { + wgc::resource::BufferMapAsyncStatus::Success => Ok(()), + _ => Err(()), // TODO + }); + } + instance.buffer_map_async( *buffer, args.offset..args.size, @@ -116,11 +130,13 @@ pub async fn op_webgpu_buffer_get_map_async( 2 => wgc::device::HostMap::Read, _ => unreachable!(), }, - callback: (), // TODO - user_data: (), // TODO + callback: buffer_map_future_wrapper, + user_data: std::ptr::null_mut(), }, )?; + receiver.await??; + Ok(json!({})) } @@ -130,7 +146,7 @@ struct BufferGetMappedRangeArgs { instance_rid: u32, buffer_rid: u32, offset: u64, - size: std::num::NonZeroU64, + size: u64, } pub fn op_webgpu_buffer_get_mapped_range( @@ -149,9 +165,16 @@ pub fn op_webgpu_buffer_get_mapped_range( .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; + let slice_pointer = wgc::gfx_select!(*buffer => instance.buffer_get_mapped_range( + *buffer, + args.offset, + std::num::NonZeroU64::new(args.size) + ))?; + // TODO: use - let slice_pointer = - instance.buffer_get_mapped_range(*buffer, args.offset, Some(args.size))?; + let slice = unsafe { + std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) + }; Ok(json!({})) } @@ -179,7 +202,7 @@ pub fn op_webgpu_buffer_unmap( .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - instance.buffer_unmap(*buffer)?; + wgc::gfx_select!(*buffer => instance.buffer_unmap(*buffer))?; Ok(json!({})) } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index d9bfff8a535f6c..fbdfaf1c677445 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -1,8 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::texture::serialize_texture_format; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -78,7 +78,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { struct CreateRenderBundleEncoderArgs { device_rid: u32, label: Option, - color_formats: [String], + color_formats: Vec, depth_stencil_format: Option, sample_count: Option, } @@ -95,24 +95,23 @@ pub fn op_webgpu_create_render_bundle_encoder( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = wgc::command::RenderBundleEncoder::new( - &wgc::command::RenderBundleEncoderDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - color_formats: Cow::Owned( - args - .color_formats - .iter() - .map(|format| serialize_texture_format(format.clone())?) - .collect::>(), - ), - depth_stencil_format: args - .depth_stencil_format - .map(|format| serialize_texture_format(format)?), - sample_count: args.sample_count.unwrap_or(1), - }, - *device, - None, - )?; + let descriptor = wgc::command::RenderBundleEncoderDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + color_formats: Cow::Owned( + args + .color_formats + .iter() + .map(|format| serialize_texture_format(format.clone())?) + .collect::>(), + ), + depth_stencil_format: args + .depth_stencil_format + .map(serialize_texture_format) + .transpose()?, + sample_count: args.sample_count.unwrap_or(1), + }; + let render_bundle_encoder = + wgc::command::RenderBundleEncoder::new(&descriptor, *device, None)?; let rid = state .resource_table @@ -149,13 +148,13 @@ pub fn op_webgpu_render_bundle_encoder_finish( ) .ok_or_else(bad_resource_id)?; - let render_bundle = instance.render_bundle_encoder_finish( - render_bundle_encoder, // TODO + let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + *render_bundle_encoder, &wgc::command::RenderBundleDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), + label: args.label.map(|label| Cow::Owned(label)), }, - std::marker::PhantomData, - )?; + std::marker::PhantomData + ))?; let rid = state .resource_table @@ -172,8 +171,8 @@ struct RenderBundleEncoderSetBindGroupArgs { render_bundle_encoder_rid: u32, index: u32, bind_group: u32, - dynamic_offsets_data: Option<[u32]>, - dynamic_offsets_data_start: u64, + dynamic_offsets_data: Option>, + dynamic_offsets_data_start: usize, dynamic_offsets_data_length: usize, } @@ -186,7 +185,9 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( let render_bundle_encoder = state .resource_table - .get_mut::(args.compute_pass_rid) + .get_mut::( + args.render_bundle_encoder_rid, + ) .ok_or_else(bad_resource_id)?; unsafe { @@ -371,11 +372,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( .get_mut::(args.buffer) .ok_or_else(bad_resource_id)?, args.offset, - if args.size == 0 { - None - } else { - Some(args.size as std::num::NonZeroU64) - }, + std::num::NonZeroU64::new(args.size), ); Ok(json!({})) @@ -414,11 +411,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( .get_mut::(args.buffer) .ok_or_else(bad_resource_id)?, args.offset, - if args.size == 0 { - None - } else { - Some(args.size as std::num::NonZeroU64) - }, + std::num::NonZeroU64::new(args.size), ); Ok(json!({})) diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 5148ac46547b34..dafdf3325dda2e 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -68,9 +68,9 @@ pub fn init(rt: &mut deno_core::JsRuntime) { } fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { - match store_op { - &"store" => wgc::command::StoreOp::Store, - &"clear" => wgc::command::StoreOp::Clear, + match store_op.as_str() { + "store" => wgc::command::StoreOp::Store, + "clear" => wgc::command::StoreOp::Clear, _ => unreachable!(), } } @@ -100,13 +100,14 @@ pub fn op_webgpu_create_command_encoder( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = instance.device_create_command_encoder( + let descriptor = wgt::CommandEncoderDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + }; + let command_encoder = wgc::gfx_select!(*device => instance.device_create_command_encoder( *device, - &wgt::CommandEncoderDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - }, - std::marker::PhantomData, - )?; + &descriptor, + std::marker::PhantomData + ))?; let rid = state .resource_table @@ -141,10 +142,9 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderBeginRenderPassArgs { - instance_rid: u32, command_encoder_rid: u32, label: Option, // wgpu#974 - color_attachments: [GPURenderPassColorAttachmentDescriptor], + color_attachments: Vec, depth_stencil_attachment: Option, occlusion_query_set: u32, // wgpu#721 @@ -157,10 +157,6 @@ pub fn op_webgpu_command_encoder_begin_render_pass( ) -> Result { let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table .get_mut::(args.command_encoder_rid) @@ -179,12 +175,15 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .resource_table .get_mut::(color_attachment.attachment) .ok_or_else(bad_resource_id)?, - resolve_target: color_attachment.resolve_target.map(|rid| { - *state - .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id)? - }), + resolve_target: color_attachment + .resolve_target + .map(|rid| { + *state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id) + }) + .transpose()?, channel: wgc::command::PassChannel { load_op: LoadOp::Clear, // TODO store_op: color_attachment @@ -240,7 +239,6 @@ pub fn op_webgpu_command_encoder_begin_render_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderBeginComputePassArgs { - instance_rid: u32, command_encoder_rid: u32, label: Option, // wgpu#974 } @@ -252,10 +250,6 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( ) -> Result { let args: CommandEncoderBeginComputePassArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; let command_encoder = state .resource_table .get_mut::(args.command_encoder_rid) @@ -301,20 +295,22 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_copy_buffer_to_buffer( + let source = *state + .resource_table + .get_mut::(args.source) + .ok_or_else(bad_resource_id)?; + let destination = *state + .resource_table + .get_mut::(args.destination) + .ok_or_else(bad_resource_id)?; + wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_buffer_to_buffer( *command_encoder, - *state - .resource_table - .get_mut::(args.source) - .ok_or_else(bad_resource_id)?, + source, args.source_offset, - *state - .resource_table - .get_mut::(args.destination) - .ok_or_else(bad_resource_id)?, + destination, args.destination_offset, - args.size, - )?; + args.size + ))?; Ok(json!({})) } @@ -371,40 +367,42 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_copy_buffer_to_texture( - *command_encoder, - &wgc::command::BufferCopyView { - buffer: *state - .resource_table - .get_mut::(args.source.buffer) - .ok_or_else(bad_resource_id)?, - layout: wgt::TextureDataLayout { - offset: args.source.offset.unwrap_or(0), - bytes_per_row: args.source.bytes_per_row, // TODO: default value? - rows_per_image: args.source.rows_per_image, // TODO: default value? - }, - }, - &wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgt::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), + let source = wgc::command::BufferCopyView { + buffer: *state + .resource_table + .get_mut::(args.source.buffer) + .ok_or_else(bad_resource_id)?, + layout: wgt::TextureDataLayout { + offset: args.source.offset.unwrap_or(0), + bytes_per_row: args.source.bytes_per_row.unwrap_or(0), + rows_per_image: args.source.rows_per_image.unwrap_or(0), }, + }; + let destination = wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + }), + }; + wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_buffer_to_texture( + *command_encoder, + &source, + &destination, &wgt::Extent3d { width: args.copy_size.width, height: args.copy_size.height, depth: args.copy_size.depth, - }, - )?; + } + ))?; Ok(json!({})) } @@ -436,39 +434,41 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_copy_texture_to_buffer( - *command_encoder, - &wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.source.texture) - .ok_or_else(bad_resource_id)?, - mip_level: args.source.mip_level.unwrap_or(0), - origin: args.source.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - } - }), - }, - &wgc::command::BufferCopyView { - buffer: *state - .resource_table - .get_mut::(args.destination.buffer) - .ok_or_else(bad_resource_id)?, - layout: wgt::TextureDataLayout { - offset: args.destination.offset.unwrap_or(0), - bytes_per_row: args.destination.bytes_per_row, // TODO: default value? - rows_per_image: args.destination.rows_per_image, // TODO: default value? - }, + let source = wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.source.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.source.mip_level.unwrap_or(0), + origin: args.source.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), + }; + let destination = wgc::command::BufferCopyView { + buffer: *state + .resource_table + .get_mut::(args.destination.buffer) + .ok_or_else(bad_resource_id)?, + layout: wgt::TextureDataLayout { + offset: args.destination.offset.unwrap_or(0), + bytes_per_row: args.destination.bytes_per_row.unwrap_or(0), + rows_per_image: args.destination.rows_per_image.unwrap_or(0), }, + }; + wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_texture_to_buffer( + *command_encoder, + &source, + &destination, &wgt::Extent3d { width: args.copy_size.width, height: args.copy_size.height, depth: args.copy_size.depth, - }, - )?; + } + ))?; Ok(json!({})) } @@ -500,43 +500,45 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_copy_texture_to_texture( - *command_encoder, - &wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.source.texture) - .ok_or_else(bad_resource_id)?, - mip_level: args.source.mip_level.unwrap_or(0), - origin: args.source.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - } + let source = wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.source.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.source.mip_level.unwrap_or(0), + origin: args.source.origin.map_or(Default::default(), |origin| { + wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + } + }), + }; + let destination = wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), }), - }, - &wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgt::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), - }, + }; + wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_texture_to_texture( + *command_encoder, + &source, + &destination, &wgt::Extent3d { width: args.copy_size.width, height: args.copy_size.height, depth: args.copy_size.depth, - }, - )?; + } + ))?; Ok(json!({})) } @@ -565,8 +567,8 @@ pub fn op_webgpu_command_encoder_push_debug_group( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance - .command_encoder_push_debug_group(*command_encoder, &args.group_label)?; + wgc::gfx_select!(*command_encoder => instance + .command_encoder_push_debug_group(*command_encoder, &args.group_label))?; Ok(json!({})) } @@ -594,7 +596,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_pop_debug_group(*command_encoder)?; + wgc::gfx_select!(*command_encoder => instance.command_encoder_pop_debug_group(*command_encoder))?; Ok(json!({})) } @@ -623,10 +625,10 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_insert_debug_marker( + wgc::gfx_select!(*command_encoder => instance.command_encoder_insert_debug_marker( *command_encoder, - &args.marker_label, - )?; + &args.marker_label + ))?; Ok(json!({})) } @@ -655,12 +657,13 @@ pub fn op_webgpu_command_encoder_finish( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_buffer = instance.command_encoder_finish( + let descriptor = wgt::CommandBufferDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + }; + let command_buffer = wgc::gfx_select!(*command_encoder => instance.command_encoder_finish( *command_encoder, - &wgt::CommandBufferDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - }, - )?; + &descriptor + ))?; let rid = state .resource_table diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index fc685278a3019d..40e1fe1c8451cd 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -172,7 +172,10 @@ pub fn op_webgpu_compute_pass_end_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_run_compute_pass(*command_encoder, compute_pass); + wgc::gfx_select!(*command_encoder => instance.command_encoder_run_compute_pass( + *command_encoder, + compute_pass + ))?; Ok(json!({})) } @@ -183,8 +186,8 @@ struct ComputePassSetBindGroupArgs { compute_pass_rid: u32, index: u32, bind_group: u32, - dynamic_offsets_data: Option<[u32]>, - dynamic_offsets_data_start: u64, + dynamic_offsets_data: Option>, + dynamic_offsets_data_start: usize, dynamic_offsets_data_length: usize, } diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 648334f9602b40..151c00f55103a9 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -53,33 +53,17 @@ pub fn init(rt: &mut deno_core::JsRuntime) { shader::init(rt); } -fn serialize_features(features: &wgt::Features) -> Vec<&str> { - let mut extensions: Vec<&str> = vec![]; +fn deserialize_features(features: &wgt::Features) -> Vec<&str> { + let mut return_features: Vec<&str> = vec![]; if features.contains(wgt::Features::DEPTH_CLAMPING) { - extensions.push("depth-clamping"); - } - if features.contains(wgt::Features) { - // TODO - extensions.push("depth24unorm-stencil8"); - } - if features.contains(wgt::Features) { - // TODO - extensions.push("depth32float-stencil8"); - } - if features.contains(wgt::Features) { - // TODO - extensions.push("pipeline-statistics-query"); + return_features.push("depth-clamping"); } if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) { - extensions.push("texture-compression-bc"); - } - if features.contains(wgt::Features) { - // TODO - extensions.push("timestamp-query"); + return_features.push("texture-compression-bc"); } - extensions + return_features } pub type WgcInstance = wgc::hub::Global; @@ -124,25 +108,30 @@ pub async fn op_webgpu_request_adapter( .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let adapter = instance.request_adapter( - &wgc::instance::RequestAdapterOptions { - power_preference: match args.power_preference { - Some(&"low-power") => wgt::PowerPreference::LowPower, - Some(&"high-performance") => wgt::PowerPreference::HighPerformance, - Some(_) => unreachable!(), - None => wgt::PowerPreference::Default, + let descriptor = wgc::instance::RequestAdapterOptions { + power_preference: match args.power_preference { + Some(power_preference) => match power_preference.as_str() { + "low-power" => wgt::PowerPreference::LowPower, + "high-performance" => wgt::PowerPreference::HighPerformance, + _ => unreachable!(), }, - compatible_surface: None, // windowless + None => wgt::PowerPreference::Default, }, - wgc::instance::AdapterInputs::Mask(wgt::BackendBit::PRIMARY, ()), // TODO + compatible_surface: None, // windowless + }; + let adapter = instance.request_adapter( + &descriptor, + wgc::instance::AdapterInputs::Mask(wgt::BackendBit::PRIMARY, |_| { + std::marker::PhantomData + }), )?; - let name = instance.adapter_get_info(adapter)?.name; - let features = serialize_features(&instance.adapter_features(adapter)?); + let name = + wgc::gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; + let adapter_features = + wgc::gfx_select!(adapter => instance.adapter_features(adapter))?; + let features = deserialize_features(&adapter_features); - let rid = state - .resource_table - .add("webGPUInstance", Box::new(instance)); let rid = state.resource_table.add("webGPUAdapter", Box::new(adapter)); Ok(json!({ @@ -155,16 +144,15 @@ pub async fn op_webgpu_request_adapter( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GPULimits { - // TODO: each should be Option - max_bind_groups: u32, - max_dynamic_uniform_buffers_per_pipeline_layout: u32, - max_dynamic_storage_buffers_per_pipeline_layout: u32, - max_sampled_textures_per_shader_stage: u32, - max_samplers_per_shader_stage: u32, - max_storage_buffers_per_shader_stage: u32, - max_storage_textures_per_shader_stage: u32, - max_uniform_buffers_per_shader_stage: u32, - max_uniform_buffer_binding_size: u32, + max_bind_groups: Option, + max_dynamic_uniform_buffers_per_pipeline_layout: Option, + max_dynamic_storage_buffers_per_pipeline_layout: Option, + max_sampled_textures_per_shader_stage: Option, + max_samplers_per_shader_stage: Option, + max_storage_buffers_per_shader_stage: Option, + max_storage_textures_per_shader_stage: Option, + max_uniform_buffers_per_shader_stage: Option, + max_uniform_buffer_binding_size: Option, } #[derive(Deserialize)] @@ -173,7 +161,7 @@ struct RequestDeviceArgs { instance_rid: u32, adapter_rid: u32, label: Option, // wgpu#976 - features: Option<[String]>, + features: Option>, limits: Option, } @@ -194,38 +182,61 @@ pub async fn op_webgpu_request_device( .get_mut::(args.adapter_rid) .ok_or_else(bad_resource_id)?; - let device = instance.adapter_request_device( - *adapter, - &wgt::DeviceDescriptor { - features: Default::default(), // TODO - limits: args.limits.map_or(Default::default(), |limits| { - wgt::Limits { - max_bind_groups: limits.max_bind_groups, - max_dynamic_uniform_buffers_per_pipeline_layout: limits - .max_dynamic_uniform_buffers_per_pipeline_layout, - max_dynamic_storage_buffers_per_pipeline_layout: limits - .max_dynamic_storage_buffers_per_pipeline_layout, - max_sampled_textures_per_shader_stage: limits - .max_sampled_textures_per_shader_stage, - max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage, - max_storage_buffers_per_shader_stage: limits - .max_storage_buffers_per_shader_stage, - max_storage_textures_per_shader_stage: limits - .max_storage_textures_per_shader_stage, - max_uniform_buffers_per_shader_stage: limits - .max_uniform_buffers_per_shader_stage, - max_uniform_buffer_binding_size: limits - .max_uniform_buffer_binding_size, - max_push_constant_size: 0, // TODO - } + let mut features = wgt::Features::default(); + + if let Some(passed_features) = args.features { + if passed_features.contains(&"depth-clamping".to_string()) { + features.set(wgt::Features::DEPTH_CLAMPING, true); + } + if passed_features.contains(&"texture-compression-bc".to_string()) { + features.set(wgt::Features::TEXTURE_COMPRESSION_BC, true); + } + } + + let descriptor = wgt::DeviceDescriptor { + features, + limits: args + .limits + .map_or(Default::default(), |limits| wgt::Limits { + max_bind_groups: limits.max_bind_groups.unwrap_or(4), + max_dynamic_uniform_buffers_per_pipeline_layout: limits + .max_dynamic_uniform_buffers_per_pipeline_layout + .unwrap_or(8), + max_dynamic_storage_buffers_per_pipeline_layout: limits + .max_dynamic_storage_buffers_per_pipeline_layout + .unwrap_or(4), + max_sampled_textures_per_shader_stage: limits + .max_sampled_textures_per_shader_stage + .unwrap_or(16), + max_samplers_per_shader_stage: limits + .max_samplers_per_shader_stage + .unwrap_or(16), + max_storage_buffers_per_shader_stage: limits + .max_storage_buffers_per_shader_stage + .unwrap_or(4), + max_storage_textures_per_shader_stage: limits + .max_storage_textures_per_shader_stage + .unwrap_or(4), + max_uniform_buffers_per_shader_stage: limits + .max_uniform_buffers_per_shader_stage + .unwrap_or(12), + max_uniform_buffer_binding_size: limits + .max_uniform_buffer_binding_size + .unwrap_or(16384), + max_push_constant_size: 0, }), - shader_validation: false, // TODO - }, + shader_validation: false, + }; + let device = wgc::gfx_select!(*adapter => instance.adapter_request_device( + *adapter, + &descriptor, None, - std::marker::PhantomData, - )?; + std::marker::PhantomData + ))?; - let features = serialize_features(&instance.device_features(device)?); + let device_features = + wgc::gfx_select!(device => instance.device_features(device))?; + let features = deserialize_features(&device_features); let limits = instance.device_limits(device)?; let json_limits = json!({ "max_bind_groups": limits.max_bind_groups, diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index c6a152f19ac29d..8974d4590bc9e0 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -2,8 +2,8 @@ use super::sampler::serialize_compare_function; use super::texture::serialize_texture_format; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -48,15 +48,15 @@ fn serialize_programmable_stage_descriptor( } fn serialize_stencil_operation(operation: String) -> wgt::StencilOperation { - match operation { - &"keep" => wgt::StencilOperation::Keep, - &"zero" => wgt::StencilOperation::Zero, - &"replace" => wgt::StencilOperation::Replace, - &"invert" => wgt::StencilOperation::Invert, - &"increment-clamp" => wgt::StencilOperation::IncrementClamp, - &"decrement-clamp" => wgt::StencilOperation::DecrementClamp, - &"increment-wrap" => wgt::StencilOperation::IncrementWrap, - &"decrement-wrap" => wgt::StencilOperation::DecrementWrap, + match operation.as_str() { + "keep" => wgt::StencilOperation::Keep, + "zero" => wgt::StencilOperation::Zero, + "replace" => wgt::StencilOperation::Replace, + "invert" => wgt::StencilOperation::Invert, + "increment-clamp" => wgt::StencilOperation::IncrementClamp, + "decrement-clamp" => wgt::StencilOperation::DecrementClamp, + "increment-wrap" => wgt::StencilOperation::IncrementWrap, + "decrement-wrap" => wgt::StencilOperation::DecrementWrap, _ => unreachable!(), } } @@ -81,20 +81,20 @@ fn serialize_stencil_state_face_descriptor( } fn serialize_blend_factor(blend_factor: String) -> wgt::BlendFactor { - match blend_factor { - &"zero" => wgt::BlendFactor::Zero, - &"one" => wgt::BlendFactor::One, - &"src-color" => wgt::BlendFactor::SrcColor, - &"one-minus-src-color" => wgt::BlendFactor::OneMinusSrcColor, - &"src-alpha" => wgt::BlendFactor::SrcAlpha, - &"one-minus-src-alpha" => wgt::BlendFactor::OneMinusSrcAlpha, - &"dst-color" => wgt::BlendFactor::DstColor, - &"one-minus-dst-color" => wgt::BlendFactor::OneMinusDstColor, - &"dst-alpha" => wgt::BlendFactor::DstAlpha, - &"one-minus-dst-alpha" => wgt::BlendFactor::OneMinusDstAlpha, - &"src-alpha-saturated" => wgt::BlendFactor::SrcAlphaSaturated, - &"blend-color" => wgt::BlendFactor::BlendColor, - &"one-minus-blend-color" => wgt::BlendFactor::OneMinusBlendColor, + match blend_factor.as_str() { + "zero" => wgt::BlendFactor::Zero, + "one" => wgt::BlendFactor::One, + "src-color" => wgt::BlendFactor::SrcColor, + "one-minus-src-color" => wgt::BlendFactor::OneMinusSrcColor, + "src-alpha" => wgt::BlendFactor::SrcAlpha, + "one-minus-src-alpha" => wgt::BlendFactor::OneMinusSrcAlpha, + "dst-color" => wgt::BlendFactor::DstColor, + "one-minus-dst-color" => wgt::BlendFactor::OneMinusDstColor, + "dst-alpha" => wgt::BlendFactor::DstAlpha, + "one-minus-dst-alpha" => wgt::BlendFactor::OneMinusDstAlpha, + "src-alpha-saturated" => wgt::BlendFactor::SrcAlphaSaturated, + "blend-color" => wgt::BlendFactor::BlendColor, + "one-minus-blend-color" => wgt::BlendFactor::OneMinusBlendColor, _ => unreachable!(), } } @@ -110,12 +110,14 @@ fn serialize_blend_descriptor( .dst_factor .map_or(wgt::BlendFactor::Zero, serialize_blend_factor), operation: match blend.operation { - Some(&"add") => wgt::BlendOperation::Add, - Some(&"subtract") => wgt::BlendOperation::Subtract, - Some(&"reverse-subtract") => wgt::BlendOperation::ReverseSubtract, - Some(&"min") => wgt::BlendOperation::Min, - Some(&"max") => wgt::BlendOperation::Max, - Some(_) => unreachable!(), + Some(operation) => match operation.as_str() { + "add" => wgt::BlendOperation::Add, + "subtract" => wgt::BlendOperation::Subtract, + "reverse-subtract" => wgt::BlendOperation::ReverseSubtract, + "min" => wgt::BlendOperation::Min, + "max" => wgt::BlendOperation::Max, + _ => unreachable!(), + }, None => wgt::BlendOperation::Add, }, } @@ -154,31 +156,35 @@ pub fn op_webgpu_create_compute_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let (compute_pipeline, _) = instance.device_create_compute_pipeline( - *device, - &wgc::pipeline::ComputePipelineDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - layout: args.layout.map(|rid| { + let descriptor = wgc::pipeline::ComputePipelineDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + layout: args + .layout + .map(|rid| { *state .resource_table .get_mut::(rid) - .ok_or_else(bad_resource_id)? - }), - compute_stage: serialize_programmable_stage_descriptor( - state, - args.compute_stage, - )?, - }, + .ok_or_else(bad_resource_id) + }) + .transpose()?, + compute_stage: serialize_programmable_stage_descriptor( + state, + args.compute_stage, + )?, + }; + let implicit_pipelines = match args.layout { + Some(_) => None, + None => Some(wgc::device::ImplicitPipelineIds { + root_id: std::marker::PhantomData, + group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + }), + }; + let (compute_pipeline, _) = wgc::gfx_select!(*device => instance.device_create_compute_pipeline( + *device, + &descriptor, std::marker::PhantomData, - match args.layout { - // TODO: check - Some(_) => None, - None => Some(wgc::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], - }), - }, - )?; + implicit_pipelines + ))?; let rid = state .resource_table @@ -214,8 +220,8 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .get_mut::(args.compute_pipeline_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = instance - .compute_pipeline_get_bind_group_layout(*compute_pipeline, args.index)?; + let bind_group_layout = wgc::gfx_select!(*compute_pipeline => instance + .compute_pipeline_get_bind_group_layout(*compute_pipeline, args.index))?; let rid = state .resource_table @@ -288,14 +294,14 @@ struct GPUVertexAttributeDescriptor { struct GPUVertexBufferLayoutDescriptor { array_stride: u64, step_mode: Option, - attributes: [GPUVertexAttributeDescriptor], + attributes: Vec, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GPUVertexStateDescriptor { index_format: Option, - vertex_buffers: Option<[GPUVertexBufferLayoutDescriptor]>, // TODO: nullable + vertex_buffers: Option>, // ODO: nullable } #[derive(Deserialize)] @@ -309,7 +315,7 @@ struct CreateRenderPipelineArgs { fragment_stage: Option, primitive_topology: String, rasterization_state: Option, - color_states: [GPUColorStateDescriptor], + color_states: Vec, depth_stencil_state: Option, vertex_state: Option, sample_count: Option, @@ -333,186 +339,202 @@ pub fn op_webgpu_create_render_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let (render_pipeline, _) = instance.device_create_render_pipeline( - *device, - &wgc::pipeline::RenderPipelineDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - layout: args.layout.map(|rid| { + let descriptor = wgc::pipeline::RenderPipelineDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + layout: args + .layout + .map(|rid| { *state .resource_table .get_mut::(rid) - .ok_or_else(bad_resource_id)? - }), - vertex_stage: serialize_programmable_stage_descriptor( - state, - args.vertex_stage, - )?, - fragment_stage: args.fragment_stage.map( - |programmable_stage_descriptor| { - serialize_programmable_stage_descriptor( - state, - programmable_stage_descriptor, - )? - }, - ), - rasterization_state: args.rasterization_state.map( - |rasterization_state| wgt::RasterizationStateDescriptor { - front_face: match rasterization_state.front_face { - Some(&"ccw") => wgt::FrontFace::Ccw, - Some(&"cw") => wgt::FrontFace::Cw, - Some(_) => unreachable!(), - None => wgt::FrontFace::Ccw, + .ok_or_else(bad_resource_id) + }) + .transpose()?, + vertex_stage: serialize_programmable_stage_descriptor( + state, + args.vertex_stage, + )?, + fragment_stage: args + .fragment_stage + .map(|programmable_stage_descriptor| { + serialize_programmable_stage_descriptor( + state, + programmable_stage_descriptor, + ) + }) + .transpose()?, + rasterization_state: args.rasterization_state.map(|rasterization_state| { + wgt::RasterizationStateDescriptor { + front_face: match rasterization_state.front_face { + Some(front_face) => match front_face.as_str() { + "ccw" => wgt::FrontFace::Ccw, + "cw" => wgt::FrontFace::Cw, + _ => unreachable!(), }, - cull_mode: match rasterization_state.cull_mode { - Some(&"none") => wgt::CullMode::None, - Some(&"front") => wgt::CullMode::Front, - Some(&"back") => wgt::CullMode::Back, - Some(_) => unreachable!(), - None => wgt::CullMode::None, + None => wgt::FrontFace::Ccw, + }, + cull_mode: match rasterization_state.cull_mode { + Some(cull_mode) => match cull_mode.as_str() { + "none" => wgt::CullMode::None, + "front" => wgt::CullMode::Front, + "back" => wgt::CullMode::Back, + _ => unreachable!(), }, - clamp_depth: rasterization_state.clamp_depth.unwrap_or(false), - depth_bias: rasterization_state.depth_bias.unwrap_or(0), - depth_bias_slope_scale: rasterization_state - .depth_bias_slope_scale - .unwrap_or(0.0), - depth_bias_clamp: rasterization_state.depth_bias_clamp.unwrap_or(0.0), + None => wgt::CullMode::None, }, - ), - primitive_topology: match args.primitive_topology { - &"point-list" => wgt::PrimitiveTopology::PointList, - &"line-list" => wgt::PrimitiveTopology::LineList, - &"line-strip" => wgt::PrimitiveTopology::LineStrip, - &"triangle-list" => wgt::PrimitiveTopology::TriangleList, - &"triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, - _ => unreachable!(), + clamp_depth: rasterization_state.clamp_depth.unwrap_or(false), + depth_bias: rasterization_state.depth_bias.unwrap_or(0), + depth_bias_slope_scale: rasterization_state + .depth_bias_slope_scale + .unwrap_or(0.0), + depth_bias_clamp: rasterization_state.depth_bias_clamp.unwrap_or(0.0), + } + }), + primitive_topology: match args.primitive_topology.as_str() { + "point-list" => wgt::PrimitiveTopology::PointList, + "line-list" => wgt::PrimitiveTopology::LineList, + "line-strip" => wgt::PrimitiveTopology::LineStrip, + "triangle-list" => wgt::PrimitiveTopology::TriangleList, + "triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, + _ => unreachable!(), + }, + color_states: Cow::Owned( + args + .color_states + .iter() + .map(|color_state| wgt::ColorStateDescriptor { + format: serialize_texture_format(color_state.format.clone())?, + alpha_blend: color_state + .alpha_blend + .map_or(Default::default(), serialize_blend_descriptor), + color_blend: color_state + .color_blend + .map_or(Default::default(), serialize_blend_descriptor), + write_mask: color_state + .write_mask + .map_or(Default::default(), |mask| { + wgt::ColorWrite::from_bits(mask).unwrap() + }), + }) + .collect::>(), + ), + depth_stencil_state: args.depth_stencil_state.map(|state| { + wgt::DepthStencilStateDescriptor { + format: serialize_texture_format(state.format)?, + depth_write_enabled: state.depth_write_enabled.unwrap_or(false), + depth_compare: state + .depth_compare + .map_or(wgt::CompareFunction::Always, serialize_compare_function), + stencil: wgt::StencilStateDescriptor { + front: state.stencil_front.map_or( + wgt::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), + back: state.stencil_front.map_or( + wgt::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), + read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), + write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), + }, + } + }), + vertex_state: args.vertex_state.map_or( + wgc::pipeline::VertexStateDescriptor { + index_format: Default::default(), + vertex_buffers: Default::default(), }, - color_states: Cow::Owned( - args - .color_states - .iter() - .map(|color_state| wgt::ColorStateDescriptor { - format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state - .alpha_blend - .map_or(Default::default(), serialize_blend_descriptor), - color_blend: color_state - .color_blend - .map_or(Default::default(), serialize_blend_descriptor), - write_mask: color_state - .write_mask - .map_or(Default::default(), |mask| { - wgt::ColorWrite::from_bits(mask).unwrap() - }), - }) - .collect::>(), - ), - depth_stencil_state: args.depth_stencil_state.map(|state| { - wgt::DepthStencilStateDescriptor { - format: serialize_texture_format(state.format)?, - depth_write_enabled: state.depth_write_enabled.unwrap_or(false), - depth_compare: state - .depth_compare - .map_or(wgt::CompareFunction::Always, serialize_compare_function), - stencil: wgt::StencilStateDescriptor { - front: state.stencil_front.map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - back: state.stencil_front.map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), - write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), - }, - } - }), - // TODO: figure out default value - vertex_state: args.vertex_state.map_or("", |state| { - wgc::pipeline::VertexStateDescriptor { - // TODO: figure out default value - index_format: state.index_format.map_or("", |format| match format { - &"uint16" => wgt::IndexFormat::Uint16, - &"uint32" => wgt::IndexFormat::Uint32, + |state| wgc::pipeline::VertexStateDescriptor { + index_format: state.index_format.map_or(Default::default(), |format| { + match format.as_str() { + "uint16" => wgt::IndexFormat::Uint16, + "uint32" => wgt::IndexFormat::Uint32, _ => unreachable!(), - }), - vertex_buffers: Cow::Owned( - state - .vertex_buffers - .unwrap() // TODO: don't unwrap - .iter() - .map(|buffer| wgc::pipeline::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode { - Some(&"vertex") => wgt::InputStepMode::Vertex, - Some(&"instance") => wgt::InputStepMode::Instance, - Some(_) => unreachable!(), - None => wgt::InputStepMode::Vertex, - }, - attributes: Cow::Owned( - buffer - .attributes - .iter() - .map(|attribute| wgt::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format { - &"uchar2" => wgt::VertexFormat::Uchar2, - &"uchar4" => wgt::VertexFormat::Uchar4, - &"char2" => wgt::VertexFormat::Char2, - &"char4" => wgt::VertexFormat::Char4, - &"uchar2norm" => wgt::VertexFormat::Uchar2Norm, - &"uchar4norm" => wgt::VertexFormat::Uchar4, - &"char2norm" => wgt::VertexFormat::Char2Norm, - &"char4norm" => wgt::VertexFormat::Char4Norm, - &"ushort2" => wgt::VertexFormat::Ushort2, - &"ushort4" => wgt::VertexFormat::Ushort4, - &"short2" => wgt::VertexFormat::Short2, - &"short4" => wgt::VertexFormat::Short4, - &"ushort2norm" => wgt::VertexFormat::Ushort2Norm, - &"ushort4norm" => wgt::VertexFormat::Ushort4Norm, - &"short2norm" => wgt::VertexFormat::Short2Norm, - &"short4norm" => wgt::VertexFormat::Short4Norm, - &"half2" => wgt::VertexFormat::Half2, - &"half4" => wgt::VertexFormat::Half4, - &"float" => wgt::VertexFormat::Float, - &"float2" => wgt::VertexFormat::Float2, - &"float3" => wgt::VertexFormat::Float3, - &"float4" => wgt::VertexFormat::Float4, - &"uint" => wgt::VertexFormat::Uint, - &"uint2" => wgt::VertexFormat::Uint2, - &"uint3" => wgt::VertexFormat::Uint3, - &"uint4" => wgt::VertexFormat::Uint4, - &"int" => wgt::VertexFormat::Int, - &"int2" => wgt::VertexFormat::Int2, - &"int3" => wgt::VertexFormat::Int3, - &"int4" => wgt::VertexFormat::Int4, - _ => unreachable!(), - }, - shader_location: attribute.shader_location, - }) - .collect::>(), - ), - }) - .collect::>(), - ), - } - }), - sample_count: args.sample_count.unwrap_or(1), - sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), - alpha_to_coverage_enabled: args - .alpha_to_coverage_enabled - .unwrap_or(false), - }, + } + }), + vertex_buffers: state.vertex_buffers.map_or( + Default::default(), + |vertex_buffers| { + Cow::Owned( + vertex_buffers + .iter() + .map(|buffer| wgc::pipeline::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode.clone() { + Some(step_mode) => match step_mode.as_str() { + "vertex" => wgt::InputStepMode::Vertex, + "instance" => wgt::InputStepMode::Instance, + _ => unreachable!(), + }, + None => wgt::InputStepMode::Vertex, + }, + attributes: Cow::Owned( + buffer + .attributes + .iter() + .map(|attribute| wgt::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format.as_str() { + "uchar2" => wgt::VertexFormat::Uchar2, + "uchar4" => wgt::VertexFormat::Uchar4, + "char2" => wgt::VertexFormat::Char2, + "char4" => wgt::VertexFormat::Char4, + "uchar2norm" => wgt::VertexFormat::Uchar2Norm, + "uchar4norm" => wgt::VertexFormat::Uchar4, + "char2norm" => wgt::VertexFormat::Char2Norm, + "char4norm" => wgt::VertexFormat::Char4Norm, + "ushort2" => wgt::VertexFormat::Ushort2, + "ushort4" => wgt::VertexFormat::Ushort4, + "short2" => wgt::VertexFormat::Short2, + "short4" => wgt::VertexFormat::Short4, + "ushort2norm" => wgt::VertexFormat::Ushort2Norm, + "ushort4norm" => wgt::VertexFormat::Ushort4Norm, + "short2norm" => wgt::VertexFormat::Short2Norm, + "short4norm" => wgt::VertexFormat::Short4Norm, + "half2" => wgt::VertexFormat::Half2, + "half4" => wgt::VertexFormat::Half4, + "float" => wgt::VertexFormat::Float, + "float2" => wgt::VertexFormat::Float2, + "float3" => wgt::VertexFormat::Float3, + "float4" => wgt::VertexFormat::Float4, + "uint" => wgt::VertexFormat::Uint, + "uint2" => wgt::VertexFormat::Uint2, + "uint3" => wgt::VertexFormat::Uint3, + "uint4" => wgt::VertexFormat::Uint4, + "int" => wgt::VertexFormat::Int, + "int2" => wgt::VertexFormat::Int2, + "int3" => wgt::VertexFormat::Int3, + "int4" => wgt::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::>(), + ), + }) + .collect::>(), + ) + }, + ), + }, + ), + sample_count: args.sample_count.unwrap_or(1), + sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), + alpha_to_coverage_enabled: args.alpha_to_coverage_enabled.unwrap_or(false), + }; + let implicit_pipelines = match args.layout { + Some(_) => None, + None => Some(wgc::device::ImplicitPipelineIds { + root_id: std::marker::PhantomData, + group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + }), + }; + let (render_pipeline, _) = wgc::gfx_select!(*device => instance.device_create_render_pipeline( + *device, + &descriptor, std::marker::PhantomData, - match args.layout { - // TODO: check - Some(_) => None, - None => Some(wgc::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], - }), - }, - )?; + implicit_pipelines + ))?; let rid = state .resource_table @@ -548,8 +570,8 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .get_mut::(args.render_pipeline_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = instance - .render_pipeline_get_bind_group_layout(*render_pipeline, args.index)?; + let bind_group_layout = wgc::gfx_select!(*render_pipeline => instance + .render_pipeline_get_bind_group_layout(*render_pipeline, args.index))?; let rid = state .resource_table diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index 2108660f9be82a..3949fdc4123b35 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -31,7 +31,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { struct QueueSubmitArgs { instance_rid: u32, queue_rid: u32, - command_buffers: [u32], + command_buffers: Vec, } pub fn op_webgpu_queue_submit( @@ -50,19 +50,18 @@ pub fn op_webgpu_queue_submit( .get_mut::(args.queue_rid) .ok_or_else(bad_resource_id)?; - instance.queue_submit( - *queue, - &args - .command_buffers - .iter() - .map(|rid| { - *state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::<[wgc::id::CommandBufferId]>(), - )?; + let ids = args + .command_buffers + .iter() + .map(|rid| { + *state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)? + }) + .collect::>(); + + wgc::gfx_select!(*queue => instance.queue_submit(*queue, &ids))?; Ok(json!({})) } @@ -82,8 +81,8 @@ struct QueueWriteBufferArgs { queue_rid: u32, buffer: u32, buffer_offset: u64, - data_offset: u64, - size: Option, + data_offset: usize, + size: Option, } pub fn op_webgpu_write_buffer( @@ -102,18 +101,20 @@ pub fn op_webgpu_write_buffer( .get_mut::(args.queue_rid) .ok_or_else(bad_resource_id)?; - instance.queue_write_buffer( + let buffer = state + .resource_table + .get_mut::(args.buffer) + .ok_or_else(bad_resource_id)?; + let data = match args.size { + Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], + None => &zero_copy[0][args.data_offset..], + }; + wgc::gfx_select!(*queue => instance.queue_write_buffer( *queue, - *state - .resource_table - .get_mut::(args.buffer) - .ok_or_else(bad_resource_id)?, + *buffer, args.buffer_offset, - match args.size { - Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], - None => &zero_copy[0][args.data_offset..], - }, - )?; + data + ))?; Ok(json!({})) } @@ -144,35 +145,37 @@ pub fn op_webgpu_write_texture( .get_mut::(args.queue_rid) .ok_or_else(bad_resource_id)?; - instance.queue_write_texture( + let destination = wgc::command::TextureCopyView { + texture: *state + .resource_table + .get_mut::(args.destination.texture) + .ok_or_else(bad_resource_id)?, + mip_level: args.destination.mip_level.unwrap_or(0), + origin: args + .destination + .origin + .map_or(Default::default(), |origin| wgt::Origin3d { + x: origin.x.unwrap_or(0), + y: origin.y.unwrap_or(0), + z: origin.z.unwrap_or(0), + }), + }; + let data_layout = wgt::TextureDataLayout { + offset: args.data_layout.offset.unwrap_or(0), + bytes_per_row: args.data_layout.bytes_per_row.unwrap_or(0), + rows_per_image: args.data_layout.rows_per_image.unwrap_or(0), + }; + wgc::gfx_select!(*queue => instance.queue_write_texture( *queue, - &wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgt::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), - }, + &destination, &*zero_copy[0], - &wgt::TextureDataLayout { - offset: args.data_layout.offset.unwrap_or(0), - bytes_per_row: args.data_layout.bytes_per_row, - rows_per_image: args.data_layout.rows_per_image, - }, + &data_layout, &wgt::Extent3d { width: args.size.width, height: args.size.height, depth: args.size.depth, - }, - )?; + } + ))?; Ok(json!({})) } diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index fdcdee55795493..77ad8263b43475 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -238,7 +238,7 @@ pub fn op_webgpu_render_pass_set_stencil_reference( #[serde(rename_all = "camelCase")] struct RenderPassExecuteBundlesArgs { render_pass_rid: u32, - bundles: [u32], + bundles: Vec, } pub fn op_webgpu_render_pass_execute_bundles( @@ -265,7 +265,7 @@ pub fn op_webgpu_render_pass_execute_bundles( .get_mut::(*rid) .ok_or_else(bad_resource_id)? }) - .collect::<[wgc::id::RenderBundleId]>() + .collect::>() .as_ptr(), args.bundles.len(), ); @@ -302,7 +302,7 @@ pub fn op_webgpu_render_pass_end_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - instance.command_encoder_run_render_pass(*command_encoder, render_pass)?; + wgc::gfx_select!(*command_encoder => instance.command_encoder_run_render_pass(*command_encoder, render_pass))?; Ok(json!({})) } @@ -313,8 +313,8 @@ struct RenderPassSetBindGroupArgs { render_pass_rid: u32, index: u32, bind_group: u32, - dynamic_offsets_data: Option<[u32]>, - dynamic_offsets_data_start: u64, + dynamic_offsets_data: Option>, + dynamic_offsets_data_start: usize, dynamic_offsets_data_length: usize, } @@ -496,11 +496,7 @@ pub fn op_webgpu_render_pass_set_index_buffer( .get_mut::(args.buffer) .ok_or_else(bad_resource_id)?, args.offset, - if args.size == 0 { - None - } else { - Some(args.size as std::num::NonZeroU64) - }, + std::num::NonZeroU64::new(args.size), ); Ok(json!({})) @@ -536,11 +532,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( .get_mut::(args.buffer) .ok_or_else(bad_resource_id)?, args.offset, - if args.size == 0 { - None - } else { - Some(args.size as std::num::NonZeroU64) - }, + std::num::NonZeroU64::new(args.size), ); Ok(json!({})) diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 05d9d8b747f5ae..d0c70229c12ed7 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -19,33 +19,37 @@ pub fn init(rt: &mut deno_core::JsRuntime) { fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { match address_mode { - Some(&"clamp-to-edge") => wgt::AddressMode::ClampToEdge, - Some(&"repeat") => wgt::AddressMode::Repeat, - Some(&"mirror-repeat") => wgt::AddressMode::MirrorRepeat, - Some(_) => unreachable!(), + Some(address_mode) => match address_mode.as_str() { + "clamp-to-edge" => wgt::AddressMode::ClampToEdge, + "repeat" => wgt::AddressMode::Repeat, + "mirror-repeat" => wgt::AddressMode::MirrorRepeat, + _ => unreachable!(), + }, None => wgt::AddressMode::ClampToEdge, } } fn serialize_filter_mode(filter_mode: Option) -> wgt::FilterMode { match filter_mode { - Some(&"nearest") => wgt::FilterMode::Nearest, - Some(&"linear") => wgt::FilterMode::Linear, - Some(_) => unreachable!(), + Some(filter_mode) => match filter_mode.as_str() { + "nearest" => wgt::FilterMode::Nearest, + "linear" => wgt::FilterMode::Linear, + _ => unreachable!(), + }, None => wgt::FilterMode::Nearest, } } pub fn serialize_compare_function(compare: String) -> wgt::CompareFunction { - match compare { - &"never" => wgt::CompareFunction::Never, - &"less" => wgt::CompareFunction::Less, - &"equal" => wgt::CompareFunction::Equal, - &"less-equal" => wgt::CompareFunction::LessEqual, - &"greater" => wgt::CompareFunction::Greater, - &"not-equal" => wgt::CompareFunction::NotEqual, - &"greater-equal" => wgt::CompareFunction::GreaterEqual, - &"always" => wgt::CompareFunction::Always, + match compare.as_str() { + "never" => wgt::CompareFunction::Never, + "less" => wgt::CompareFunction::Less, + "equal" => wgt::CompareFunction::Equal, + "less-equal" => wgt::CompareFunction::LessEqual, + "greater" => wgt::CompareFunction::Greater, + "not-equal" => wgt::CompareFunction::NotEqual, + "greater-equal" => wgt::CompareFunction::GreaterEqual, + "always" => wgt::CompareFunction::Always, _ => unreachable!(), } } @@ -84,25 +88,28 @@ pub fn op_webgpu_create_sampler( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let sampler = instance.device_create_sampler( + let descriptor = wgc::resource::SamplerDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + address_modes: [ + serialize_address_mode(args.address_mode_u), + serialize_address_mode(args.address_mode_v), + serialize_address_mode(args.address_mode_w), + ], + mag_filter: serialize_filter_mode(args.mag_filter), + min_filter: serialize_filter_mode(args.min_filter), + mipmap_filter: serialize_filter_mode(args.mipmap_filter), + lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), + lod_max_clamp: args + .lod_max_clamp + .unwrap_or(wgc::resource::SamplerDescriptor::default().lod_max_clamp), + compare: args.compare.map(serialize_compare_function), + anisotropy_clamp: args.max_anisotropy, + }; + let sampler = wgc::gfx_select!(*device => instance.device_create_sampler( *device, - &wgc::resource::SamplerDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - address_modes: [ - serialize_address_mode(args.address_mode_u), - serialize_address_mode(args.address_mode_v), - serialize_address_mode(args.address_mode_w), - ], - mag_filter: serialize_filter_mode(args.mag_filter), - min_filter: serialize_filter_mode(args.min_filter), - mipmap_filter: serialize_filter_mode(args.mipmap_filter), - lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args.lod_max_clamp.unwrap_or(f32::MAX), // TODO: check - compare: args.compare.map(serialize_compare_function), - anisotropy_clamp: args.max_anisotropy, - }, - std::marker::PhantomData, - )?; + &descriptor, + std::marker::PhantomData + ))?; let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index c6404f79a157c3..63c692e8109ef8 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -43,19 +43,20 @@ pub fn op_webgpu_create_shader_module( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let shader_module = instance.device_create_shader_module( + let source = match args.code { + Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), + None => wgc::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data + })), + }; + let shader_module = wgc::gfx_select!(*device => instance.device_create_shader_module( *device, - match args.code { - Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), - None => wgc::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { - let (prefix, data, suffix) = zero_copy[0].align_to::(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data - })), - }, - std::marker::PhantomData, - )?; + source, + std::marker::PhantomData + ))?; let rid = state .resource_table diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index c6090d64fb88a3..82d19cb9ebcb77 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -25,95 +25,95 @@ pub fn init(rt: &mut deno_core::JsRuntime) { pub fn serialize_texture_format( format: String, ) -> Result { - Ok(match format { + Ok(match format.as_str() { // 8-bit formats - &"r8unorm" => wgt::TextureFormat::R8Unorm, - &"r8snorm" => wgt::TextureFormat::R8Snorm, - &"r8uint" => wgt::TextureFormat::R8Uint, - &"r8sint" => wgt::TextureFormat::R8Sint, + "r8unorm" => wgt::TextureFormat::R8Unorm, + "r8snorm" => wgt::TextureFormat::R8Snorm, + "r8uint" => wgt::TextureFormat::R8Uint, + "r8sint" => wgt::TextureFormat::R8Sint, // 16-bit formats - &"r16uint" => wgt::TextureFormat::R16Uint, - &"r16sint" => wgt::TextureFormat::R16Sint, - &"r16float" => wgt::TextureFormat::R16Float, - &"rg8unorm" => wgt::TextureFormat::Rg8Unorm, - &"rg8snorm" => wgt::TextureFormat::Rg8Snorm, - &"rg8uint" => wgt::TextureFormat::Rg8Uint, - &"rg8sint" => wgt::TextureFormat::Rg8Sint, + "r16uint" => wgt::TextureFormat::R16Uint, + "r16sint" => wgt::TextureFormat::R16Sint, + "r16float" => wgt::TextureFormat::R16Float, + "rg8unorm" => wgt::TextureFormat::Rg8Unorm, + "rg8snorm" => wgt::TextureFormat::Rg8Snorm, + "rg8uint" => wgt::TextureFormat::Rg8Uint, + "rg8sint" => wgt::TextureFormat::Rg8Sint, // 32-bit formats - &"r32uint" => wgt::TextureFormat::R32Uint, - &"r32sint" => wgt::TextureFormat::R32Sint, - &"r32float" => wgt::TextureFormat::R32Float, - &"rg16uint" => wgt::TextureFormat::Rg16Uint, - &"rg16sint" => wgt::TextureFormat::Rg16Sint, - &"rg16float" => wgt::TextureFormat::Rg16Float, - &"rgba8unorm" => wgt::TextureFormat::Rgba8Unorm, - &"rgba8unorm-srgb" => wgt::TextureFormat::Rgba8UnormSrgb, - &"rgba8snorm" => wgt::TextureFormat::Rgba8Snorm, - &"rgba8uint" => wgt::TextureFormat::Rgba8Uint, - &"rgba8sint" => wgt::TextureFormat::Rgba8Sint, - &"bgra8unorm" => wgt::TextureFormat::Bgra8Unorm, - &"bgra8unorm-srgb" => wgt::TextureFormat::Bgra8UnormSrgb, + "r32uint" => wgt::TextureFormat::R32Uint, + "r32sint" => wgt::TextureFormat::R32Sint, + "r32float" => wgt::TextureFormat::R32Float, + "rg16uint" => wgt::TextureFormat::Rg16Uint, + "rg16sint" => wgt::TextureFormat::Rg16Sint, + "rg16float" => wgt::TextureFormat::Rg16Float, + "rgba8unorm" => wgt::TextureFormat::Rgba8Unorm, + "rgba8unorm-srgb" => wgt::TextureFormat::Rgba8UnormSrgb, + "rgba8snorm" => wgt::TextureFormat::Rgba8Snorm, + "rgba8uint" => wgt::TextureFormat::Rgba8Uint, + "rgba8sint" => wgt::TextureFormat::Rgba8Sint, + "bgra8unorm" => wgt::TextureFormat::Bgra8Unorm, + "bgra8unorm-srgb" => wgt::TextureFormat::Bgra8UnormSrgb, // Packed 32-bit formats - &"rgb9e5ufloat" => return Err(not_supported()), // wgpu#967 - &"rgb10a2unorm" => wgt::TextureFormat::Rgb10a2Unorm, - &"rg11b10ufloat" => wgt::TextureFormat::Rg11b10Float, + "rgb9e5ufloat" => return Err(not_supported()), // wgpu#967 + "rgb10a2unorm" => wgt::TextureFormat::Rgb10a2Unorm, + "rg11b10ufloat" => wgt::TextureFormat::Rg11b10Float, // 64-bit formats - &"rg32uint" => wgt::TextureFormat::Rg32Uint, - &"rg32sint" => wgt::TextureFormat::Rg32Sint, - &"rg32float" => wgt::TextureFormat::Rg32Float, - &"rgba16uint" => wgt::TextureFormat::Rgba16Uint, - &"rgba16sint" => wgt::TextureFormat::Rgba16Sint, - &"rgba16float" => wgt::TextureFormat::Rgba16Float, + "rg32uint" => wgt::TextureFormat::Rg32Uint, + "rg32sint" => wgt::TextureFormat::Rg32Sint, + "rg32float" => wgt::TextureFormat::Rg32Float, + "rgba16uint" => wgt::TextureFormat::Rgba16Uint, + "rgba16sint" => wgt::TextureFormat::Rgba16Sint, + "rgba16float" => wgt::TextureFormat::Rgba16Float, // 128-bit formats - &"rgba32uint" => wgt::TextureFormat::Rgba32Uint, - &"rgba32sint" => wgt::TextureFormat::Rgba32Sint, - &"rgba32float" => wgt::TextureFormat::Rgba32Float, + "rgba32uint" => wgt::TextureFormat::Rgba32Uint, + "rgba32sint" => wgt::TextureFormat::Rgba32Sint, + "rgba32float" => wgt::TextureFormat::Rgba32Float, // Depth and stencil formats - &"stencil8" => return Err(not_supported()), // wgpu#967 - &"depth16unorm" => return Err(not_supported()), // wgpu#967 - &"depth24plus" => wgt::TextureFormat::Depth24Plus, - &"depth24plus-stencil8" => wgt::TextureFormat::Depth24PlusStencil8, - &"depth32float" => wgt::TextureFormat::Depth32Float, + "stencil8" => return Err(not_supported()), // wgpu#967 + "depth16unorm" => return Err(not_supported()), // wgpu#967 + "depth24plus" => wgt::TextureFormat::Depth24Plus, + "depth24plus-stencil8" => wgt::TextureFormat::Depth24PlusStencil8, + "depth32float" => wgt::TextureFormat::Depth32Float, // BC compressed formats usable if "texture-compression-bc" is both // supported by the device/user agent and enabled in requestDevice. - &"bc1-rgba-unorm" => wgt::TextureFormat::Bc1RgbaUnorm, - &"bc1-rgba-unorm-srgb" => wgt::TextureFormat::Bc1RgbaUnormSrgb, - &"bc2-rgba-unorm" => wgt::TextureFormat::Bc2RgbaUnorm, - &"bc2-rgba-unorm-srgb" => wgt::TextureFormat::Bc2RgbaUnormSrgb, - &"bc3-rgba-unorm" => wgt::TextureFormat::Bc3RgbaUnorm, - &"bc3-rgba-unorm-srgb" => wgt::TextureFormat::Bc3RgbaUnormSrgb, - &"bc4-r-unorm" => wgt::TextureFormat::Bc4RUnorm, - &"bc4-r-snorm" => wgt::TextureFormat::Bc4RSnorm, - &"bc5-rg-unorm" => wgt::TextureFormat::Bc5RgUnorm, - &"bc5-rg-snorm" => wgt::TextureFormat::Bc5RgSnorm, - &"bc6h-rgb-ufloat" => wgt::TextureFormat::Bc6hRgbUfloat, - &"bc6h-rgb-float" => wgt::TextureFormat::Bc6hRgbSfloat, // wgpu#967 - &"bc7-rgba-unorm" => wgt::TextureFormat::Bc7RgbaUnorm, - &"bc7-rgba-unorm-srgb" => wgt::TextureFormat::Bc7RgbaUnormSrgb, + "bc1-rgba-unorm" => wgt::TextureFormat::Bc1RgbaUnorm, + "bc1-rgba-unorm-srgb" => wgt::TextureFormat::Bc1RgbaUnormSrgb, + "bc2-rgba-unorm" => wgt::TextureFormat::Bc2RgbaUnorm, + "bc2-rgba-unorm-srgb" => wgt::TextureFormat::Bc2RgbaUnormSrgb, + "bc3-rgba-unorm" => wgt::TextureFormat::Bc3RgbaUnorm, + "bc3-rgba-unorm-srgb" => wgt::TextureFormat::Bc3RgbaUnormSrgb, + "bc4-r-unorm" => wgt::TextureFormat::Bc4RUnorm, + "bc4-r-snorm" => wgt::TextureFormat::Bc4RSnorm, + "bc5-rg-unorm" => wgt::TextureFormat::Bc5RgUnorm, + "bc5-rg-snorm" => wgt::TextureFormat::Bc5RgSnorm, + "bc6h-rgb-ufloat" => wgt::TextureFormat::Bc6hRgbUfloat, + "bc6h-rgb-float" => wgt::TextureFormat::Bc6hRgbSfloat, // wgpu#967 + "bc7-rgba-unorm" => wgt::TextureFormat::Bc7RgbaUnorm, + "bc7-rgba-unorm-srgb" => wgt::TextureFormat::Bc7RgbaUnormSrgb, // "depth24unorm-stencil8" extension - &"depth24unorm-stencil8" => return Err(not_supported()), // wgpu#967 + "depth24unorm-stencil8" => return Err(not_supported()), // wgpu#967 // "depth32float-stencil8" extension - &"depth32float-stencil8" => return Err(not_supported()), // wgpu#967 + "depth32float-stencil8" => return Err(not_supported()), // wgpu#967 _ => unreachable!(), }) } pub fn serialize_dimension(dimension: String) -> wgt::TextureViewDimension { - match dimension { - &"1d" => wgt::TextureViewDimension::D1, - &"2d" => wgt::TextureViewDimension::D2, - &"2d-array" => wgt::TextureViewDimension::D2Array, - &"cube" => wgt::TextureViewDimension::Cube, - &"cube-array" => wgt::TextureViewDimension::CubeArray, - &"3d" => wgt::TextureViewDimension::D3, + match dimension.as_str() { + "1d" => wgt::TextureViewDimension::D1, + "2d" => wgt::TextureViewDimension::D2, + "2d-array" => wgt::TextureViewDimension::D2Array, + "cube" => wgt::TextureViewDimension::Cube, + "cube-array" => wgt::TextureViewDimension::CubeArray, + "3d" => wgt::TextureViewDimension::D3, _ => unreachable!(), } } @@ -156,29 +156,33 @@ pub fn op_webgpu_create_texture( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; - let texture = instance.device_create_texture( - *device, - &wgc::resource::TextureDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - size: wgt::Extent3d { - width: args.size.width, - height: args.size.height, - depth: args.size.depth, - }, - mip_level_count: args.mip_level_count.unwrap_or(1), - sample_count: args.sample_count.unwrap_or(1), - dimension: match args.dimension { - Some(&"1d") => wgt::TextureDimension::D1, - Some(&"2d") => wgt::TextureDimension::D2, - Some(&"3d") => wgt::TextureDimension::D3, - Some(_) => unreachable!(), - None => wgt::TextureDimension::D2, + let descriptor = wgc::resource::TextureDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + size: wgt::Extent3d { + width: args.size.width, + height: args.size.height, + depth: args.size.depth, + }, + mip_level_count: args.mip_level_count.unwrap_or(1), + sample_count: args.sample_count.unwrap_or(1), + dimension: match args.dimension { + Some(dimension) => match dimension.as_str() { + "1d" => wgt::TextureDimension::D1, + "2d" => wgt::TextureDimension::D2, + "3d" => wgt::TextureDimension::D3, + _ => unreachable!(), }, - format: serialize_texture_format(args.format)?, - usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), + None => wgt::TextureDimension::D2, }, - std::marker::PhantomData, - )?; + format: serialize_texture_format(args.format)?, + usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), + }; + + let texture = wgc::gfx_select!(*device => instance.device_create_texture( + *device, + &descriptor, + std::marker::PhantomData + ))?; let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); @@ -197,9 +201,9 @@ struct CreateTextureViewArgs { dimension: Option, aspect: Option, base_mip_level: Option, - mip_level_count: Option, + mip_level_count: Option, base_array_layer: Option, - array_layer_count: Option, + array_layer_count: Option, } pub fn op_webgpu_create_texture_view( @@ -218,28 +222,33 @@ pub fn op_webgpu_create_texture_view( .get_mut::(args.texture_rid) .ok_or_else(bad_resource_id)?; - let texture_view = instance.texture_create_view( - *texture, - &wgc::resource::TextureViewDescriptor { - label: args.label.map(|label| Cow::Borrowed(&label)), - format: args.format.map(|format| serialize_texture_format(format)?), - dimension: args - .dimension - .map(|dimension| serialize_dimension(dimension)), - aspect: match args.aspect { - Some(&"all") => wgt::TextureAspect::All, - Some(&"stencil-only") => wgt::TextureAspect::StencilOnly, - Some(&"depth-only") => wgt::TextureAspect::DepthOnly, - Some(_) => unreachable!(), - None => wgt::TextureAspect::All, + let descriptor = wgc::resource::TextureViewDescriptor { + label: args.label.map(|label| Cow::Owned(label)), + format: args.format.map(serialize_texture_format).transpose()?, + dimension: args + .dimension + .map(|dimension| serialize_dimension(dimension)), + aspect: match args.aspect { + Some(aspect) => match aspect.as_str() { + "all" => wgt::TextureAspect::All, + "stencil-only" => wgt::TextureAspect::StencilOnly, + "depth-only" => wgt::TextureAspect::DepthOnly, + _ => unreachable!(), }, - base_mip_level: args.base_mip_level.unwrap_or(0), - level_count: args.mip_level_count, - base_array_layer: args.base_array_layer.unwrap_or(0), - array_layer_count: args.array_layer_count, + None => wgt::TextureAspect::All, }, - std::marker::PhantomData, - )?; + base_mip_level: args.base_mip_level.unwrap_or(0), + level_count: std::num::NonZeroU32::new(args.mip_level_count.unwrap_or(0)), + base_array_layer: args.base_array_layer.unwrap_or(0), + array_layer_count: std::num::NonZeroU32::new( + args.array_layer_count.unwrap_or(0), + ), + }; + let texture_view = wgc::gfx_select!(*texture => instance.texture_create_view( + *texture, + &descriptor, + std::marker::PhantomData + ))?; let rid = state .resource_table diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 3f7cd39630dee1..17a87d8dc2786f 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -82,7 +82,10 @@ }, ); - return new GPUDevice(this, rid, data); + return new GPUDevice(this, rid, { + label: descriptor.label, + ...data, + }); } } @@ -113,7 +116,8 @@ this.#rid = rid; this.#features = Object.freeze(data.features); this.#limits = data.limits; - this.#defaultQueue = new GPUQueue(rid); // TODO: label? + this.#defaultQueue = new GPUQueue(rid, data.label); + this.label = data.label; } createBuffer(descriptor) { @@ -542,7 +546,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_render_pass", { - instanceRid, commandEncoderRid: this.#rid, ...descriptor, }, @@ -555,7 +558,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_compute_pass", { - instanceRid, commandEncoderRid: this.#rid, ...descriptor, }, From ef57dcf660aca07a6b2f0c7cc3ca2978b90e6d4e Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:56:20 +0200 Subject: [PATCH 021/144] cleanup --- cli/ops/webgpu/command_encoder.rs | 5 +++-- cli/ops/webgpu/mod.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index dafdf3325dda2e..682cda4e1afa87 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -178,12 +178,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass( resolve_target: color_attachment .resolve_target .map(|rid| { - *state + state .resource_table .get_mut::(rid) .ok_or_else(bad_resource_id) }) - .transpose()?, + .transpose()? + .map(|texture| *texture), channel: wgc::command::PassChannel { load_op: LoadOp::Clear, // TODO store_op: color_attachment diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 151c00f55103a9..05bd04e768dd9a 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -237,7 +237,7 @@ pub async fn op_webgpu_request_device( let device_features = wgc::gfx_select!(device => instance.device_features(device))?; let features = deserialize_features(&device_features); - let limits = instance.device_limits(device)?; + let limits = wgc::gfx_select!(device => instance.device_limits(device))?; let json_limits = json!({ "max_bind_groups": limits.max_bind_groups, "max_dynamic_uniform_buffers_per_pipeline_layout": limits.max_dynamic_uniform_buffers_per_pipeline_layout, From 4f270c90f161e3f7029029df59f1a8c0aa051e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Oct 2020 23:10:18 +0200 Subject: [PATCH 022/144] fix most of compiler errors --- cli/ops/webgpu/binding.rs | 225 +++++++++++++++--------------- cli/ops/webgpu/bundle.rs | 14 +- cli/ops/webgpu/command_encoder.rs | 118 ++++++++-------- cli/ops/webgpu/pipeline.rs | 125 +++++++++-------- cli/ops/webgpu/queue.rs | 19 ++- cli/ops/webgpu/render_pass.rs | 22 +-- 6 files changed, 262 insertions(+), 261 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 8db28c5e8211c2..0c22e48927e860 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -79,74 +79,73 @@ pub fn op_webgpu_create_bind_group_layout( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let mut entries = vec![]; + + for entry in &args.entries { + let e = wgt::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), + ty: match entry.kind.as_str() { + "uniform-buffer" => wgt::BindingType::UniformBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + }, + "storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + readonly: false, + }, + "readonly-storage-buffer" => wgt::BindingType::StorageBuffer { + dynamic: entry.has_dynamic_offset.unwrap_or(false), + min_binding_size: std::num::NonZeroU64::new( + entry.min_buffer_binding_size.unwrap_or(0), + ), + readonly: true, + }, + "sampler" => wgt::BindingType::Sampler { comparison: false }, + "comparison-sampler" => wgt::BindingType::Sampler { comparison: true }, + "sampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: false, + }, + "multisampled-texture" => wgt::BindingType::SampledTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + component_type: serialize_texture_component_type( + entry.texture_component_type.unwrap(), + )?, + multisampled: true, + }, + "readonly-storage-texture" => wgt::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, + readonly: true, + }, + "writeonly-storage-texture" => wgt::BindingType::StorageTexture { + dimension: serialize_dimension(entry.view_dimension.unwrap()), + format: serialize_texture_format( + entry.storage_texture_format.unwrap(), + )?, + readonly: false, + }, + _ => unreachable!(), + }, + count: None, + }; + entries.push(e); + } + let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { label: args.label.map(|label| Cow::Owned(label)), - entries: Cow::Owned( - args - .entries - .iter() - .map(|entry| wgt::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), - ty: match entry.kind.as_str() { - "uniform-buffer" => wgt::BindingType::UniformBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - }, - "storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - readonly: false, - }, - "readonly-storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - readonly: true, - }, - "sampler" => wgt::BindingType::Sampler { comparison: false }, - "comparison-sampler" => { - wgt::BindingType::Sampler { comparison: true } - } - "sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, - multisampled: false, - }, - "multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), - )?, - multisampled: true, - }, - "readonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: true, - }, - "writeonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.unwrap(), - )?, - readonly: false, - }, - _ => unreachable!(), - }, - count: None, - }) - .collect::>(), - ), + entries: Cow::Owned(entries), }; let bind_group_layout = wgc::gfx_select!(*device => instance.device_create_bind_group_layout( *device, @@ -188,20 +187,19 @@ pub fn op_webgpu_create_pipeline_layout( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let mut bind_group_layouts = vec![]; + + for rid in &args.bind_group_layouts { + let id = state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)?; + bind_group_layouts.push(*id); + } + let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(|label| Cow::Owned(label)), - bind_group_layouts: Cow::Owned( - args - .bind_group_layouts - .iter() - .map(|rid| { - state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::>(), - ), + bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; let pipeline_layout = wgc::gfx_select!(*device => instance.device_create_pipeline_layout( @@ -255,48 +253,47 @@ pub fn op_webgpu_create_bind_group( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let mut entries = vec![]; + + for entry in &args.entries { + let e = wgc::binding_model::BindGroupEntry { + binding: entry.binding, + resource: match entry.kind.as_str() { + "GPUSampler" => wgc::binding_model::BindingResource::Sampler( + *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + ), + "GPUTextureView" => wgc::binding_model::BindingResource::TextureView( + *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + ), + "GPUBufferBinding" => wgc::binding_model::BindingResource::Buffer( + wgc::binding_model::BufferBinding { + buffer_id: *state + .resource_table + .get_mut::(entry.resource) + .ok_or_else(bad_resource_id)?, + offset: entry.offset.unwrap_or(0), + size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), + }, + ), + _ => unreachable!(), + }, + }; + entries.push(e); + } + let descriptor = wgc::binding_model::BindGroupDescriptor { label: args.label.map(|label| Cow::Owned(label)), layout: *state .resource_table .get_mut::(args.layout) .ok_or_else(bad_resource_id)?, - entries: Cow::Owned( - args - .entries - .iter() - .map(|entry| wgc::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.kind.as_str() { - "GPUSampler" => wgc::binding_model::BindingResource::Sampler( - *state - .resource_table - .get_mut::(entry.resource) - .ok_or_else(bad_resource_id)?, - ), - "GPUTextureView" => { - wgc::binding_model::BindingResource::TextureView( - *state - .resource_table - .get_mut::(entry.resource) - .ok_or_else(bad_resource_id)?, - ) - } - "GPUBufferBinding" => wgc::binding_model::BindingResource::Buffer( - wgc::binding_model::BufferBinding { - buffer_id: *state - .resource_table - .get_mut::(entry.resource) - .ok_or_else(bad_resource_id)?, - offset: entry.offset.unwrap_or(0), - size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), - }, - ), - _ => unreachable!(), - }, - }) - .collect::>(), - ), + entries: Cow::Owned(entries), }; let bind_group = wgc::gfx_select!(*device => instance.device_create_bind_group( *device, diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index fbdfaf1c677445..e18e02c1307c19 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -95,15 +95,15 @@ pub fn op_webgpu_create_render_bundle_encoder( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let mut color_formats = vec![]; + + for format in &args.color_formats { + color_formats.push(serialize_texture_format(format.clone())?); + } + let descriptor = wgc::command::RenderBundleEncoderDescriptor { label: args.label.map(|label| Cow::Owned(label)), - color_formats: Cow::Owned( - args - .color_formats - .iter() - .map(|format| serialize_texture_format(format.clone())?) - .collect::>(), - ), + color_formats: Cow::Owned(color_formats), depth_stencil_format: args .depth_stencil_format .map(serialize_texture_format) diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 682cda4e1afa87..6a569daf8232f3 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -162,69 +162,67 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .get_mut::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; + let mut color_attachments = vec![]; + + for color_attachment in args.color_attachments { + let attachment = wgc::command::ColorAttachmentDescriptor { + attachment: *state + .resource_table + .get_mut::(color_attachment.attachment) + .ok_or_else(bad_resource_id)?, + resolve_target: color_attachment + .resolve_target + .map(|rid| { + state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id) + }) + .transpose()? + .map(|texture| *texture), + channel: wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, // TODO + store_op: color_attachment + .store_op + .map_or(wgc::command::StoreOp::Store, serialize_store_op), + clear_value: (), // TODO + read_only: false, // TODO + }, + }; + + color_attachments.push(attachment) + } + + let mut depth_stencil_attachment = None; + + if let Some(attachment) = args.depth_stencil_attachment { + let attachment = wgc::command::DepthStencilAttachmentDescriptor { + attachment: *state + .resource_table + .get_mut::(attachment.attachment) + .ok_or_else(bad_resource_id)?, + depth: wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, // TODO + store_op: serialize_store_op(attachment.depth_store_op), + clear_value: (), // TODO + read_only: false, // TODO + }, + stencil: wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, // TODO + store_op: serialize_store_op(attachment.stencil_store_op), + clear_value: (), // TODO + read_only: false, // TODO + }, + }; + + depth_stencil_attachment = Some(attachment); + } + let render_pass = wgc::command::RenderPass::new( *command_encoder, wgc::command::RenderPassDescriptor { - color_attachments: Cow::Owned( - args - .color_attachments - .iter() - .map(|color_attachment| { - wgc::command::ColorAttachmentDescriptor { - attachment: *state - .resource_table - .get_mut::(color_attachment.attachment) - .ok_or_else(bad_resource_id)?, - resolve_target: color_attachment - .resolve_target - .map(|rid| { - state - .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id) - }) - .transpose()? - .map(|texture| *texture), - channel: wgc::command::PassChannel { - load_op: LoadOp::Clear, // TODO - store_op: color_attachment - .store_op - .map_or(wgc::command::StoreOp::Store, serialize_store_op), - clear_value: (), // TODO - read_only: false, // TODO - }, - } - }) - .collect::>(), - ), - depth_stencil_attachment: args.depth_stencil_attachment.map( - |depth_stencil_attachment| { - &wgc::command::DepthStencilAttachmentDescriptor { - attachment: *state - .resource_table - .get_mut::( - depth_stencil_attachment.attachment, - ) - .ok_or_else(bad_resource_id)?, - depth: wgc::command::PassChannel { - load_op: LoadOp::Clear, // TODO - store_op: serialize_store_op( - depth_stencil_attachment.depth_store_op, - ), - clear_value: (), // TODO - read_only: false, // TODO - }, - stencil: wgc::command::PassChannel { - load_op: LoadOp::Clear, // TODO - store_op: serialize_store_op( - depth_stencil_attachment.stencil_store_op, - ), - clear_value: (), // TODO - read_only: false, // TODO - }, - } - }, - ), + color_attachments: Cow::Owned(color_attachments), + depth_stencil_attachment: depth_stencil_attachment.as_ref(), }, ); diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 8974d4590bc9e0..3f77234016dca4 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -156,17 +156,19 @@ pub fn op_webgpu_create_compute_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let layout = if let Some(rid) = args.layout { + let id = state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)?; + Some(*id) + } else { + None + }; + let descriptor = wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), - layout: args - .layout - .map(|rid| { - *state - .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id) - }) - .transpose()?, + layout: layout.transpose()?, compute_stage: serialize_programmable_stage_descriptor( state, args.compute_stage, @@ -339,17 +341,61 @@ pub fn op_webgpu_create_render_pipeline( .get_mut::(args.device_rid) .ok_or_else(bad_resource_id)?; + let mut color_states = vec![]; + + for color_state in &args.color_states { + let state = wgt::ColorStateDescriptor { + format: serialize_texture_format(color_state.format.clone())?, + alpha_blend: color_state + .alpha_blend + .map_or(Default::default(), serialize_blend_descriptor), + color_blend: color_state + .color_blend + .map_or(Default::default(), serialize_blend_descriptor), + write_mask: color_state.write_mask.map_or(Default::default(), |mask| { + wgt::ColorWrite::from_bits(mask).unwrap() + }), + }; + color_states.push(state); + } + + let mut depth_stencil_state = None; + + if let Some(state) = &args.depth_stencil_state { + depth_stencil_state = Some(wgt::DepthStencilStateDescriptor { + format: serialize_texture_format(state.format)?, + depth_write_enabled: state.depth_write_enabled.unwrap_or(false), + depth_compare: state + .depth_compare + .map_or(wgt::CompareFunction::Always, serialize_compare_function), + stencil: wgt::StencilStateDescriptor { + front: state.stencil_front.map_or( + wgt::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), + back: state.stencil_front.map_or( + wgt::StencilStateFaceDescriptor::IGNORE, + serialize_stencil_state_face_descriptor, + ), + read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), + write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), + }, + }); + } + + let layout = if let Some(rid) = args.layout { + let id = state + .resource_table + .get_mut::(rid) + .ok_or_else(bad_resource_id)?; + Some(id) + } else { + None + }; + let descriptor = wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), - layout: args - .layout - .map(|rid| { - *state - .resource_table - .get_mut::(rid) - .ok_or_else(bad_resource_id) - }) - .transpose()?, + layout: layout.transpose()?, vertex_stage: serialize_programmable_stage_descriptor( state, args.vertex_stage, @@ -398,47 +444,8 @@ pub fn op_webgpu_create_render_pipeline( "triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, _ => unreachable!(), }, - color_states: Cow::Owned( - args - .color_states - .iter() - .map(|color_state| wgt::ColorStateDescriptor { - format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state - .alpha_blend - .map_or(Default::default(), serialize_blend_descriptor), - color_blend: color_state - .color_blend - .map_or(Default::default(), serialize_blend_descriptor), - write_mask: color_state - .write_mask - .map_or(Default::default(), |mask| { - wgt::ColorWrite::from_bits(mask).unwrap() - }), - }) - .collect::>(), - ), - depth_stencil_state: args.depth_stencil_state.map(|state| { - wgt::DepthStencilStateDescriptor { - format: serialize_texture_format(state.format)?, - depth_write_enabled: state.depth_write_enabled.unwrap_or(false), - depth_compare: state - .depth_compare - .map_or(wgt::CompareFunction::Always, serialize_compare_function), - stencil: wgt::StencilStateDescriptor { - front: state.stencil_front.map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - back: state.stencil_front.map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), - write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), - }, - } - }), + color_states: Cow::Owned(color_states), + depth_stencil_state, vertex_state: args.vertex_state.map_or( wgc::pipeline::VertexStateDescriptor { index_format: Default::default(), diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index 3949fdc4123b35..858b3f77fbd286 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -50,16 +50,15 @@ pub fn op_webgpu_queue_submit( .get_mut::(args.queue_rid) .ok_or_else(bad_resource_id)?; - let ids = args - .command_buffers - .iter() - .map(|rid| { - *state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::>(); + let mut ids = vec![]; + + for rid in &args.command_buffers { + let buffer_id = state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)?; + ids.push(*buffer_id); + } wgc::gfx_select!(*queue => instance.queue_submit(*queue, &ids))?; diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 77ad8263b43475..ba4dc709fe50a2 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -253,20 +253,20 @@ pub fn op_webgpu_render_pass_execute_bundles( .get_mut::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; + let mut render_bundle_ids = vec![]; + + for rid in &args.bundles { + let bundle_id = state + .resource_table + .get_mut::(*rid) + .ok_or_else(bad_resource_id)?; + render_bundle_ids.push(*bundle_id); + } + unsafe { wgc::command::render_ffi::wgpu_render_pass_execute_bundles( render_pass, - args - .bundles - .iter() - .map(|rid| { - *state - .resource_table - .get_mut::(*rid) - .ok_or_else(bad_resource_id)? - }) - .collect::>() - .as_ptr(), + render_bundle_ids.as_ptr(), args.bundles.len(), ); } From f4ae3ffd58595669a631cec839235a1b58d976ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Oct 2020 23:19:13 +0200 Subject: [PATCH 023/144] fix more compile errors --- cli/ops/webgpu/mod.rs | 12 ++++++------ cli/ops/webgpu/pipeline.rs | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 05bd04e768dd9a..7e5be7fb07b05d 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -173,13 +173,13 @@ pub async fn op_webgpu_request_device( let args: RequestDeviceArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); - let instance = state + let adapter = *state .resource_table - .get_mut::(args.instance_rid) + .get_mut::(args.adapter_rid) .ok_or_else(bad_resource_id)?; - let adapter = state + let instance = state .resource_table - .get_mut::(args.adapter_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let mut features = wgt::Features::default(); @@ -227,8 +227,8 @@ pub async fn op_webgpu_request_device( }), shader_validation: false, }; - let device = wgc::gfx_select!(*adapter => instance.adapter_request_device( - *adapter, + let device = wgc::gfx_select!(adapter => instance.adapter_request_device( + adapter, &descriptor, None, std::marker::PhantomData diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 3f77234016dca4..ad2023d433bba5 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -168,7 +168,7 @@ pub fn op_webgpu_create_compute_pipeline( let descriptor = wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), - layout: layout.transpose()?, + layout, compute_stage: serialize_programmable_stage_descriptor( state, args.compute_stage, @@ -388,14 +388,14 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get_mut::(rid) .ok_or_else(bad_resource_id)?; - Some(id) + Some(*id) } else { None }; let descriptor = wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), - layout: layout.transpose()?, + layout, vertex_stage: serialize_programmable_stage_descriptor( state, args.vertex_stage, From 7cf4a3516956bb66b9b59c1bc401896443e5a33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Oct 2020 23:35:31 +0200 Subject: [PATCH 024/144] fix more compile errors, part2 --- cli/ops/webgpu/buffer.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index d545756cf945f0..d3e765abd0e988 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -111,17 +111,33 @@ pub async fn op_webgpu_buffer_get_map_async( let (sender, receiver) = oneshot::channel::>(); + let boxed_sender = Box::new(sender); + let sender_ptr = Box::into_raw(boxed_sender); + let sender_ptr = unsafe { + std::mem::transmute::<*mut oneshot::Sender>, *mut u8>( + sender_ptr, + ) + }; + extern "C" fn buffer_map_future_wrapper( status: wgc::resource::BufferMapAsyncStatus, user_data: *mut u8, ) { - sender.send(match status { + let sender_ptr = unsafe { + std::mem::transmute::<*mut u8, *mut oneshot::Sender>>( + user_data, + ) + }; + let boxed_sender = Box::from_raw(sender_ptr); + boxed_sender.send(match status { wgc::resource::BufferMapAsyncStatus::Success => Ok(()), - _ => Err(()), // TODO + _ => unreachable!(), // TODO }); + drop(boxed_sender); } - instance.buffer_map_async( + // TODO: get "device" + wgc::gfx_select!(device => instance.buffer_map_async( *buffer, args.offset..args.size, wgc::resource::BufferMapOperation { @@ -131,9 +147,9 @@ pub async fn op_webgpu_buffer_get_map_async( _ => unreachable!(), }, callback: buffer_map_future_wrapper, - user_data: std::ptr::null_mut(), - }, - )?; + user_data: sender_ptr, + } + ))?; receiver.await??; From 5c4dd3fffbbf56d2c0548942aa0ada9bb865b269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 15 Oct 2020 00:11:09 +0200 Subject: [PATCH 025/144] fix more compile errors, part3 --- cli/ops/webgpu/buffer.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index d3e765abd0e988..8e2ad8f30a4d8c 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -100,13 +100,13 @@ pub async fn op_webgpu_buffer_get_map_async( let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); - let instance = state + let buffer = *state .resource_table - .get_mut::(args.instance_rid) + .get_mut::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let buffer = state + let instance = state .resource_table - .get_mut::(args.buffer_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let (sender, receiver) = oneshot::channel::>(); @@ -137,8 +137,8 @@ pub async fn op_webgpu_buffer_get_map_async( } // TODO: get "device" - wgc::gfx_select!(device => instance.buffer_map_async( - *buffer, + wgc::gfx_select!(buffer => instance.buffer_map_async( + buffer, args.offset..args.size, wgc::resource::BufferMapOperation { host: match args.mode { From c0b038ffebb25da69f35dbfca500cd909f6777c5 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 00:20:23 +0200 Subject: [PATCH 026/144] bogus data --- cli/ops/webgpu/buffer.rs | 1 - cli/ops/webgpu/command_encoder.rs | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 8e2ad8f30a4d8c..e30e0e9217910b 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -136,7 +136,6 @@ pub async fn op_webgpu_buffer_get_map_async( drop(boxed_sender); } - // TODO: get "device" wgc::gfx_select!(buffer => instance.buffer_map_async( buffer, args.offset..args.size, diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 6a569daf8232f3..b6203ad59bcb7c 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -185,7 +185,12 @@ pub fn op_webgpu_command_encoder_begin_render_pass( store_op: color_attachment .store_op .map_or(wgc::command::StoreOp::Store, serialize_store_op), - clear_value: (), // TODO + clear_value: wgt::Color { + r: 0.0, + g: 0.0, + b: 0.0, + a: 0.0 + }, // TODO read_only: false, // TODO }, }; @@ -204,13 +209,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass( depth: wgc::command::PassChannel { load_op: wgc::command::LoadOp::Clear, // TODO store_op: serialize_store_op(attachment.depth_store_op), - clear_value: (), // TODO + clear_value: 0.0, // TODO read_only: false, // TODO }, stencil: wgc::command::PassChannel { load_op: wgc::command::LoadOp::Clear, // TODO store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: (), // TODO + clear_value: 0, // TODO read_only: false, // TODO }, }; From cc321eac19181777fb6f8a94f39cece8b038533e Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 01:16:08 +0200 Subject: [PATCH 027/144] real data --- cli/ops/webgpu/command_encoder.rs | 85 ++++++++++++++++++++++--------- cli/ops/webgpu/render_pass.rs | 10 ++-- cli/rt/14_webgpu.js | 39 ++++++++++++++ 3 files changed, 104 insertions(+), 30 deletions(-) diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index b6203ad59bcb7c..2732aab6542405 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -123,7 +123,8 @@ pub fn op_webgpu_create_command_encoder( struct GPURenderPassColorAttachmentDescriptor { attachment: u32, resolve_target: Option, - load_value: (), // TODO: mixed types + load_op: String, + load_value: Option, store_op: Option, } @@ -131,10 +132,12 @@ struct GPURenderPassColorAttachmentDescriptor { #[serde(rename_all = "camelCase")] struct GPURenderPassDepthStencilAttachmentDescriptor { attachment: u32, - depth_load_value: (), // TODO: mixed types + depth_load_op: String, + depth_load_value: Option, depth_store_op: String, depth_read_only: Option, - stencil_load_value: (), // TODO: mixed types + stencil_load_op: String, + stencil_load_value: Option, stencil_store_op: String, stencil_read_only: Option, } @@ -180,18 +183,32 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }) .transpose()? .map(|texture| *texture), - channel: wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, // TODO - store_op: color_attachment - .store_op - .map_or(wgc::command::StoreOp::Store, serialize_store_op), - clear_value: wgt::Color { - r: 0.0, - g: 0.0, - b: 0.0, - a: 0.0 - }, // TODO - read_only: false, // TODO + channel: match color_attachment.load_op.as_str() { + "load" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Load, + store_op: color_attachment + .store_op + .map_or(wgc::command::StoreOp::Store, serialize_store_op), + clear_value: Default::default(), + read_only: false, + }, + "clear" => { + let color = color_attachment.load_value.unwrap(); + wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, + store_op: color_attachment + .store_op + .map_or(wgc::command::StoreOp::Store, serialize_store_op), + clear_value: wgt::Color { + r: color.r, + g: color.g, + b: color.b, + a: color.a, + }, + read_only: false, + } + }, + _ => unreachable!(), }, }; @@ -206,17 +223,35 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .resource_table .get_mut::(attachment.attachment) .ok_or_else(bad_resource_id)?, - depth: wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, // TODO - store_op: serialize_store_op(attachment.depth_store_op), - clear_value: 0.0, // TODO - read_only: false, // TODO + depth: match attachment.depth_load_op.as_str() { + "load" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Load, + store_op: serialize_store_op(attachment.depth_store_op), + clear_value: 0.0, + read_only: attachment.depth_read_only.unwrap_or(false), + }, + "clear" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, + store_op: serialize_store_op(attachment.depth_store_op), + clear_value: attachment.depth_load_value.unwrap(), + read_only: attachment.depth_read_only.unwrap_or(false), + }, + _ => unreachable!(), }, - stencil: wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, // TODO - store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: 0, // TODO - read_only: false, // TODO + stencil: match attachment.stencil_load_op.as_str() { + "load" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Load, + store_op: serialize_store_op(attachment.stencil_store_op), + clear_value: 0, + read_only: attachment.stencil_read_only.unwrap_or(false), + }, + "clear" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, + store_op: serialize_store_op(attachment.stencil_store_op), + clear_value: attachment.stencil_load_value.unwrap(), + read_only: attachment.stencil_read_only.unwrap_or(false), + }, + _ => unreachable!(), }, }; diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index ba4dc709fe50a2..2abe63c621b315 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -168,11 +168,11 @@ pub fn op_webgpu_render_pass_set_scissor_rect( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUColor { - r: f64, - g: f64, - b: f64, - a: f64, +pub struct GPUColor { + pub r: f64, + pub g: f64, + pub b: f64, + pub a: f64, } #[derive(Deserialize)] diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 17a87d8dc2786f..47ef0828c3a721 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -543,11 +543,50 @@ } beginRenderPass(descriptor) { + let depthStencilAttachment; + if (descriptor.depthStencilAttachment) { + depthStencilAttachment = { + ...descriptor.depthStencilAttachment, + attachment: GPUTextureViewMap.get(descriptor.depthStencilAttachment.attachment), + }; + + if (typeof descriptor.depthStencilAttachment.depthLoadValue === "string") { + depthStencilAttachment.depthLoadOp = descriptor.depthStencilAttachment.depthLoadValue; + } else { + depthStencilAttachment.depthLoadOp = "clear"; + depthStencilAttachment.depthLoadValue = descriptor.depthStencilAttachment.depthLoadValue; + } + + if (typeof descriptor.depthStencilAttachment.stencilLoadValue === "string") { + depthStencilAttachment.stencilLoadOp = descriptor.depthStencilAttachment.stencilLoadValue; + } else { + depthStencilAttachment.stencilLoadOp = "clear"; + depthStencilAttachment.stencilLoadValue = descriptor.depthStencilAttachment.stencilLoadValue; + } + } + const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_render_pass", { commandEncoderRid: this.#rid, ...descriptor, + colorAttachments: descriptor.colorAttachments.map(colorAttachment => { + const attachment = { + attachment: GPUTextureViewMap.get(colorAttachment.attachment), + resolveTarget: colorAttachment.resolveTarget && GPUTextureViewMap.get(colorAttachment.resolveTarget), + storeOp: colorAttachment.storeOp, + }; + + if (typeof colorAttachment.loadValue === "string") { + attachment.loadOp = colorAttachment.loadValue; + } else { + attachment.loadOp = "clear"; + attachment.loadValue = normalizeGPUColor(colorAttachment.loadValue); + } + + return attachment; + }), + depthStencilAttachment, }, ); From ffbb6b73008d8ae20fcb7fac97adbea6a653a48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 15 Oct 2020 01:21:51 +0200 Subject: [PATCH 028/144] fix more compile errors, part4 --- cli/ops/webgpu/binding.rs | 73 +++++++------ cli/ops/webgpu/buffer.rs | 41 ++++--- cli/ops/webgpu/bundle.rs | 49 +++++---- cli/ops/webgpu/command_encoder.rs | 176 +++++++++++++++--------------- cli/ops/webgpu/compute_pass.rs | 46 ++++---- cli/ops/webgpu/pipeline.rs | 96 ++++++++-------- cli/ops/webgpu/queue.rs | 58 +++++----- cli/ops/webgpu/render_pass.rs | 82 +++++++------- cli/ops/webgpu/sampler.rs | 12 +- cli/ops/webgpu/shader.rs | 12 +- cli/ops/webgpu/texture.rs | 24 ++-- 11 files changed, 350 insertions(+), 319 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index 0c22e48927e860..bc74e5fd3ff004 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -70,13 +70,13 @@ pub fn op_webgpu_create_bind_group_layout( ) -> Result { let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let mut entries = vec![]; @@ -109,30 +109,30 @@ pub fn op_webgpu_create_bind_group_layout( "sampler" => wgt::BindingType::Sampler { comparison: false }, "comparison-sampler" => wgt::BindingType::Sampler { comparison: true }, "sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), + dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), + entry.texture_component_type.clone().unwrap(), )?, multisampled: false, }, "multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), + dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), component_type: serialize_texture_component_type( - entry.texture_component_type.unwrap(), + entry.texture_component_type.clone().unwrap(), )?, multisampled: true, }, "readonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), + dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), + entry.storage_texture_format.clone().unwrap(), )?, readonly: true, }, "writeonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.unwrap()), + dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), format: serialize_texture_format( - entry.storage_texture_format.unwrap(), + entry.storage_texture_format.clone().unwrap(), )?, readonly: false, }, @@ -147,8 +147,8 @@ pub fn op_webgpu_create_bind_group_layout( label: args.label.map(|label| Cow::Owned(label)), entries: Cow::Owned(entries), }; - let bind_group_layout = wgc::gfx_select!(*device => instance.device_create_bind_group_layout( - *device, + let bind_group_layout = wgc::gfx_select!(device => instance.device_create_bind_group_layout( + device, &descriptor, std::marker::PhantomData ))?; @@ -178,13 +178,9 @@ pub fn op_webgpu_create_pipeline_layout( ) -> Result { let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let device = state + let device = *state .resource_table - .get_mut::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let mut bind_group_layouts = vec![]; @@ -192,18 +188,23 @@ pub fn op_webgpu_create_pipeline_layout( for rid in &args.bind_group_layouts { let id = state .resource_table - .get_mut::(*rid) + .get::(*rid) .ok_or_else(bad_resource_id)?; bind_group_layouts.push(*id); } + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(|label| Cow::Owned(label)), bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; - let pipeline_layout = wgc::gfx_select!(*device => instance.device_create_pipeline_layout( - *device, + let pipeline_layout = wgc::gfx_select!(device => instance.device_create_pipeline_layout( + device, &descriptor, std::marker::PhantomData ))?; @@ -244,13 +245,9 @@ pub fn op_webgpu_create_bind_group( ) -> Result { let args: CreateBindGroupArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let device = state + let device = *state .resource_table - .get_mut::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let mut entries = vec![]; @@ -262,20 +259,20 @@ pub fn op_webgpu_create_bind_group( "GPUSampler" => wgc::binding_model::BindingResource::Sampler( *state .resource_table - .get_mut::(entry.resource) + .get::(entry.resource) .ok_or_else(bad_resource_id)?, ), "GPUTextureView" => wgc::binding_model::BindingResource::TextureView( *state .resource_table - .get_mut::(entry.resource) + .get::(entry.resource) .ok_or_else(bad_resource_id)?, ), "GPUBufferBinding" => wgc::binding_model::BindingResource::Buffer( wgc::binding_model::BufferBinding { buffer_id: *state .resource_table - .get_mut::(entry.resource) + .get::(entry.resource) .ok_or_else(bad_resource_id)?, offset: entry.offset.unwrap_or(0), size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), @@ -291,12 +288,18 @@ pub fn op_webgpu_create_bind_group( label: args.label.map(|label| Cow::Owned(label)), layout: *state .resource_table - .get_mut::(args.layout) + .get::(args.layout) .ok_or_else(bad_resource_id)?, entries: Cow::Owned(entries), }; - let bind_group = wgc::gfx_select!(*device => instance.device_create_bind_group( - *device, + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + + let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( + device, &descriptor, std::marker::PhantomData ))?; diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index e30e0e9217910b..0da88ff19aa78d 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -54,13 +54,13 @@ pub fn op_webgpu_create_buffer( ) -> Result { let args: CreateBufferArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::BufferDescriptor { @@ -69,8 +69,8 @@ pub fn op_webgpu_create_buffer( usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }; - let buffer = wgc::gfx_select!(*device => instance.device_create_buffer( - *device, + let buffer = wgc::gfx_select!(device => instance.device_create_buffer( + device, &descriptor, std::marker::PhantomData ))?; @@ -128,12 +128,11 @@ pub async fn op_webgpu_buffer_get_map_async( user_data, ) }; - let boxed_sender = Box::from_raw(sender_ptr); + let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; boxed_sender.send(match status { wgc::resource::BufferMapAsyncStatus::Success => Ok(()), _ => unreachable!(), // TODO }); - drop(boxed_sender); } wgc::gfx_select!(buffer => instance.buffer_map_async( @@ -167,27 +166,27 @@ struct BufferGetMappedRangeArgs { pub fn op_webgpu_buffer_get_mapped_range( state: &mut OpState, args: Value, - zero_copy: &mut [ZeroCopyBuf], + _zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; - let instance = state + let buffer = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let buffer = state + let instance = state .resource_table - .get_mut::(args.buffer_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let slice_pointer = wgc::gfx_select!(*buffer => instance.buffer_get_mapped_range( - *buffer, + let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( + buffer, args.offset, std::num::NonZeroU64::new(args.size) ))?; // TODO: use - let slice = unsafe { + let _slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) }; @@ -208,16 +207,16 @@ pub fn op_webgpu_buffer_unmap( ) -> Result { let args: BufferUnmapArgs = serde_json::from_value(args)?; - let instance = state + let buffer = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let buffer = state + let instance = state .resource_table - .get_mut::(args.buffer_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*buffer => instance.buffer_unmap(*buffer))?; + wgc::gfx_select!(buffer => instance.buffer_unmap(buffer))?; Ok(json!({})) } diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index e18e02c1307c19..49d140ac26dfe5 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -183,6 +183,10 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( ) -> Result { let args: RenderBundleEncoderSetBindGroupArgs = serde_json::from_value(args)?; + let bind_group_id = *state + .resource_table + .get::(args.bind_group) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table .get_mut::( @@ -194,18 +198,15 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( wgc::command::bundle_ffi::wgpu_render_bundle_set_bind_group( render_bundle_encoder, args.index, - *state - .resource_table - .get_mut::(args.bind_group) - .ok_or_else(bad_resource_id)?, + bind_group_id, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), - None => unsafe { + None => { let (prefix, data, suffix) = zero_copy[0].align_to::(); assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - }, + } }, args.dynamic_offsets_data_length, ); @@ -322,6 +323,10 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( ) -> Result { let args: RenderBundleEncoderSetPipelineArgs = serde_json::from_value(args)?; + let pipeline_id = *state + .resource_table + .get::(args.pipeline) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table .get_mut::( @@ -331,10 +336,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( wgc::command::bundle_ffi::wgpu_render_bundle_set_pipeline( render_bundle_encoder, - *state - .resource_table - .get_mut::(args.pipeline) - .ok_or_else(bad_resource_id)?, + pipeline_id, ); Ok(json!({})) @@ -358,6 +360,10 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( let args: RenderBundleEncoderSetIndexBufferArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.buffer) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table .get_mut::( @@ -367,10 +373,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( wgc::command::bundle_ffi::wgpu_render_bundle_set_index_buffer( render_bundle_encoder, - *state - .resource_table - .get_mut::(args.buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -396,6 +399,10 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( let args: RenderBundleEncoderSetVertexBufferArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.buffer) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table .get_mut::( @@ -406,10 +413,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( wgc::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( render_bundle_encoder, args.slot, - *state - .resource_table - .get_mut::(args.buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -504,6 +508,10 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect( ) -> Result { let args: RenderBundleEncoderDrawIndirectArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?; let render_bundle_encoder = state .resource_table .get_mut::( @@ -513,10 +521,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect( wgc::command::bundle_ffi::wgpu_render_bundle_draw_indirect( render_bundle_encoder, - *state - .resource_table - .get_mut::(args.indirect_buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.indirect_offset, ); diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 2732aab6542405..c58d018b14ad55 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -91,20 +91,20 @@ pub fn op_webgpu_create_command_encoder( ) -> Result { let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(|label| Cow::Owned(label)), }; - let command_encoder = wgc::gfx_select!(*device => instance.device_create_command_encoder( - *device, + let command_encoder = wgc::gfx_select!(device => instance.device_create_command_encoder( + device, &descriptor, std::marker::PhantomData ))?; @@ -160,9 +160,9 @@ pub fn op_webgpu_command_encoder_begin_render_pass( ) -> Result { let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; - let command_encoder = state + let command_encoder = *state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let mut color_attachments = vec![]; @@ -259,7 +259,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( } let render_pass = wgc::command::RenderPass::new( - *command_encoder, + command_encoder, wgc::command::RenderPassDescriptor { color_attachments: Cow::Owned(color_attachments), depth_stencil_attachment: depth_stencil_attachment.as_ref(), @@ -325,25 +325,25 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( let args: CommandEncoderCopyBufferToBufferArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = state + let command_encoder = *state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let source = *state .resource_table - .get_mut::(args.source) + .get::(args.source) .ok_or_else(bad_resource_id)?; let destination = *state .resource_table - .get_mut::(args.destination) + .get::(args.destination) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_buffer_to_buffer( - *command_encoder, + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + + wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( + command_encoder, source, args.source_offset, destination, @@ -397,20 +397,25 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( let args: CommandEncoderCopyBufferToTextureArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let source_buffer_id = *state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.source.buffer) + .ok_or_else(bad_resource_id)?; + let destination_texture_id = *state + .resource_table + .get::(args.destination.texture) + .ok_or_else(bad_resource_id)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let source = wgc::command::BufferCopyView { - buffer: *state - .resource_table - .get_mut::(args.source.buffer) - .ok_or_else(bad_resource_id)?, + buffer: source_buffer_id, layout: wgt::TextureDataLayout { offset: args.source.offset.unwrap_or(0), bytes_per_row: args.source.bytes_per_row.unwrap_or(0), @@ -418,10 +423,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( }, }; let destination = wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, + texture: destination_texture_id, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination @@ -432,8 +434,8 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( z: origin.z.unwrap_or(0), }), }; - wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_buffer_to_texture( - *command_encoder, + wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_texture( + command_encoder, &source, &destination, &wgt::Extent3d { @@ -464,20 +466,25 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( let args: CommandEncoderCopyTextureToBufferArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let source_texture_id = *state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.source.texture) + .ok_or_else(bad_resource_id)?; + let destination_buffer_id = *state + .resource_table + .get::(args.destination.buffer) + .ok_or_else(bad_resource_id)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let source = wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.source.texture) - .ok_or_else(bad_resource_id)?, + texture: source_texture_id, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { wgt::Origin3d { @@ -488,18 +495,15 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( }), }; let destination = wgc::command::BufferCopyView { - buffer: *state - .resource_table - .get_mut::(args.destination.buffer) - .ok_or_else(bad_resource_id)?, + buffer: destination_buffer_id, layout: wgt::TextureDataLayout { offset: args.destination.offset.unwrap_or(0), bytes_per_row: args.destination.bytes_per_row.unwrap_or(0), rows_per_image: args.destination.rows_per_image.unwrap_or(0), }, }; - wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_texture_to_buffer( - *command_encoder, + wgc::gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_buffer( + command_encoder, &source, &destination, &wgt::Extent3d { @@ -530,20 +534,25 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let source_texture_id = *state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.source.texture) + .ok_or_else(bad_resource_id)?; + let destination_texture_id = *state + .resource_table + .get::(args.destination.texture) + .ok_or_else(bad_resource_id)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let source = wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.source.texture) - .ok_or_else(bad_resource_id)?, + texture: source_texture_id, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { wgt::Origin3d { @@ -554,10 +563,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( }), }; let destination = wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, + texture: destination_texture_id, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination @@ -568,8 +574,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( z: origin.z.unwrap_or(0), }), }; - wgc::gfx_select!(*command_encoder => instance.command_encoder_copy_texture_to_texture( - *command_encoder, + wgc::gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_texture( + command_encoder, &source, &destination, &wgt::Extent3d { @@ -597,17 +603,17 @@ pub fn op_webgpu_command_encoder_push_debug_group( ) -> Result { let args: CommandEncoderPushDebugGroupArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance - .command_encoder_push_debug_group(*command_encoder, &args.group_label))?; + wgc::gfx_select!(command_encoder => instance + .command_encoder_push_debug_group(command_encoder, &args.group_label))?; Ok(json!({})) } @@ -626,16 +632,16 @@ pub fn op_webgpu_command_encoder_pop_debug_group( ) -> Result { let args: CommandEncoderPopDebugGroupArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance.command_encoder_pop_debug_group(*command_encoder))?; + wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; Ok(json!({})) } @@ -655,17 +661,17 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( ) -> Result { let args: CommandEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance.command_encoder_insert_debug_marker( - *command_encoder, + wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( + command_encoder, &args.marker_label ))?; @@ -687,20 +693,20 @@ pub fn op_webgpu_command_encoder_finish( ) -> Result { let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(|label| Cow::Owned(label)), }; - let command_buffer = wgc::gfx_select!(*command_encoder => instance.command_encoder_finish( - *command_encoder, + let command_buffer = wgc::gfx_select!(command_encoder => instance.command_encoder_finish( + command_encoder, &descriptor ))?; diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index 40e1fe1c8451cd..37d19e21bc4850 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -65,6 +65,10 @@ pub fn op_webgpu_compute_pass_set_pipeline( ) -> Result { let args: ComputePassSetPipelineArgs = serde_json::from_value(args)?; + let pipeline_id = *state + .resource_table + .get_mut::(args.pipeline) + .ok_or_else(bad_resource_id)?; let compute_pass = state .resource_table .get_mut::(args.compute_pass_rid) @@ -72,10 +76,7 @@ pub fn op_webgpu_compute_pass_set_pipeline( wgc::command::compute_ffi::wgpu_compute_pass_set_pipeline( compute_pass, - *state - .resource_table - .get_mut::(args.pipeline) - .ok_or_else(bad_resource_id)?, + pipeline_id, ); Ok(json!({})) @@ -127,6 +128,10 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( ) -> Result { let args: ComputePassDispatchIndirectArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get_mut::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?; let compute_pass = state .resource_table .get_mut::(args.compute_pass_rid) @@ -134,10 +139,7 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( wgc::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( compute_pass, - *state - .resource_table - .get_mut::(args.indirect_buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.indirect_offset, ); @@ -159,21 +161,21 @@ pub fn op_webgpu_compute_pass_end_pass( ) -> Result { let args: ComputePassEndPassArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let compute_pass = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance.command_encoder_run_compute_pass( - *command_encoder, + wgc::gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( + command_encoder, compute_pass ))?; @@ -198,6 +200,11 @@ pub fn op_webgpu_compute_pass_set_bind_group( ) -> Result { let args: ComputePassSetBindGroupArgs = serde_json::from_value(args)?; + let bind_group_id = *state + .resource_table + .get::(args.bind_group) + .ok_or_else(bad_resource_id)?; + let compute_pass = state .resource_table .get_mut::(args.compute_pass_rid) @@ -207,18 +214,15 @@ pub fn op_webgpu_compute_pass_set_bind_group( wgc::command::compute_ffi::wgpu_compute_pass_set_bind_group( compute_pass, args.index, - *state - .resource_table - .get_mut::(args.bind_group) - .ok_or_else(bad_resource_id)?, + bind_group_id, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), - None => unsafe { + None => { let (prefix, data, suffix) = zero_copy[0].align_to::(); assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - }, + } }, args.dynamic_offsets_data_length, ); diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index ad2023d433bba5..b8ebd1e6fd53fd 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -35,13 +35,13 @@ pub fn init(rt: &mut deno_core::JsRuntime) { } fn serialize_programmable_stage_descriptor( - state: &mut OpState, + state: &OpState, programmable_stage_descriptor: GPUProgrammableStageDescriptor, ) -> Result { Ok(wgc::pipeline::ProgrammableStageDescriptor { module: *state .resource_table - .get_mut::(programmable_stage_descriptor.module) + .get::(programmable_stage_descriptor.module) .ok_or_else(bad_resource_id)?, entry_point: Cow::Owned(programmable_stage_descriptor.entry_point), }) @@ -147,19 +147,15 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let device = state + let device = *state .resource_table - .get_mut::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let layout = if let Some(rid) = args.layout { let id = state .resource_table - .get_mut::(rid) + .get::(rid) .ok_or_else(bad_resource_id)?; Some(*id) } else { @@ -181,8 +177,14 @@ pub fn op_webgpu_create_compute_pipeline( group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], }), }; - let (compute_pipeline, _) = wgc::gfx_select!(*device => instance.device_create_compute_pipeline( - *device, + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + + let (compute_pipeline, _) = wgc::gfx_select!(device => instance.device_create_compute_pipeline( + device, &descriptor, std::marker::PhantomData, implicit_pipelines @@ -213,17 +215,17 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( let args: ComputePipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; - let instance = state + let compute_pipeline = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.compute_pipeline_rid) .ok_or_else(bad_resource_id)?; - let compute_pipeline = state + let instance = state .resource_table - .get_mut::(args.compute_pipeline_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = wgc::gfx_select!(*compute_pipeline => instance - .compute_pipeline_get_bind_group_layout(*compute_pipeline, args.index))?; + let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance + .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; let rid = state .resource_table @@ -332,13 +334,9 @@ pub fn op_webgpu_create_render_pipeline( ) -> Result { let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let device = state + let device = *state .resource_table - .get_mut::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let mut color_states = vec![]; @@ -386,29 +384,36 @@ pub fn op_webgpu_create_render_pipeline( let layout = if let Some(rid) = args.layout { let id = state .resource_table - .get_mut::(rid) + .get::(rid) .ok_or_else(bad_resource_id)?; Some(*id) } else { None }; + let fragment_stage = + if let Some(programmable_stage_descriptor) = args.fragment_stage { + Some(serialize_programmable_stage_descriptor( + state, + programmable_stage_descriptor, + )?) + } else { + None + }; + + let vertex_stage = + serialize_programmable_stage_descriptor(state, args.vertex_stage)?; + + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let descriptor = wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), layout, - vertex_stage: serialize_programmable_stage_descriptor( - state, - args.vertex_stage, - )?, - fragment_stage: args - .fragment_stage - .map(|programmable_stage_descriptor| { - serialize_programmable_stage_descriptor( - state, - programmable_stage_descriptor, - ) - }) - .transpose()?, + vertex_stage, + fragment_stage, rasterization_state: args.rasterization_state.map(|rasterization_state| { wgt::RasterizationStateDescriptor { front_face: match rasterization_state.front_face { @@ -536,8 +541,9 @@ pub fn op_webgpu_create_render_pipeline( group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], }), }; - let (render_pipeline, _) = wgc::gfx_select!(*device => instance.device_create_render_pipeline( - *device, + + let (render_pipeline, _) = wgc::gfx_select!(device => instance.device_create_render_pipeline( + device, &descriptor, std::marker::PhantomData, implicit_pipelines @@ -568,17 +574,17 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; - let instance = state + let render_pipeline = *state .resource_table - .get_mut::(args.instance_rid) + .get_mut::(args.render_pipeline_rid) .ok_or_else(bad_resource_id)?; - let render_pipeline = state + let instance = state .resource_table - .get_mut::(args.render_pipeline_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let bind_group_layout = wgc::gfx_select!(*render_pipeline => instance - .render_pipeline_get_bind_group_layout(*render_pipeline, args.index))?; + let bind_group_layout = wgc::gfx_select!(render_pipeline => instance + .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; let rid = state .resource_table diff --git a/cli/ops/webgpu/queue.rs b/cli/ops/webgpu/queue.rs index 858b3f77fbd286..419f356366b4cc 100644 --- a/cli/ops/webgpu/queue.rs +++ b/cli/ops/webgpu/queue.rs @@ -41,13 +41,9 @@ pub fn op_webgpu_queue_submit( ) -> Result { let args: QueueSubmitArgs = serde_json::from_value(args)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let queue = state + let queue = *state .resource_table - .get_mut::(args.queue_rid) + .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; let mut ids = vec![]; @@ -55,12 +51,17 @@ pub fn op_webgpu_queue_submit( for rid in &args.command_buffers { let buffer_id = state .resource_table - .get_mut::(*rid) + .get::(*rid) .ok_or_else(bad_resource_id)?; ids.push(*buffer_id); } - wgc::gfx_select!(*queue => instance.queue_submit(*queue, &ids))?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + + wgc::gfx_select!(queue => instance.queue_submit(queue, &ids))?; Ok(json!({})) } @@ -91,26 +92,26 @@ pub fn op_webgpu_write_buffer( ) -> Result { let args: QueueWriteBufferArgs = serde_json::from_value(args)?; - let instance = state + let queue = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; - let queue = state + let buffer = *state .resource_table - .get_mut::(args.queue_rid) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - - let buffer = state + let instance = state .resource_table - .get_mut::(args.buffer) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], None => &zero_copy[0][args.data_offset..], }; - wgc::gfx_select!(*queue => instance.queue_write_buffer( - *queue, - *buffer, + wgc::gfx_select!(queue => instance.queue_write_buffer( + queue, + buffer, args.buffer_offset, data ))?; @@ -135,20 +136,21 @@ pub fn op_webgpu_write_texture( ) -> Result { let args: QueueWriteTextureArgs = serde_json::from_value(args)?; - let instance = state + let texture = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let queue = state + let queue = *state .resource_table - .get_mut::(args.queue_rid) + .get::(args.queue_rid) + .ok_or_else(bad_resource_id)?; + let instance = state + .resource_table + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let destination = wgc::command::TextureCopyView { - texture: *state - .resource_table - .get_mut::(args.destination.texture) - .ok_or_else(bad_resource_id)?, + texture, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination @@ -164,8 +166,8 @@ pub fn op_webgpu_write_texture( bytes_per_row: args.data_layout.bytes_per_row.unwrap_or(0), rows_per_image: args.data_layout.rows_per_image.unwrap_or(0), }; - wgc::gfx_select!(*queue => instance.queue_write_texture( - *queue, + wgc::gfx_select!(queue => instance.queue_write_texture( + queue, &destination, &*zero_copy[0], &data_layout, diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 2abe63c621b315..f04ae5910d810e 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -248,21 +248,21 @@ pub fn op_webgpu_render_pass_execute_bundles( ) -> Result { let args: RenderPassExecuteBundlesArgs = serde_json::from_value(args)?; - let render_pass = state - .resource_table - .get_mut::(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - let mut render_bundle_ids = vec![]; for rid in &args.bundles { let bundle_id = state .resource_table - .get_mut::(*rid) + .get::(*rid) .ok_or_else(bad_resource_id)?; render_bundle_ids.push(*bundle_id); } + let render_pass = state + .resource_table + .get_mut::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + unsafe { wgc::command::render_ffi::wgpu_render_pass_execute_bundles( render_pass, @@ -289,20 +289,20 @@ pub fn op_webgpu_render_pass_end_pass( ) -> Result { let args: RenderPassEndPassArgs = serde_json::from_value(args)?; - let instance = state + let command_encoder = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = state + let instance = state .resource_table - .get_mut::(args.command_encoder_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(*command_encoder => instance.command_encoder_run_render_pass(*command_encoder, render_pass))?; + wgc::gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; Ok(json!({})) } @@ -325,6 +325,10 @@ pub fn op_webgpu_render_pass_set_bind_group( ) -> Result { let args: RenderPassSetBindGroupArgs = serde_json::from_value(args)?; + let bind_group_id = *state + .resource_table + .get::(args.bind_group) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -334,18 +338,15 @@ pub fn op_webgpu_render_pass_set_bind_group( wgc::command::render_ffi::wgpu_render_pass_set_bind_group( render_pass, args.index, - *state - .resource_table - .get_mut::(args.bind_group) - .ok_or_else(bad_resource_id)?, + bind_group_id, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), - None => unsafe { + None => { let (prefix, data, suffix) = zero_copy[0].align_to::(); assert!(prefix.is_empty()); assert!(suffix.is_empty()); data[args.dynamic_offsets_data_start..].as_ptr() - }, + } }, args.dynamic_offsets_data_length, ); @@ -451,6 +452,10 @@ pub fn op_webgpu_render_pass_set_pipeline( ) -> Result { let args: RenderPassSetPipelineArgs = serde_json::from_value(args)?; + let pipeline_id = *state + .resource_table + .get::(args.pipeline) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -458,10 +463,7 @@ pub fn op_webgpu_render_pass_set_pipeline( wgc::command::render_ffi::wgpu_render_pass_set_pipeline( render_pass, - *state - .resource_table - .get_mut::(args.pipeline) - .ok_or_else(bad_resource_id)?, + pipeline_id, ); Ok(json!({})) @@ -484,6 +486,10 @@ pub fn op_webgpu_render_pass_set_index_buffer( ) -> Result { let args: RenderPassSetIndexBufferArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.buffer) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -491,10 +497,7 @@ pub fn op_webgpu_render_pass_set_index_buffer( wgc::command::render_ffi::wgpu_render_pass_set_index_buffer( render_pass, - *state - .resource_table - .get_mut::(args.buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -519,6 +522,10 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( ) -> Result { let args: RenderPassSetVertexBufferArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.buffer) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -527,10 +534,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( wgc::command::render_ffi::wgpu_render_pass_set_vertex_buffer( render_pass, args.slot, - *state - .resource_table - .get_mut::(args.buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -621,6 +625,10 @@ pub fn op_webgpu_render_pass_draw_indirect( ) -> Result { let args: RenderPassDrawIndirectArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -628,10 +636,7 @@ pub fn op_webgpu_render_pass_draw_indirect( wgc::command::render_ffi::wgpu_render_pass_draw_indirect( render_pass, - *state - .resource_table - .get_mut::(args.indirect_buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.indirect_offset, ); @@ -653,6 +658,10 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect( ) -> Result { let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; + let buffer_id = *state + .resource_table + .get::(args.indirect_buffer) + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get_mut::(args.render_pass_rid) @@ -660,10 +669,7 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect( wgc::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( render_pass, - *state - .resource_table - .get_mut::(args.indirect_buffer) - .ok_or_else(bad_resource_id)?, + buffer_id, args.indirect_offset, ); diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index d0c70229c12ed7..06455872440910 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -79,13 +79,13 @@ pub fn op_webgpu_create_sampler( ) -> Result { let args: CreateSamplerArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::SamplerDescriptor { @@ -105,8 +105,8 @@ pub fn op_webgpu_create_sampler( compare: args.compare.map(serialize_compare_function), anisotropy_clamp: args.max_anisotropy, }; - let sampler = wgc::gfx_select!(*device => instance.device_create_sampler( - *device, + let sampler = wgc::gfx_select!(device => instance.device_create_sampler( + device, &descriptor, std::marker::PhantomData ))?; diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 63c692e8109ef8..d84c532f71ac50 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -34,13 +34,13 @@ pub fn op_webgpu_create_shader_module( ) -> Result { let args: CreateShaderModuleArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let source = match args.code { @@ -52,8 +52,8 @@ pub fn op_webgpu_create_shader_module( data })), }; - let shader_module = wgc::gfx_select!(*device => instance.device_create_shader_module( - *device, + let shader_module = wgc::gfx_select!(device => instance.device_create_shader_module( + device, source, std::marker::PhantomData ))?; diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index 82d19cb9ebcb77..b4a9b945b31273 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -147,13 +147,13 @@ pub fn op_webgpu_create_texture( ) -> Result { let args: CreateTextureArgs = serde_json::from_value(args)?; - let instance = state + let device = *state .resource_table - .get_mut::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = state + let instance = state .resource_table - .get_mut::(args.device_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::TextureDescriptor { @@ -178,8 +178,8 @@ pub fn op_webgpu_create_texture( usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), }; - let texture = wgc::gfx_select!(*device => instance.device_create_texture( - *device, + let texture = wgc::gfx_select!(device => instance.device_create_texture( + device, &descriptor, std::marker::PhantomData ))?; @@ -213,13 +213,13 @@ pub fn op_webgpu_create_texture_view( ) -> Result { let args: CreateTextureViewArgs = serde_json::from_value(args)?; - let instance = state + let texture = *state .resource_table - .get_mut::(args.instance_rid) + .get_mut::(args.texture_rid) .ok_or_else(bad_resource_id)?; - let texture = state + let instance = state .resource_table - .get_mut::(args.texture_rid) + .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::TextureViewDescriptor { @@ -244,8 +244,8 @@ pub fn op_webgpu_create_texture_view( args.array_layer_count.unwrap_or(0), ), }; - let texture_view = wgc::gfx_select!(*texture => instance.texture_create_view( - *texture, + let texture_view = wgc::gfx_select!(texture => instance.texture_create_view( + texture, &descriptor, std::marker::PhantomData ))?; From 6d00506a94e764aca57adf0097905d7aef4d4be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 15 Oct 2020 01:43:00 +0200 Subject: [PATCH 029/144] fix more compile errors, part5 --- cli/ops/webgpu/command_encoder.rs | 2 +- cli/ops/webgpu/pipeline.rs | 31 ++++++++++++++++++++----------- cli/ops/webgpu/sampler.rs | 4 ++-- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index c58d018b14ad55..e6b8285dbe15f2 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -207,7 +207,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }, read_only: false, } - }, + } _ => unreachable!(), }, }; diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index b8ebd1e6fd53fd..d4e8ac6357b7eb 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -47,7 +47,7 @@ fn serialize_programmable_stage_descriptor( }) } -fn serialize_stencil_operation(operation: String) -> wgt::StencilOperation { +fn serialize_stencil_operation(operation: &String) -> wgt::StencilOperation { match operation.as_str() { "keep" => wgt::StencilOperation::Keep, "zero" => wgt::StencilOperation::Zero, @@ -62,25 +62,29 @@ fn serialize_stencil_operation(operation: String) -> wgt::StencilOperation { } fn serialize_stencil_state_face_descriptor( - state: GPUStencilStateFaceDescriptor, + state: &GPUStencilStateFaceDescriptor, ) -> wgt::StencilStateFaceDescriptor { wgt::StencilStateFaceDescriptor { compare: state .compare + .as_ref() .map_or(wgt::CompareFunction::Always, serialize_compare_function), fail_op: state .fail_op + .as_ref() .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), depth_fail_op: state .depth_fail_op + .as_ref() .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), pass_op: state .pass_op + .as_ref() .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), } } -fn serialize_blend_factor(blend_factor: String) -> wgt::BlendFactor { +fn serialize_blend_factor(blend_factor: &String) -> wgt::BlendFactor { match blend_factor.as_str() { "zero" => wgt::BlendFactor::Zero, "one" => wgt::BlendFactor::One, @@ -100,16 +104,18 @@ fn serialize_blend_factor(blend_factor: String) -> wgt::BlendFactor { } fn serialize_blend_descriptor( - blend: GPUBlendDescriptor, + blend: &GPUBlendDescriptor, ) -> wgt::BlendDescriptor { wgt::BlendDescriptor { src_factor: blend .src_factor + .as_ref() .map_or(wgt::BlendFactor::One, serialize_blend_factor), dst_factor: blend .dst_factor + .as_ref() .map_or(wgt::BlendFactor::Zero, serialize_blend_factor), - operation: match blend.operation { + operation: match &blend.operation { Some(operation) => match operation.as_str() { "add" => wgt::BlendOperation::Add, "subtract" => wgt::BlendOperation::Subtract, @@ -162,13 +168,13 @@ pub fn op_webgpu_create_compute_pipeline( None }; + let compute_stage = + serialize_programmable_stage_descriptor(state, args.compute_stage)?; + let descriptor = wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), layout, - compute_stage: serialize_programmable_stage_descriptor( - state, - args.compute_stage, - )?, + compute_stage, }; let implicit_pipelines = match args.layout { Some(_) => None, @@ -346,9 +352,11 @@ pub fn op_webgpu_create_render_pipeline( format: serialize_texture_format(color_state.format.clone())?, alpha_blend: color_state .alpha_blend + .as_ref() .map_or(Default::default(), serialize_blend_descriptor), color_blend: color_state .color_blend + .as_ref() .map_or(Default::default(), serialize_blend_descriptor), write_mask: color_state.write_mask.map_or(Default::default(), |mask| { wgt::ColorWrite::from_bits(mask).unwrap() @@ -365,13 +373,14 @@ pub fn op_webgpu_create_render_pipeline( depth_write_enabled: state.depth_write_enabled.unwrap_or(false), depth_compare: state .depth_compare + .as_ref() .map_or(wgt::CompareFunction::Always, serialize_compare_function), stencil: wgt::StencilStateDescriptor { - front: state.stencil_front.map_or( + front: state.stencil_front.as_ref().map_or( wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), - back: state.stencil_front.map_or( + back: state.stencil_front.as_ref().map_or( wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index 06455872440910..d660304f8942dd 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -40,7 +40,7 @@ fn serialize_filter_mode(filter_mode: Option) -> wgt::FilterMode { } } -pub fn serialize_compare_function(compare: String) -> wgt::CompareFunction { +pub fn serialize_compare_function(compare: &String) -> wgt::CompareFunction { match compare.as_str() { "never" => wgt::CompareFunction::Never, "less" => wgt::CompareFunction::Less, @@ -102,7 +102,7 @@ pub fn op_webgpu_create_sampler( lod_max_clamp: args .lod_max_clamp .unwrap_or(wgc::resource::SamplerDescriptor::default().lod_max_clamp), - compare: args.compare.map(serialize_compare_function), + compare: args.compare.as_ref().map(serialize_compare_function), anisotropy_clamp: args.max_anisotropy, }; let sampler = wgc::gfx_select!(device => instance.device_create_sampler( From ca2578bccbe652dbd0bc0ff381dffd3e20b65025 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 02:25:24 +0200 Subject: [PATCH 030/144] fix NonZeroU8 --- cli/ops/webgpu/sampler.rs | 6 ++-- cli/rt/14_webgpu.js | 61 ++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index d660304f8942dd..ec3fe49562e6b9 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -69,7 +69,7 @@ struct CreateSamplerArgs { lod_min_clamp: Option, lod_max_clamp: Option, compare: Option, - max_anisotropy: Option, + max_anisotropy: Option, } pub fn op_webgpu_create_sampler( @@ -103,7 +103,9 @@ pub fn op_webgpu_create_sampler( .lod_max_clamp .unwrap_or(wgc::resource::SamplerDescriptor::default().lod_max_clamp), compare: args.compare.as_ref().map(serialize_compare_function), - anisotropy_clamp: args.max_anisotropy, + anisotropy_clamp: std::num::NonZeroU8::new( + args.max_anisotropy.unwrap_or(0), + ), }; let sampler = wgc::gfx_select!(device => instance.device_create_sampler( device, diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 47ef0828c3a721..9d6714e60f75bc 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -547,21 +547,31 @@ if (descriptor.depthStencilAttachment) { depthStencilAttachment = { ...descriptor.depthStencilAttachment, - attachment: GPUTextureViewMap.get(descriptor.depthStencilAttachment.attachment), + attachment: GPUTextureViewMap.get( + descriptor.depthStencilAttachment.attachment, + ), }; - if (typeof descriptor.depthStencilAttachment.depthLoadValue === "string") { - depthStencilAttachment.depthLoadOp = descriptor.depthStencilAttachment.depthLoadValue; + if ( + typeof descriptor.depthStencilAttachment.depthLoadValue === "string" + ) { + depthStencilAttachment.depthLoadOp = + descriptor.depthStencilAttachment.depthLoadValue; } else { depthStencilAttachment.depthLoadOp = "clear"; - depthStencilAttachment.depthLoadValue = descriptor.depthStencilAttachment.depthLoadValue; + depthStencilAttachment.depthLoadValue = + descriptor.depthStencilAttachment.depthLoadValue; } - if (typeof descriptor.depthStencilAttachment.stencilLoadValue === "string") { - depthStencilAttachment.stencilLoadOp = descriptor.depthStencilAttachment.stencilLoadValue; + if ( + typeof descriptor.depthStencilAttachment.stencilLoadValue === "string" + ) { + depthStencilAttachment.stencilLoadOp = + descriptor.depthStencilAttachment.stencilLoadValue; } else { depthStencilAttachment.stencilLoadOp = "clear"; - depthStencilAttachment.stencilLoadValue = descriptor.depthStencilAttachment.stencilLoadValue; + depthStencilAttachment.stencilLoadValue = + descriptor.depthStencilAttachment.stencilLoadValue; } } @@ -570,22 +580,27 @@ { commandEncoderRid: this.#rid, ...descriptor, - colorAttachments: descriptor.colorAttachments.map(colorAttachment => { - const attachment = { - attachment: GPUTextureViewMap.get(colorAttachment.attachment), - resolveTarget: colorAttachment.resolveTarget && GPUTextureViewMap.get(colorAttachment.resolveTarget), - storeOp: colorAttachment.storeOp, - }; - - if (typeof colorAttachment.loadValue === "string") { - attachment.loadOp = colorAttachment.loadValue; - } else { - attachment.loadOp = "clear"; - attachment.loadValue = normalizeGPUColor(colorAttachment.loadValue); - } - - return attachment; - }), + colorAttachments: descriptor.colorAttachments.map( + (colorAttachment) => { + const attachment = { + attachment: GPUTextureViewMap.get(colorAttachment.attachment), + resolveTarget: colorAttachment.resolveTarget && + GPUTextureViewMap.get(colorAttachment.resolveTarget), + storeOp: colorAttachment.storeOp, + }; + + if (typeof colorAttachment.loadValue === "string") { + attachment.loadOp = colorAttachment.loadValue; + } else { + attachment.loadOp = "clear"; + attachment.loadValue = normalizeGPUColor( + colorAttachment.loadValue, + ); + } + + return attachment; + }, + ), depthStencilAttachment, }, ); From 679b461b521c7ba0f26c6e3dc2e9a46328b5602b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 12:29:59 +0200 Subject: [PATCH 031/144] create webgpu instance and add to navigator & workerNavigator --- cli/rt/14_webgpu.js | 16 ++++++++++++---- cli/rt/99_main.js | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 9d6714e60f75bc..026f6cd6cbf511 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -40,14 +40,22 @@ } } - let instanceRid; // TODO: use op_webgpu_create_instance + let instanceRid; - const GPU = { + function getInstanceRid() { + if (!instanceRid) { + const { rid } = core.jsonOpSync("op_webgpu_create_instance"); + instanceRid = rid; + } + return instanceRid; + } + + const gpu = { async requestAdapter(options = {}) { const { rid, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", { - instanceRid, + instanceRid: getInstanceRid(), ...options, }, ); @@ -1207,6 +1215,6 @@ } window.__bootstrap.webGPU = { - webGPU: GPU, + gpu, }; })(this); diff --git a/cli/rt/99_main.js b/cli/rt/99_main.js index e332647267bd07..f17484f32aa6fd 100644 --- a/cli/rt/99_main.js +++ b/cli/rt/99_main.js @@ -25,6 +25,7 @@ delete Object.prototype.__proto__; const headers = window.__bootstrap.headers; const streams = window.__bootstrap.streams; const fileReader = window.__bootstrap.fileReader; + const webGPU = window.__bootstrap.webGPU; const webSocket = window.__bootstrap.webSocket; const fetch = window.__bootstrap.fetch; const prompt = window.__bootstrap.prompt; @@ -276,10 +277,19 @@ delete Object.prototype.__proto__; setTimeout: util.writable(timers.setTimeout), }; + const windowOrWorkerNavigatorProperties = { + gpu: webGPU.gpu, + }; + + const mainRuntimeNavigatorProperties = { + ...windowOrWorkerNavigatorProperties, + }; + const mainRuntimeGlobalProperties = { Window: util.nonEnumerable(Window), window: util.readOnly(globalThis), self: util.readOnly(globalThis), + navigator: util.readOnly(mainRuntimeNavigatorProperties), // TODO(bartlomieju): from MDN docs (https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope) // it seems those two properties should be available to workers as well onload: util.writable(null), @@ -291,9 +301,14 @@ delete Object.prototype.__proto__; prompt: util.writable(prompt.prompt), }; + const workerRuntimeNavigatorProperties = { + ...windowOrWorkerNavigatorProperties, + }; + const workerRuntimeGlobalProperties = { WorkerGlobalScope: util.nonEnumerable(WorkerGlobalScope), DedicatedWorkerGlobalScope: util.nonEnumerable(DedicatedWorkerGlobalScope), + navigator: util.readOnly(workerRuntimeNavigatorProperties), self: util.readOnly(globalThis), onmessage: util.writable(onmessage), onerror: util.writable(onerror), From fbb5a5b3c50523752fe10a0deb4eca1a4807c436 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 22:51:39 +0200 Subject: [PATCH 032/144] bump wgpu-core and fix VertexBufferDescriptor --- Cargo.lock | 4 +- cli/Cargo.toml | 2 +- cli/ops/webgpu/pipeline.rs | 114 ++++++++++++++++++++----------------- 3 files changed, 65 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 260dc6b4ddf0e8..ac782d949bdf3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3454,9 +3454,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c266a580d5cc13410797edc1bd71518033792945c25bc071a8d3bbdc46710de" +checksum = "ea487deeae90e06d77eb8e6cef945247774e7c0a0a226d238b31e90633594365" dependencies = [ "arrayvec", "bitflags", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 79d5e1a943d6b5..bcab7fa3730e60 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -75,7 +75,7 @@ walkdir = "2.3.1" warp = { version = "0.2.5", features = ["tls"] } semver-parser = "0.9.0" uuid = { version = "0.8.1", features = ["v4"] } -wgc = { package = "wgpu-core", version = "0.6.4" } +wgc = { package = "wgpu-core", version = "0.6.5" } wgt = { package = "wgpu-types", version = "0.6.1" } [target.'cfg(windows)'.dependencies] diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index d4e8ac6357b7eb..5c7cccdda2b5a6 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -311,7 +311,7 @@ struct GPUVertexBufferLayoutDescriptor { #[serde(rename_all = "camelCase")] struct GPUVertexStateDescriptor { index_format: Option, - vertex_buffers: Option>, // ODO: nullable + vertex_buffers: Option>>, } #[derive(Deserialize)] @@ -479,59 +479,69 @@ pub fn op_webgpu_create_render_pipeline( Cow::Owned( vertex_buffers .iter() - .map(|buffer| wgc::pipeline::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode.clone() { - Some(step_mode) => match step_mode.as_str() { - "vertex" => wgt::InputStepMode::Vertex, - "instance" => wgt::InputStepMode::Instance, - _ => unreachable!(), - }, - None => wgt::InputStepMode::Vertex, - }, - attributes: Cow::Owned( - buffer - .attributes - .iter() - .map(|attribute| wgt::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format.as_str() { - "uchar2" => wgt::VertexFormat::Uchar2, - "uchar4" => wgt::VertexFormat::Uchar4, - "char2" => wgt::VertexFormat::Char2, - "char4" => wgt::VertexFormat::Char4, - "uchar2norm" => wgt::VertexFormat::Uchar2Norm, - "uchar4norm" => wgt::VertexFormat::Uchar4, - "char2norm" => wgt::VertexFormat::Char2Norm, - "char4norm" => wgt::VertexFormat::Char4Norm, - "ushort2" => wgt::VertexFormat::Ushort2, - "ushort4" => wgt::VertexFormat::Ushort4, - "short2" => wgt::VertexFormat::Short2, - "short4" => wgt::VertexFormat::Short4, - "ushort2norm" => wgt::VertexFormat::Ushort2Norm, - "ushort4norm" => wgt::VertexFormat::Ushort4Norm, - "short2norm" => wgt::VertexFormat::Short2Norm, - "short4norm" => wgt::VertexFormat::Short4Norm, - "half2" => wgt::VertexFormat::Half2, - "half4" => wgt::VertexFormat::Half4, - "float" => wgt::VertexFormat::Float, - "float2" => wgt::VertexFormat::Float2, - "float3" => wgt::VertexFormat::Float3, - "float4" => wgt::VertexFormat::Float4, - "uint" => wgt::VertexFormat::Uint, - "uint2" => wgt::VertexFormat::Uint2, - "uint3" => wgt::VertexFormat::Uint3, - "uint4" => wgt::VertexFormat::Uint4, - "int" => wgt::VertexFormat::Int, - "int2" => wgt::VertexFormat::Int2, - "int3" => wgt::VertexFormat::Int3, - "int4" => wgt::VertexFormat::Int4, + .map(|buffer| { + if let Some(buffer) = buffer { + wgc::pipeline::VertexBufferDescriptor { + stride: buffer.array_stride, + step_mode: match buffer.step_mode.clone() { + Some(step_mode) => match step_mode.as_str() { + "vertex" => wgt::InputStepMode::Vertex, + "instance" => wgt::InputStepMode::Instance, _ => unreachable!(), }, - shader_location: attribute.shader_location, - }) - .collect::>(), - ), + None => wgt::InputStepMode::Vertex, + }, + attributes: Cow::Owned( + buffer + .attributes + .iter() + .map(|attribute| wgt::VertexAttributeDescriptor { + offset: attribute.offset, + format: match attribute.format.as_str() { + "uchar2" => wgt::VertexFormat::Uchar2, + "uchar4" => wgt::VertexFormat::Uchar4, + "char2" => wgt::VertexFormat::Char2, + "char4" => wgt::VertexFormat::Char4, + "uchar2norm" => wgt::VertexFormat::Uchar2Norm, + "uchar4norm" => wgt::VertexFormat::Uchar4, + "char2norm" => wgt::VertexFormat::Char2Norm, + "char4norm" => wgt::VertexFormat::Char4Norm, + "ushort2" => wgt::VertexFormat::Ushort2, + "ushort4" => wgt::VertexFormat::Ushort4, + "short2" => wgt::VertexFormat::Short2, + "short4" => wgt::VertexFormat::Short4, + "ushort2norm" => wgt::VertexFormat::Ushort2Norm, + "ushort4norm" => wgt::VertexFormat::Ushort4Norm, + "short2norm" => wgt::VertexFormat::Short2Norm, + "short4norm" => wgt::VertexFormat::Short4Norm, + "half2" => wgt::VertexFormat::Half2, + "half4" => wgt::VertexFormat::Half4, + "float" => wgt::VertexFormat::Float, + "float2" => wgt::VertexFormat::Float2, + "float3" => wgt::VertexFormat::Float3, + "float4" => wgt::VertexFormat::Float4, + "uint" => wgt::VertexFormat::Uint, + "uint2" => wgt::VertexFormat::Uint2, + "uint3" => wgt::VertexFormat::Uint3, + "uint4" => wgt::VertexFormat::Uint4, + "int" => wgt::VertexFormat::Int, + "int2" => wgt::VertexFormat::Int2, + "int3" => wgt::VertexFormat::Int3, + "int4" => wgt::VertexFormat::Int4, + _ => unreachable!(), + }, + shader_location: attribute.shader_location, + }) + .collect::>(), + ), + } + } else { + wgc::pipeline::VertexBufferDescriptor { + stride: 0, + step_mode: wgt::InputStepMode::Vertex, + attributes: Default::default(), + } + } }) .collect::>(), ) From 704e4db10b8ecf322f143b6234f5352190705a18 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 15 Oct 2020 23:23:01 +0200 Subject: [PATCH 033/144] fix gpubuffer mapping --- cli/ops/webgpu/buffer.rs | 4 ++-- cli/rt/14_webgpu.js | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 0da88ff19aa78d..516ce727d639bc 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -137,11 +137,11 @@ pub async fn op_webgpu_buffer_get_map_async( wgc::gfx_select!(buffer => instance.buffer_map_async( buffer, - args.offset..args.size, + args.offset..(args.offset + args.size), wgc::resource::BufferMapOperation { host: match args.mode { 1 => wgc::device::HostMap::Read, - 2 => wgc::device::HostMap::Read, + 2 => wgc::device::HostMap::Write, _ => unreachable!(), }, callback: buffer_map_future_wrapper, diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 026f6cd6cbf511..4e876144371bb7 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -370,7 +370,8 @@ class GPUBuffer { #rid; #size; - #mappedSize; // TODO: is this OK? + #mappedSize; + #mappedOffset; constructor(rid, label, size) { this.#rid = rid; @@ -379,19 +380,19 @@ } async mapAsync(mode, offset = 0, size = undefined) { - this.#mappedSize = size ?? this.#size; // TODO: is this OK? + this.#mappedOffset = offset; + this.#mappedSize = size ?? (this.#size - offset); await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { instanceRid, bufferRid: this.#rid, mode, offset, size: this.#mappedSize, - } // TODO: is this OK? - ); + }); } getMappedRange(offset = 0, size = undefined) { - const buf = new ArrayBuffer(size ?? this.#mappedSize); // TODO: is this OK? + const buf = new ArrayBuffer(size ?? ((this.#mappedOffset + this.#mappedSize) - offset)); core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", @@ -399,7 +400,7 @@ instanceRid, bufferRid: this.#rid, offset, - size, + size: size ?? this.#mappedSize, }, buf, ); @@ -415,7 +416,7 @@ } destroy() { - throw new Error("Not yet implemented"); // wgpu master + throw new Error("Not yet implemented"); } } @@ -440,7 +441,7 @@ } destroy() { - throw new Error("Not yet implemented"); // wgpu master + throw new Error("Not yet implemented"); } } From 877119fb103b48b4986457380703fd228c51844c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 16 Oct 2020 12:56:07 +0200 Subject: [PATCH 034/144] fix more compiler errors --- cli/ops/webgpu/bundle.rs | 10 +++++----- cli/ops/webgpu/compute_pass.rs | 8 ++++---- cli/ops/webgpu/pipeline.rs | 22 +++++++++++----------- cli/ops/webgpu/render_pass.rs | 8 ++++---- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index 49d140ac26dfe5..b748544257ed8a 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -139,17 +139,17 @@ pub fn op_webgpu_render_bundle_encoder_finish( let instance = state .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?.clone(); let render_bundle_encoder = state .resource_table - .get_mut::( + .get::( args.render_bundle_encoder_rid, ) - .ok_or_else(bad_resource_id)?; + .ok_or_else(bad_resource_id)?.clone(); let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( - *render_bundle_encoder, + render_bundle_encoder, &wgc::command::RenderBundleDescriptor { label: args.label.map(|label| Cow::Owned(label)), }, diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index 37d19e21bc4850..4270a6ad1a8015 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -161,6 +161,10 @@ pub fn op_webgpu_compute_pass_end_pass( ) -> Result { let args: ComputePassEndPassArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?.clone(); let command_encoder = *state .resource_table .get::(args.command_encoder_rid) @@ -169,10 +173,6 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; wgc::gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( command_encoder, diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 5c7cccdda2b5a6..2c3b819de9ed17 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -153,6 +153,12 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; + + let instance = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?.clone(); + let device = *state .resource_table .get::(args.device_rid) @@ -184,11 +190,6 @@ pub fn op_webgpu_create_compute_pipeline( }), }; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let (compute_pipeline, _) = wgc::gfx_select!(device => instance.device_create_compute_pipeline( device, &descriptor, @@ -340,6 +341,10 @@ pub fn op_webgpu_create_render_pipeline( ) -> Result { let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; + let instance = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?.clone(); let device = *state .resource_table .get::(args.device_rid) @@ -369,7 +374,7 @@ pub fn op_webgpu_create_render_pipeline( if let Some(state) = &args.depth_stencil_state { depth_stencil_state = Some(wgt::DepthStencilStateDescriptor { - format: serialize_texture_format(state.format)?, + format: serialize_texture_format(state.format.clone())?, depth_write_enabled: state.depth_write_enabled.unwrap_or(false), depth_compare: state .depth_compare @@ -413,11 +418,6 @@ pub fn op_webgpu_create_render_pipeline( let vertex_stage = serialize_programmable_stage_descriptor(state, args.vertex_stage)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let descriptor = wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(|label| Cow::Owned(label)), layout, diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index f04ae5910d810e..c9ead20712128b 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -293,14 +293,14 @@ pub fn op_webgpu_render_pass_end_pass( .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; + let instance = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?.clone(); let render_pass = state .resource_table .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; wgc::gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; From 7e9ee9ac48f3a8ce98cbc44bbf778c52d4939d92 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 16 Oct 2020 14:38:00 +0200 Subject: [PATCH 035/144] fix remaining compile errors --- cli/ops/webgpu/buffer.rs | 10 ++++++---- cli/ops/webgpu/bundle.rs | 15 +++++++-------- cli/ops/webgpu/command_encoder.rs | 8 ++++---- cli/ops/webgpu/compute_pass.rs | 3 ++- cli/ops/webgpu/mod.rs | 2 +- cli/ops/webgpu/pipeline.rs | 9 +++++---- cli/ops/webgpu/render_pass.rs | 5 +++-- cli/ops/webgpu/shader.rs | 4 ++-- cli/rt/14_webgpu.js | 6 ++++-- 9 files changed, 34 insertions(+), 28 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 516ce727d639bc..a64cd991900876 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -129,10 +129,12 @@ pub async fn op_webgpu_buffer_get_map_async( ) }; let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; - boxed_sender.send(match status { - wgc::resource::BufferMapAsyncStatus::Success => Ok(()), - _ => unreachable!(), // TODO - }); + boxed_sender + .send(match status { + wgc::resource::BufferMapAsyncStatus::Success => Ok(()), + _ => unreachable!(), // TODO + }) + .unwrap(); } wgc::gfx_select!(buffer => instance.buffer_map_async( diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index b748544257ed8a..e32194dcf5a0dd 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -137,16 +137,15 @@ pub fn op_webgpu_render_bundle_encoder_finish( ) -> Result { let args: RenderBundleEncoderFinishArgs = serde_json::from_value(args)?; + let render_bundle_encoder = *state + .resource_table + .remove::(args.render_bundle_encoder_rid) + .ok_or_else(bad_resource_id)?; let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?.clone(); - let render_bundle_encoder = state - .resource_table - .get::( - args.render_bundle_encoder_rid, - ) - .ok_or_else(bad_resource_id)?.clone(); + .ok_or_else(bad_resource_id)? + .clone(); let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, @@ -347,7 +346,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( struct RenderBundleEncoderSetIndexBufferArgs { render_bundle_encoder_rid: u32, buffer: u32, - index_format: String, // wgpu#978 + _index_format: String, // wgpu#978 offset: u64, size: u64, } diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index e6b8285dbe15f2..9a8b9919bd5e20 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -81,7 +81,7 @@ struct CreateCommandEncoderArgs { instance_rid: u32, device_rid: u32, label: Option, - measure_execution_time: Option, // waiting for wgpu to add measure_execution_time + _measure_execution_time: Option, // waiting for wgpu to add measure_execution_time } pub fn op_webgpu_create_command_encoder( @@ -146,11 +146,11 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { #[serde(rename_all = "camelCase")] struct CommandEncoderBeginRenderPassArgs { command_encoder_rid: u32, - label: Option, // wgpu#974 + _label: Option, // wgpu#974 color_attachments: Vec, depth_stencil_attachment: Option, - occlusion_query_set: u32, // wgpu#721 + _occlusion_query_set: u32, // wgpu#721 } pub fn op_webgpu_command_encoder_begin_render_pass( @@ -279,7 +279,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( #[serde(rename_all = "camelCase")] struct CommandEncoderBeginComputePassArgs { command_encoder_rid: u32, - label: Option, // wgpu#974 + _label: Option, // wgpu#974 } pub fn op_webgpu_command_encoder_begin_compute_pass( diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index 4270a6ad1a8015..bb65c0480f633c 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -164,7 +164,8 @@ pub fn op_webgpu_compute_pass_end_pass( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?.clone(); + .ok_or_else(bad_resource_id)? + .clone(); let command_encoder = *state .resource_table .get::(args.command_encoder_rid) diff --git a/cli/ops/webgpu/mod.rs b/cli/ops/webgpu/mod.rs index 7e5be7fb07b05d..358971b1fb9f5f 100644 --- a/cli/ops/webgpu/mod.rs +++ b/cli/ops/webgpu/mod.rs @@ -160,7 +160,7 @@ struct GPULimits { struct RequestDeviceArgs { instance_rid: u32, adapter_rid: u32, - label: Option, // wgpu#976 + _label: Option, // wgpu#976 features: Option>, limits: Option, } diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 2c3b819de9ed17..e776a9a684ecd9 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -153,11 +153,11 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; - let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?.clone(); + .ok_or_else(bad_resource_id)? + .clone(); let device = *state .resource_table @@ -344,7 +344,8 @@ pub fn op_webgpu_create_render_pipeline( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?.clone(); + .ok_or_else(bad_resource_id)? + .clone(); let device = *state .resource_table .get::(args.device_rid) @@ -385,7 +386,7 @@ pub fn op_webgpu_create_render_pipeline( wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), - back: state.stencil_front.as_ref().map_or( + back: state.stencil_back.as_ref().map_or( wgt::StencilStateFaceDescriptor::IGNORE, serialize_stencil_state_face_descriptor, ), diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index c9ead20712128b..8c2ff4a9dc18d2 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -296,7 +296,8 @@ pub fn op_webgpu_render_pass_end_pass( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?.clone(); + .ok_or_else(bad_resource_id)? + .clone(); let render_pass = state .resource_table .get::(args.render_pass_rid) @@ -474,7 +475,7 @@ pub fn op_webgpu_render_pass_set_pipeline( struct RenderPassSetIndexBufferArgs { render_pass_rid: u32, buffer: u32, - index_format: String, // wgpu#978 + _index_format: String, // wgpu#978 offset: u64, size: u64, } diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index d84c532f71ac50..9185818a83f522 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -22,9 +22,9 @@ pub fn init(rt: &mut deno_core::JsRuntime) { struct CreateShaderModuleArgs { instance_rid: u32, device_rid: u32, - label: Option, // wgpu#977 + _label: Option, // wgpu#977 code: Option, - source_map: (), // not in wgpu + _source_map: (), // not in wgpu } pub fn op_webgpu_create_shader_module( diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 4e876144371bb7..0d4fcc552e02e8 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -97,7 +97,7 @@ } } - // TODO: https://gpuweb.github.io/gpuweb/#telemetry + // TODO: https://gpuweb.github.io/gpuweb/#errors-and-debugging class GPUDevice extends EventTarget { #rid; #adapter; @@ -392,7 +392,9 @@ } getMappedRange(offset = 0, size = undefined) { - const buf = new ArrayBuffer(size ?? ((this.#mappedOffset + this.#mappedSize) - offset)); + const buf = new ArrayBuffer( + size ?? ((this.#mappedOffset + this.#mappedSize) - offset), + ); core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", From f13f86e6480981b535a1aa22e869572143114f43 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 16 Oct 2020 14:59:57 +0200 Subject: [PATCH 036/144] fix some lint errors --- cli/ops/webgpu/binding.rs | 6 ++--- cli/ops/webgpu/buffer.rs | 2 +- cli/ops/webgpu/bundle.rs | 10 ++++---- cli/ops/webgpu/command_encoder.rs | 4 ++-- cli/ops/webgpu/compute_pass.rs | 6 +++-- cli/ops/webgpu/pipeline.rs | 40 +++++++++++++++++++++---------- cli/ops/webgpu/render_pass.rs | 6 +++-- cli/ops/webgpu/sampler.rs | 11 +++++---- cli/ops/webgpu/texture.rs | 8 +++---- 9 files changed, 57 insertions(+), 36 deletions(-) diff --git a/cli/ops/webgpu/binding.rs b/cli/ops/webgpu/binding.rs index bc74e5fd3ff004..65e64d76b59bcc 100644 --- a/cli/ops/webgpu/binding.rs +++ b/cli/ops/webgpu/binding.rs @@ -144,7 +144,7 @@ pub fn op_webgpu_create_bind_group_layout( } let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), entries: Cow::Owned(entries), }; let bind_group_layout = wgc::gfx_select!(device => instance.device_create_bind_group_layout( @@ -199,7 +199,7 @@ pub fn op_webgpu_create_pipeline_layout( .ok_or_else(bad_resource_id)?; let descriptor = wgc::binding_model::PipelineLayoutDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; @@ -285,7 +285,7 @@ pub fn op_webgpu_create_bind_group( } let descriptor = wgc::binding_model::BindGroupDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), layout: *state .resource_table .get::(args.layout) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index a64cd991900876..b94e254bf3a15a 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -64,7 +64,7 @@ pub fn op_webgpu_create_buffer( .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::BufferDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), size: args.size, usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index e32194dcf5a0dd..b55676c01a7441 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -102,7 +102,7 @@ pub fn op_webgpu_create_render_bundle_encoder( } let descriptor = wgc::command::RenderBundleEncoderDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), color_formats: Cow::Owned(color_formats), depth_stencil_format: args .depth_stencil_format @@ -150,7 +150,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgc::command::RenderBundleDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), }, std::marker::PhantomData ))?; @@ -237,9 +237,10 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::bundle_ffi::wgpu_render_bundle_push_debug_group( render_bundle_encoder, - std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + label.as_ptr(), ); } @@ -299,9 +300,10 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( render_bundle_encoder, - std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + label.as_ptr(), ); } diff --git a/cli/ops/webgpu/command_encoder.rs b/cli/ops/webgpu/command_encoder.rs index 9a8b9919bd5e20..121f511d28271b 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/cli/ops/webgpu/command_encoder.rs @@ -101,7 +101,7 @@ pub fn op_webgpu_create_command_encoder( .ok_or_else(bad_resource_id)?; let descriptor = wgt::CommandEncoderDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), }; let command_encoder = wgc::gfx_select!(device => instance.device_create_command_encoder( device, @@ -703,7 +703,7 @@ pub fn op_webgpu_command_encoder_finish( .ok_or_else(bad_resource_id)?; let descriptor = wgt::CommandBufferDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), }; let command_buffer = wgc::gfx_select!(command_encoder => instance.command_encoder_finish( command_encoder, diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index bb65c0480f633c..444091f64405f6 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -252,9 +252,10 @@ pub fn op_webgpu_compute_pass_push_debug_group( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::compute_ffi::wgpu_compute_pass_push_debug_group( compute_pass, - std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + label.as_ptr(), 0, // wgpu#975 ); } @@ -305,9 +306,10 @@ pub fn op_webgpu_compute_pass_insert_debug_marker( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( compute_pass, - std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + label.as_ptr(), 0, // wgpu#975 ); } diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index e776a9a684ecd9..56c8a6644eabab 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -47,8 +47,8 @@ fn serialize_programmable_stage_descriptor( }) } -fn serialize_stencil_operation(operation: &String) -> wgt::StencilOperation { - match operation.as_str() { +fn serialize_stencil_operation(operation: &str) -> wgt::StencilOperation { + match operation { "keep" => wgt::StencilOperation::Keep, "zero" => wgt::StencilOperation::Zero, "replace" => wgt::StencilOperation::Replace, @@ -68,24 +68,32 @@ fn serialize_stencil_state_face_descriptor( compare: state .compare .as_ref() - .map_or(wgt::CompareFunction::Always, serialize_compare_function), + .map_or(wgt::CompareFunction::Always, |op| { + serialize_compare_function(op) + }), fail_op: state .fail_op .as_ref() - .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), + .map_or(wgt::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), depth_fail_op: state .depth_fail_op .as_ref() - .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), + .map_or(wgt::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), pass_op: state .pass_op .as_ref() - .map_or(wgt::StencilOperation::Keep, serialize_stencil_operation), + .map_or(wgt::StencilOperation::Keep, |op| { + serialize_stencil_operation(op) + }), } } -fn serialize_blend_factor(blend_factor: &String) -> wgt::BlendFactor { - match blend_factor.as_str() { +fn serialize_blend_factor(blend_factor: &str) -> wgt::BlendFactor { + match blend_factor { "zero" => wgt::BlendFactor::Zero, "one" => wgt::BlendFactor::One, "src-color" => wgt::BlendFactor::SrcColor, @@ -110,11 +118,15 @@ fn serialize_blend_descriptor( src_factor: blend .src_factor .as_ref() - .map_or(wgt::BlendFactor::One, serialize_blend_factor), + .map_or(wgt::BlendFactor::One, |factor| { + serialize_blend_factor(factor) + }), dst_factor: blend .dst_factor .as_ref() - .map_or(wgt::BlendFactor::Zero, serialize_blend_factor), + .map_or(wgt::BlendFactor::Zero, |factor| { + serialize_blend_factor(factor) + }), operation: match &blend.operation { Some(operation) => match operation.as_str() { "add" => wgt::BlendOperation::Add, @@ -178,7 +190,7 @@ pub fn op_webgpu_create_compute_pipeline( serialize_programmable_stage_descriptor(state, args.compute_stage)?; let descriptor = wgc::pipeline::ComputePipelineDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), layout, compute_stage, }; @@ -380,7 +392,9 @@ pub fn op_webgpu_create_render_pipeline( depth_compare: state .depth_compare .as_ref() - .map_or(wgt::CompareFunction::Always, serialize_compare_function), + .map_or(wgt::CompareFunction::Always, |compare| { + serialize_compare_function(compare) + }), stencil: wgt::StencilStateDescriptor { front: state.stencil_front.as_ref().map_or( wgt::StencilStateFaceDescriptor::IGNORE, @@ -420,7 +434,7 @@ pub fn op_webgpu_create_render_pipeline( serialize_programmable_stage_descriptor(state, args.vertex_stage)?; let descriptor = wgc::pipeline::RenderPipelineDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), layout, vertex_stage, fragment_stage, diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 8c2ff4a9dc18d2..1628160f2139d9 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -376,9 +376,10 @@ pub fn op_webgpu_render_pass_push_debug_group( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::render_ffi::wgpu_render_pass_push_debug_group( render_pass, - std::ffi::CString::new(args.group_label).unwrap().as_ptr(), + label.as_ptr(), 0, // wgpu#975 ); } @@ -429,9 +430,10 @@ pub fn op_webgpu_render_pass_insert_debug_marker( .ok_or_else(bad_resource_id)?; unsafe { + let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::render_ffi::wgpu_render_pass_insert_debug_marker( render_pass, - std::ffi::CString::new(args.marker_label).unwrap().as_ptr(), + label.as_ptr(), 0, // wgpu#975 ); } diff --git a/cli/ops/webgpu/sampler.rs b/cli/ops/webgpu/sampler.rs index ec3fe49562e6b9..fdf3ccc9063772 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/cli/ops/webgpu/sampler.rs @@ -40,8 +40,8 @@ fn serialize_filter_mode(filter_mode: Option) -> wgt::FilterMode { } } -pub fn serialize_compare_function(compare: &String) -> wgt::CompareFunction { - match compare.as_str() { +pub fn serialize_compare_function(compare: &str) -> wgt::CompareFunction { + match compare { "never" => wgt::CompareFunction::Never, "less" => wgt::CompareFunction::Less, "equal" => wgt::CompareFunction::Equal, @@ -89,7 +89,7 @@ pub fn op_webgpu_create_sampler( .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::SamplerDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), address_modes: [ serialize_address_mode(args.address_mode_u), serialize_address_mode(args.address_mode_v), @@ -102,7 +102,10 @@ pub fn op_webgpu_create_sampler( lod_max_clamp: args .lod_max_clamp .unwrap_or(wgc::resource::SamplerDescriptor::default().lod_max_clamp), - compare: args.compare.as_ref().map(serialize_compare_function), + compare: args + .compare + .as_ref() + .map(|compare| serialize_compare_function(compare)), anisotropy_clamp: std::num::NonZeroU8::new( args.max_anisotropy.unwrap_or(0), ), diff --git a/cli/ops/webgpu/texture.rs b/cli/ops/webgpu/texture.rs index b4a9b945b31273..84ba0f88d84af4 100644 --- a/cli/ops/webgpu/texture.rs +++ b/cli/ops/webgpu/texture.rs @@ -157,7 +157,7 @@ pub fn op_webgpu_create_texture( .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::TextureDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), size: wgt::Extent3d { width: args.size.width, height: args.size.height, @@ -223,11 +223,9 @@ pub fn op_webgpu_create_texture_view( .ok_or_else(bad_resource_id)?; let descriptor = wgc::resource::TextureViewDescriptor { - label: args.label.map(|label| Cow::Owned(label)), + label: args.label.map(Cow::Owned), format: args.format.map(serialize_texture_format).transpose()?, - dimension: args - .dimension - .map(|dimension| serialize_dimension(dimension)), + dimension: args.dimension.map(serialize_dimension), aspect: match args.aspect { Some(aspect) => match aspect.as_str() { "all" => wgt::TextureAspect::All, From bec5d749fa961d385d763c9523fd34c614095b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 16 Oct 2020 15:26:15 +0200 Subject: [PATCH 037/144] lint rust --- cli/ops/webgpu/buffer.rs | 13 ++----------- cli/ops/webgpu/bundle.rs | 3 +-- cli/ops/webgpu/compute_pass.rs | 3 +-- cli/ops/webgpu/pipeline.rs | 6 ++---- cli/ops/webgpu/render_pass.rs | 3 +-- 5 files changed, 7 insertions(+), 21 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index b94e254bf3a15a..ea2ce61df67e65 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -112,22 +112,13 @@ pub async fn op_webgpu_buffer_get_map_async( let (sender, receiver) = oneshot::channel::>(); let boxed_sender = Box::new(sender); - let sender_ptr = Box::into_raw(boxed_sender); - let sender_ptr = unsafe { - std::mem::transmute::<*mut oneshot::Sender>, *mut u8>( - sender_ptr, - ) - }; + let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; extern "C" fn buffer_map_future_wrapper( status: wgc::resource::BufferMapAsyncStatus, user_data: *mut u8, ) { - let sender_ptr = unsafe { - std::mem::transmute::<*mut u8, *mut oneshot::Sender>>( - user_data, - ) - }; + let sender_ptr = user_data as *mut oneshot::Sender>; let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; boxed_sender .send(match status { diff --git a/cli/ops/webgpu/bundle.rs b/cli/ops/webgpu/bundle.rs index b55676c01a7441..c0797fe00198be 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/cli/ops/webgpu/bundle.rs @@ -144,8 +144,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)? - .clone(); + .ok_or_else(bad_resource_id)?; let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/cli/ops/webgpu/compute_pass.rs b/cli/ops/webgpu/compute_pass.rs index 444091f64405f6..3bcd0a245b637d 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/cli/ops/webgpu/compute_pass.rs @@ -164,8 +164,7 @@ pub fn op_webgpu_compute_pass_end_pass( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)? - .clone(); + .ok_or_else(bad_resource_id)?; let command_encoder = *state .resource_table .get::(args.command_encoder_rid) diff --git a/cli/ops/webgpu/pipeline.rs b/cli/ops/webgpu/pipeline.rs index 56c8a6644eabab..f7349ca908522a 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/cli/ops/webgpu/pipeline.rs @@ -168,8 +168,7 @@ pub fn op_webgpu_create_compute_pipeline( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)? - .clone(); + .ok_or_else(bad_resource_id)?; let device = *state .resource_table @@ -356,8 +355,7 @@ pub fn op_webgpu_create_render_pipeline( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)? - .clone(); + .ok_or_else(bad_resource_id)?; let device = *state .resource_table .get::(args.device_rid) diff --git a/cli/ops/webgpu/render_pass.rs b/cli/ops/webgpu/render_pass.rs index 1628160f2139d9..9fd047265cad08 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/cli/ops/webgpu/render_pass.rs @@ -296,8 +296,7 @@ pub fn op_webgpu_render_pass_end_pass( let instance = state .resource_table .get::(args.instance_rid) - .ok_or_else(bad_resource_id)? - .clone(); + .ok_or_else(bad_resource_id)?; let render_pass = state .resource_table .get::(args.render_pass_rid) From 9b1e83f38498318bfa3764ee1db9f3d7d58d948f Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 16 Oct 2020 16:15:01 +0200 Subject: [PATCH 038/144] fix buffer mapping --- cli/ops/webgpu/buffer.rs | 7 ++++--- cli/rt/14_webgpu.js | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index ea2ce61df67e65..5183b5ea800695 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -178,12 +178,13 @@ pub fn op_webgpu_buffer_get_mapped_range( std::num::NonZeroU64::new(args.size) ))?; - // TODO: use - let _slice = unsafe { + let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) }; - Ok(json!({})) + Ok(json!({ + "buffer": slice, + })) } #[derive(Deserialize)] diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 0d4fcc552e02e8..395c827903231e 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -135,7 +135,12 @@ ...descriptor, }); - const buffer = new GPUBuffer(rid, descriptor.label, descriptor.size); + const buffer = new GPUBuffer( + rid, + descriptor.label, + descriptor.size, + descriptor.mappedAtCreation, + ); GPUBufferMap.set(buffer, rid); return buffer; } @@ -373,10 +378,15 @@ #mappedSize; #mappedOffset; - constructor(rid, label, size) { + constructor(rid, label, size, mappedAtCreation) { this.#rid = rid; this.label = label ?? null; this.#size = size; + + if (mappedAtCreation) { + this.#mappedSize = size; + this.#mappedOffset = 0; + } } async mapAsync(mode, offset = 0, size = undefined) { @@ -392,11 +402,7 @@ } getMappedRange(offset = 0, size = undefined) { - const buf = new ArrayBuffer( - size ?? ((this.#mappedOffset + this.#mappedSize) - offset), - ); - - core.jsonOpSync( + const { buffer } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { instanceRid, @@ -404,10 +410,9 @@ offset, size: size ?? this.#mappedSize, }, - buf, ); - return buf; + return new Uint8Array(buffer).buffer; } unmap() { From 8107a61410f2362049a098523e6021c068a0b115 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 16 Oct 2020 19:29:10 +0200 Subject: [PATCH 039/144] fixes & temporary get_mapped_range solution --- cli/ops/webgpu/buffer.rs | 19 +++++++++++++++++-- cli/ops/webgpu/shader.rs | 2 +- cli/rt/14_webgpu.js | 31 ++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/cli/ops/webgpu/buffer.rs b/cli/ops/webgpu/buffer.rs index 5183b5ea800695..6ab7ff87b6f782 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/cli/ops/webgpu/buffer.rs @@ -182,8 +182,16 @@ pub fn op_webgpu_buffer_get_mapped_range( std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) }; + let mut buf: Vec = vec![0; slice.len()]; + buf.copy_from_slice(slice); + + let rid = state + .resource_table + .add("webGPUBufferMapped", Box::new(slice)); + Ok(json!({ - "buffer": slice, + "rid": rid, + "buffer": buf, })) } @@ -192,12 +200,13 @@ pub fn op_webgpu_buffer_get_mapped_range( struct BufferUnmapArgs { instance_rid: u32, buffer_rid: u32, + mapped_rid: u32, } pub fn op_webgpu_buffer_unmap( state: &mut OpState, args: Value, - _zero_copy: &mut [ZeroCopyBuf], + zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: BufferUnmapArgs = serde_json::from_value(args)?; @@ -205,11 +214,17 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; + let mapped = *state + .resource_table + .remove::<&mut [u8]>(args.mapped_rid) + .ok_or_else(bad_resource_id)?; let instance = state .resource_table .get_mut::(args.instance_rid) .ok_or_else(bad_resource_id)?; + mapped.copy_from_slice(&*zero_copy[0]); + wgc::gfx_select!(buffer => instance.buffer_unmap(buffer))?; Ok(json!({})) diff --git a/cli/ops/webgpu/shader.rs b/cli/ops/webgpu/shader.rs index 9185818a83f522..b274b11f689fdf 100644 --- a/cli/ops/webgpu/shader.rs +++ b/cli/ops/webgpu/shader.rs @@ -24,7 +24,7 @@ struct CreateShaderModuleArgs { device_rid: u32, _label: Option, // wgpu#977 code: Option, - _source_map: (), // not in wgpu + _source_map: Option<()>, // not in wgpu } pub fn op_webgpu_create_shader_module( diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 395c827903231e..997d4cbf5017f5 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -206,16 +206,19 @@ entries: descriptor.entries.map((entry) => { if (entry instanceof GPUSampler) { return { + binding: entry.binding, kind: "GPUSampler", resource: GPUSamplerMap.get(entry), }; } else if (entry instanceof GPUTextureView) { return { + binding: entry.binding, kind: "GPUTextureView", resource: GPUTextureViewMap.get(entry), }; } else { return { + binding: entry.binding, kind: "GPUBuffer", resource: GPUBufferMap.get(entry.buffer), offset: entry.offset, @@ -237,9 +240,12 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - code: (typeof descriptor.code === "string") && descriptor.code, + code: (typeof descriptor.code === "string") + ? descriptor.code + : undefined, + sourceMap: descriptor.sourceMap, }, - (descriptor.code instanceof Uint32Array) && descriptor.code, + (descriptor.code instanceof Uint32Array) ? descriptor.code : undefined, ); const shaderModule = new GPUShaderModule(rid, descriptor.label); @@ -252,8 +258,9 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - layout: descriptor.layout && - GPUPipelineLayoutMap.get(descriptor.layout), + layout: descriptor.layout + ? GPUPipelineLayoutMap.get(descriptor.layout) + : undefined, computeStage: { module: GPUShaderModuleMap.get(descriptor.computeStage.module), entryPoint: descriptor.computeStage.entryPoint, @@ -377,6 +384,8 @@ #size; #mappedSize; #mappedOffset; + #mappedRid; + #mappedBuffer; constructor(rid, label, size, mappedAtCreation) { this.#rid = rid; @@ -402,7 +411,7 @@ } getMappedRange(offset = 0, size = undefined) { - const { buffer } = core.jsonOpSync( + const { buffer, rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { instanceRid, @@ -412,14 +421,17 @@ }, ); - return new Uint8Array(buffer).buffer; + this.#mappedRid = rid; + this.#mappedBuffer = new Uint8Array(buffer); + return this.#mappedBuffer.buffer; } unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { instanceRid, bufferRid: this.#rid, - }); + mappedRid: this.#mappedRid, + }, this.#mappedBuffer); } destroy() { @@ -600,8 +612,9 @@ (colorAttachment) => { const attachment = { attachment: GPUTextureViewMap.get(colorAttachment.attachment), - resolveTarget: colorAttachment.resolveTarget && - GPUTextureViewMap.get(colorAttachment.resolveTarget), + resolveTarget: colorAttachment.resolveTarget + ? GPUTextureViewMap.get(colorAttachment.resolveTarget) + : undefined, storeOp: colorAttachment.storeOp, }; From c6f535530056e7d6dcbbfcef2453a7ee9d15404d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 16 Oct 2020 21:26:04 +0200 Subject: [PATCH 040/144] fix createBindGroup resource --- cli/rt/14_webgpu.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/rt/14_webgpu.js b/cli/rt/14_webgpu.js index 997d4cbf5017f5..99f242ed794bb2 100644 --- a/cli/rt/14_webgpu.js +++ b/cli/rt/14_webgpu.js @@ -208,21 +208,21 @@ return { binding: entry.binding, kind: "GPUSampler", - resource: GPUSamplerMap.get(entry), + resource: GPUSamplerMap.get(entry.resource), }; } else if (entry instanceof GPUTextureView) { return { binding: entry.binding, kind: "GPUTextureView", - resource: GPUTextureViewMap.get(entry), + resource: GPUTextureViewMap.get(entry.resource), }; } else { return { binding: entry.binding, - kind: "GPUBuffer", - resource: GPUBufferMap.get(entry.buffer), - offset: entry.offset, - size: entry.size, + kind: "GPUBufferBinding", + resource: GPUBufferMap.get(entry.resource.buffer), + offset: entry.resource.offset, + size: entry.resource.size, }; } }), From 0903f6840024c35433319fa921e472ea7cfa2ce0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 9 Dec 2020 06:31:21 +0100 Subject: [PATCH 041/144] move to own op crate --- Cargo.lock | 13 +- cli/Cargo.toml | 4 +- cli/build.rs | 1 + cli/ops/webgpu.rs | 384 ++++++++++++++++++ {cli/rt => op_crates/webgpu}/14_webgpu.js | 0 op_crates/webgpu/Cargo.toml | 20 + {cli/ops => op_crates}/webgpu/binding.rs | 18 - {cli/ops => op_crates}/webgpu/buffer.rs | 23 -- {cli/ops => op_crates}/webgpu/bundle.rs | 63 --- .../webgpu/command_encoder.rs | 58 --- {cli/ops => op_crates}/webgpu/compute_pass.rs | 43 -- .../webgpu/mod.rs => op_crates/webgpu/lib.rs | 63 ++- {cli/ops => op_crates}/webgpu/pipeline.rs | 23 -- {cli/ops => op_crates}/webgpu/queue.rs | 18 - {cli/ops => op_crates}/webgpu/render_pass.rs | 88 ---- {cli/ops => op_crates}/webgpu/sampler.rs | 8 - {cli/ops => op_crates}/webgpu/shader.rs | 8 - {cli/ops => op_crates}/webgpu/texture.rs | 13 - 18 files changed, 441 insertions(+), 407 deletions(-) create mode 100644 cli/ops/webgpu.rs rename {cli/rt => op_crates/webgpu}/14_webgpu.js (100%) create mode 100644 op_crates/webgpu/Cargo.toml rename {cli/ops => op_crates}/webgpu/binding.rs (95%) rename {cli/ops => op_crates}/webgpu/buffer.rs (91%) rename {cli/ops => op_crates}/webgpu/bundle.rs (86%) rename {cli/ops => op_crates}/webgpu/command_encoder.rs (92%) rename {cli/ops => op_crates}/webgpu/compute_pass.rs (86%) rename cli/ops/webgpu/mod.rs => op_crates/webgpu/lib.rs (89%) rename {cli/ops => op_crates}/webgpu/pipeline.rs (97%) rename {cli/ops => op_crates}/webgpu/queue.rs (92%) rename {cli/ops => op_crates}/webgpu/render_pass.rs (86%) rename {cli/ops => op_crates}/webgpu/sampler.rs (95%) rename {cli/ops => op_crates}/webgpu/shader.rs (90%) rename {cli/ops => op_crates}/webgpu/texture.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index 8f83150d3d64c3..2af99bfcd2a43f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -569,6 +569,7 @@ dependencies = [ "deno_fetch", "deno_lint", "deno_web", + "deno_webgpu", "dissimilar", "dlopen", "dprint-plugin-typescript", @@ -612,8 +613,6 @@ dependencies = [ "warp", "webpki", "webpki-roots 0.19.0", - "wgpu-core", - "wgpu-types", "winapi 0.3.9", "winres", ] @@ -697,6 +696,16 @@ dependencies = [ "serde", ] +[[package]] +name = "deno_webgpu" +version = "0.1.0" +dependencies = [ + "deno_core", + "serde", + "wgpu-core", + "wgpu-types", +] + [[package]] name = "derive_more" version = "0.99.11" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index f19e079924a5c5..931ca31c9d59b9 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -24,6 +24,7 @@ deno_crypto = { path = "../op_crates/crypto", version = "0.3.0" } deno_core = { path = "../core", version = "0.69.0" } deno_web = { path = "../op_crates/web", version = "0.20.0" } deno_fetch = { path = "../op_crates/fetch", version = "0.12.0" } +deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.0" } regex = "1.3.9" serde = { version = "1.0.116", features = ["derive"] } @@ -38,6 +39,7 @@ deno_doc = "0.1.17" deno_fetch = { path = "../op_crates/fetch", version = "0.12.0" } deno_lint = "0.2.12" deno_web = { path = "../op_crates/web", version = "0.20.0" } +deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.0" } atty = "0.2.14" base64 = "0.12.3" @@ -84,8 +86,6 @@ walkdir = "2.3.1" warp = { version = "0.2.5", features = ["tls"] } webpki = "0.21.3" webpki-roots = "=0.19.0" # Pinned to v0.19.0 to match 'reqwest'. -wgc = { package = "wgpu-core", version = "0.6.5" } -wgt = { package = "wgpu-types", version = "0.6.1" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] } diff --git a/cli/build.rs b/cli/build.rs index b0088a9d83ad6c..cf057efc1c35ce 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -21,6 +21,7 @@ fn create_snapshot( deno_web::init(&mut js_runtime); deno_fetch::init(&mut js_runtime); deno_crypto::init(&mut js_runtime); + deno_webgpu::init(&mut js_runtime); // TODO(nayeemrmn): https://github.com/rust-lang/cargo/issues/3946 to get the // workspace root. let display_root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap(); diff --git a/cli/ops/webgpu.rs b/cli/ops/webgpu.rs new file mode 100644 index 00000000000000..704757252b93d0 --- /dev/null +++ b/cli/ops/webgpu.rs @@ -0,0 +1,384 @@ +use deno_webgpu::*; + +pub fn init(rt: &mut deno_core::JsRuntime) { + super::reg_json_sync( + rt, + "op_webgpu_create_instance", + op_webgpu_create_instance, + ); + super::reg_json_async( + rt, + "op_webgpu_request_adapter", + op_webgpu_request_adapter, + ); + super::reg_json_async( + rt, + "op_webgpu_request_device", + op_webgpu_request_device, + ); + + { + // buffer + super::reg_json_sync( + rt, + "op_webgpu_create_buffer", + buffer::op_webgpu_create_buffer, + ); + super::reg_json_async( + rt, + "op_webgpu_buffer_get_map_async", + buffer::op_webgpu_buffer_get_map_async, + ); + super::reg_json_sync( + rt, + "op_webgpu_buffer_get_mapped_range", + buffer::op_webgpu_buffer_get_mapped_range, + ); + super::reg_json_sync( + rt, + "op_webgpu_buffer_unmap", + buffer::op_webgpu_buffer_unmap, + ); + } + { + // texture + super::reg_json_sync( + rt, + "op_webgpu_create_texture", + texture::op_webgpu_create_texture, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_texture_view", + texture::op_webgpu_create_texture_view, + ); + } + { + // sampler + super::reg_json_sync( + rt, + "op_webgpu_create_sampler", + sampler::op_webgpu_create_sampler, + ); + } + { + // binding + super::reg_json_sync( + rt, + "op_webgpu_create_bind_group_layout", + binding::op_webgpu_create_bind_group_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_pipeline_layout", + binding::op_webgpu_create_pipeline_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_bind_group", + binding::op_webgpu_create_bind_group, + ); + } + { + // pipeline + super::reg_json_sync( + rt, + "op_webgpu_create_compute_pipeline", + pipeline::op_webgpu_create_compute_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pipeline_get_bind_group_layout", + pipeline::op_webgpu_compute_pipeline_get_bind_group_layout, + ); + super::reg_json_sync( + rt, + "op_webgpu_create_render_pipeline", + pipeline::op_webgpu_create_render_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pipeline_get_bind_group_layout", + pipeline::op_webgpu_render_pipeline_get_bind_group_layout, + ); + } + { + // command_encoder + super::reg_json_sync( + rt, + "op_webgpu_create_command_encoder", + command_encoder::op_webgpu_create_command_encoder, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_render_pass", + command_encoder::op_webgpu_command_encoder_begin_render_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_begin_compute_pass", + command_encoder::op_webgpu_command_encoder_begin_compute_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_buffer", + command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_buffer_to_texture", + command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_buffer", + command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_copy_texture_to_texture", + command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_push_debug_group", + command_encoder::op_webgpu_command_encoder_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_pop_debug_group", + command_encoder::op_webgpu_command_encoder_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_insert_debug_marker", + command_encoder::op_webgpu_command_encoder_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_finish", + command_encoder::op_webgpu_command_encoder_finish, + ); + } + { + // render_pass + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_viewport", + render_pass::op_webgpu_render_pass_set_viewport, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_scissor_rect", + render_pass::op_webgpu_render_pass_set_scissor_rect, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_blend_color", + render_pass::op_webgpu_render_pass_set_blend_color, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_stencil_reference", + render_pass::op_webgpu_render_pass_set_stencil_reference, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_execute_bundles", + render_pass::op_webgpu_render_pass_execute_bundles, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_end_pass", + render_pass::op_webgpu_render_pass_end_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_bind_group", + render_pass::op_webgpu_render_pass_set_bind_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_push_debug_group", + render_pass::op_webgpu_render_pass_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_pop_debug_group", + render_pass::op_webgpu_render_pass_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_insert_debug_marker", + render_pass::op_webgpu_render_pass_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_pipeline", + render_pass::op_webgpu_render_pass_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_index_buffer", + render_pass::op_webgpu_render_pass_set_index_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_set_vertex_buffer", + render_pass::op_webgpu_render_pass_set_vertex_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw", + render_pass::op_webgpu_render_pass_draw, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed", + render_pass::op_webgpu_render_pass_draw_indexed, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indirect", + render_pass::op_webgpu_render_pass_draw_indirect, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_draw_indexed_indirect", + render_pass::op_webgpu_render_pass_draw_indexed_indirect, + ); + } + { + // compute_pass + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_pipeline", + compute_pass::op_webgpu_compute_pass_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch", + compute_pass::op_webgpu_compute_pass_dispatch, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_dispatch_indirect", + compute_pass::op_webgpu_compute_pass_dispatch_indirect, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_end_pass", + compute_pass::op_webgpu_compute_pass_end_pass, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_set_bind_group", + compute_pass::op_webgpu_compute_pass_set_bind_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_push_debug_group", + compute_pass::op_webgpu_compute_pass_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_pop_debug_group", + compute_pass::op_webgpu_compute_pass_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_compute_pass_insert_debug_marker", + compute_pass::op_webgpu_compute_pass_insert_debug_marker, + ); + } + { + // bundle + super::reg_json_sync( + rt, + "op_webgpu_create_render_bundle_encoder", + bundle::op_webgpu_create_render_bundle_encoder, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_finish", + bundle::op_webgpu_render_bundle_encoder_finish, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_bind_group", + bundle::op_webgpu_render_bundle_encoder_set_bind_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_push_debug_group", + bundle::op_webgpu_render_bundle_encoder_push_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_pop_debug_group", + bundle::op_webgpu_render_bundle_encoder_pop_debug_group, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_insert_debug_marker", + bundle::op_webgpu_render_bundle_encoder_insert_debug_marker, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_pipeline", + bundle::op_webgpu_render_bundle_encoder_set_pipeline, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_index_buffer", + bundle::op_webgpu_render_bundle_encoder_set_index_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_set_vertex_buffer", + bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw", + bundle::op_webgpu_render_bundle_encoder_draw, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indexed", + bundle::op_webgpu_render_bundle_encoder_draw_indexed, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_bundle_encoder_draw_indirect", + bundle::op_webgpu_render_bundle_encoder_draw_indirect, + ); + } + { + // queue + super::reg_json_sync( + rt, + "op_webgpu_queue_submit", + queue::op_webgpu_queue_submit, + ); + super::reg_json_sync( + rt, + "op_webgpu_write_buffer", + queue::op_webgpu_write_buffer, + ); + super::reg_json_sync( + rt, + "op_webgpu_write_texture", + queue::op_webgpu_write_texture, + ); + } + { + // shader + super::reg_json_sync( + rt, + "op_webgpu_create_shader_module", + shader::op_webgpu_create_shader_module, + ); + } +} + diff --git a/cli/rt/14_webgpu.js b/op_crates/webgpu/14_webgpu.js similarity index 100% rename from cli/rt/14_webgpu.js rename to op_crates/webgpu/14_webgpu.js diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml new file mode 100644 index 00000000000000..810e860ae04314 --- /dev/null +++ b/op_crates/webgpu/Cargo.toml @@ -0,0 +1,20 @@ +# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_webgpu" +version = "0.1.0" +edition = "2018" +description = "provides webgpu Web API to deno_core" +authors = ["the Deno authors"] +license = "MIT" +readme = "README.md" +repository = "https://github.com/denoland/deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core = { version = "0.69.0", path = "../../core" } +serde = { version = "1.0.116", features = ["derive"] } +wgc = { package = "wgpu-core", version = "0.6.5" } +wgt = { package = "wgpu-types", version = "0.6.1" } diff --git a/cli/ops/webgpu/binding.rs b/op_crates/webgpu/binding.rs similarity index 95% rename from cli/ops/webgpu/binding.rs rename to op_crates/webgpu/binding.rs index 65e64d76b59bcc..c6de0bf534f0d4 100644 --- a/cli/ops/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -10,24 +10,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_bind_group_layout", - op_webgpu_create_bind_group_layout, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_create_pipeline_layout", - op_webgpu_create_pipeline_layout, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_create_bind_group", - op_webgpu_create_bind_group, - ); -} - fn serialize_texture_component_type( component_type: String, ) -> Result { diff --git a/cli/ops/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs similarity index 91% rename from cli/ops/webgpu/buffer.rs rename to op_crates/webgpu/buffer.rs index 6ab7ff87b6f782..883c9d122e094c 100644 --- a/cli/ops/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -13,29 +13,6 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_buffer", - op_webgpu_create_buffer, - ); - super::super::reg_json_async( - rt, - "op_webgpu_buffer_get_map_async", - op_webgpu_buffer_get_map_async, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_buffer_get_mapped_range", - op_webgpu_buffer_get_mapped_range, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_buffer_unmap", - op_webgpu_buffer_unmap, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBufferArgs { diff --git a/cli/ops/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs similarity index 86% rename from cli/ops/webgpu/bundle.rs rename to op_crates/webgpu/bundle.rs index c0797fe00198be..382cdf545558ab 100644 --- a/cli/ops/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -10,69 +10,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_render_bundle_encoder", - op_webgpu_create_render_bundle_encoder, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_finish", - op_webgpu_render_bundle_encoder_finish, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_bind_group", - op_webgpu_render_bundle_encoder_set_bind_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_push_debug_group", - op_webgpu_render_bundle_encoder_push_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_pop_debug_group", - op_webgpu_render_bundle_encoder_pop_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_insert_debug_marker", - op_webgpu_render_bundle_encoder_insert_debug_marker, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_pipeline", - op_webgpu_render_bundle_encoder_set_pipeline, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_index_buffer", - op_webgpu_render_bundle_encoder_set_index_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_set_vertex_buffer", - op_webgpu_render_bundle_encoder_set_vertex_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw", - op_webgpu_render_bundle_encoder_draw, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indexed", - op_webgpu_render_bundle_encoder_draw_indexed, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_bundle_encoder_draw_indirect", - op_webgpu_render_bundle_encoder_draw_indirect, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderBundleEncoderArgs { diff --git a/cli/ops/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs similarity index 92% rename from cli/ops/webgpu/command_encoder.rs rename to op_crates/webgpu/command_encoder.rs index 121f511d28271b..71277ef393476e 100644 --- a/cli/ops/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -9,64 +9,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_command_encoder", - op_webgpu_create_command_encoder, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_begin_render_pass", - op_webgpu_command_encoder_begin_render_pass, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_begin_compute_pass", - op_webgpu_command_encoder_begin_compute_pass, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_buffer", - op_webgpu_command_encoder_copy_buffer_to_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_buffer_to_texture", - op_webgpu_command_encoder_copy_buffer_to_texture, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_buffer", - op_webgpu_command_encoder_copy_texture_to_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_copy_texture_to_texture", - op_webgpu_command_encoder_copy_texture_to_texture, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_push_debug_group", - op_webgpu_command_encoder_push_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_pop_debug_group", - op_webgpu_command_encoder_pop_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_insert_debug_marker", - op_webgpu_command_encoder_insert_debug_marker, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_command_encoder_finish", - op_webgpu_command_encoder_finish, - ); -} - fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { match store_op.as_str() { "store" => wgc::command::StoreOp::Store, diff --git a/cli/ops/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs similarity index 86% rename from cli/ops/webgpu/compute_pass.rs rename to op_crates/webgpu/compute_pass.rs index 3bcd0a245b637d..9c3b9fe4053703 100644 --- a/cli/ops/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -8,49 +8,6 @@ use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_set_pipeline", - op_webgpu_compute_pass_set_pipeline, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_dispatch", - op_webgpu_compute_pass_dispatch, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_dispatch_indirect", - op_webgpu_compute_pass_dispatch_indirect, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_end_pass", - op_webgpu_compute_pass_end_pass, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_set_bind_group", - op_webgpu_compute_pass_set_bind_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_push_debug_group", - op_webgpu_compute_pass_push_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_pop_debug_group", - op_webgpu_compute_pass_pop_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pass_insert_debug_marker", - op_webgpu_compute_pass_insert_debug_marker, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassSetPipelineArgs { diff --git a/cli/ops/webgpu/mod.rs b/op_crates/webgpu/lib.rs similarity index 89% rename from cli/ops/webgpu/mod.rs rename to op_crates/webgpu/lib.rs index 358971b1fb9f5f..50aca05791f48e 100644 --- a/cli/ops/webgpu/mod.rs +++ b/op_crates/webgpu/lib.rs @@ -1,16 +1,18 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -mod binding; -mod buffer; -mod bundle; -mod command_encoder; -mod compute_pass; -mod pipeline; -mod queue; -mod render_pass; -mod sampler; -mod shader; -mod texture; +#![deny(warnings)] + +pub mod binding; +pub mod buffer; +pub mod bundle; +pub mod command_encoder; +pub mod compute_pass; +pub mod pipeline; +pub mod queue; +pub mod render_pass; +pub mod sampler; +pub mod shader; +pub mod texture; use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -23,34 +25,15 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::reg_json_sync( - rt, - "op_webgpu_create_instance", - op_webgpu_create_instance, - ); - super::reg_json_async( - rt, - "op_webgpu_request_adapter", - op_webgpu_request_adapter, - ); - super::reg_json_async( - rt, - "op_webgpu_request_device", - op_webgpu_request_device, - ); - - buffer::init(rt); - texture::init(rt); - sampler::init(rt); - binding::init(rt); - pipeline::init(rt); - command_encoder::init(rt); - render_pass::init(rt); - compute_pass::init(rt); - bundle::init(rt); - queue::init(rt); - shader::init(rt); +/// Execute this crates' JS source files. +pub fn init(isolate: &mut deno_core::JsRuntime) { + let files = vec![( + "deno:op_crates/webgpu/14_webgpu.js", + include_str!("14_webgpu.js"), + )]; + for (url, source_code) in files { + isolate.execute(url, source_code).unwrap(); + } } fn deserialize_features(features: &wgt::Features) -> Vec<&str> { @@ -66,7 +49,7 @@ fn deserialize_features(features: &wgt::Features) -> Vec<&str> { return_features } -pub type WgcInstance = wgc::hub::Global; +type WgcInstance = wgc::hub::Global; pub fn op_webgpu_create_instance( state: &mut OpState, diff --git a/cli/ops/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs similarity index 97% rename from cli/ops/webgpu/pipeline.rs rename to op_crates/webgpu/pipeline.rs index f7349ca908522a..c0237fa1b52730 100644 --- a/cli/ops/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -11,29 +11,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_compute_pipeline", - op_webgpu_create_compute_pipeline, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_compute_pipeline_get_bind_group_layout", - op_webgpu_compute_pipeline_get_bind_group_layout, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_create_render_pipeline", - op_webgpu_create_render_pipeline, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pipeline_get_bind_group_layout", - op_webgpu_render_pipeline_get_bind_group_layout, - ); -} - fn serialize_programmable_stage_descriptor( state: &OpState, programmable_stage_descriptor: GPUProgrammableStageDescriptor, diff --git a/cli/ops/webgpu/queue.rs b/op_crates/webgpu/queue.rs similarity index 92% rename from cli/ops/webgpu/queue.rs rename to op_crates/webgpu/queue.rs index 419f356366b4cc..aaa3863242d647 100644 --- a/cli/ops/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -8,24 +8,6 @@ use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_queue_submit", - op_webgpu_queue_submit, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_write_buffer", - op_webgpu_write_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_write_texture", - op_webgpu_write_texture, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueSubmitArgs { diff --git a/cli/ops/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs similarity index 86% rename from cli/ops/webgpu/render_pass.rs rename to op_crates/webgpu/render_pass.rs index 9fd047265cad08..9d012f41bdf41e 100644 --- a/cli/ops/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -8,94 +8,6 @@ use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_viewport", - op_webgpu_render_pass_set_viewport, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_scissor_rect", - op_webgpu_render_pass_set_scissor_rect, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_blend_color", - op_webgpu_render_pass_set_blend_color, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_stencil_reference", - op_webgpu_render_pass_set_stencil_reference, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_execute_bundles", - op_webgpu_render_pass_execute_bundles, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_end_pass", - op_webgpu_render_pass_end_pass, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_bind_group", - op_webgpu_render_pass_set_bind_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_push_debug_group", - op_webgpu_render_pass_push_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_pop_debug_group", - op_webgpu_render_pass_pop_debug_group, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_insert_debug_marker", - op_webgpu_render_pass_insert_debug_marker, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_pipeline", - op_webgpu_render_pass_set_pipeline, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_index_buffer", - op_webgpu_render_pass_set_index_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_set_vertex_buffer", - op_webgpu_render_pass_set_vertex_buffer, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw", - op_webgpu_render_pass_draw, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indexed", - op_webgpu_render_pass_draw_indexed, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indirect", - op_webgpu_render_pass_draw_indirect, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_render_pass_draw_indexed_indirect", - op_webgpu_render_pass_draw_indexed_indirect, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassSetViewportArgs { diff --git a/cli/ops/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs similarity index 95% rename from cli/ops/webgpu/sampler.rs rename to op_crates/webgpu/sampler.rs index fdf3ccc9063772..b947aea54afd27 100644 --- a/cli/ops/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -9,14 +9,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_sampler", - op_webgpu_create_sampler, - ); -} - fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { match address_mode { Some(address_mode) => match address_mode.as_str() { diff --git a/cli/ops/webgpu/shader.rs b/op_crates/webgpu/shader.rs similarity index 90% rename from cli/ops/webgpu/shader.rs rename to op_crates/webgpu/shader.rs index b274b11f689fdf..01228604d71f15 100644 --- a/cli/ops/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -9,14 +9,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_shader_module", - op_webgpu_create_shader_module, - ); -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateShaderModuleArgs { diff --git a/cli/ops/webgpu/texture.rs b/op_crates/webgpu/texture.rs similarity index 96% rename from cli/ops/webgpu/texture.rs rename to op_crates/webgpu/texture.rs index 84ba0f88d84af4..e41263da459892 100644 --- a/cli/ops/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -9,19 +9,6 @@ use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; use std::borrow::Cow; -pub fn init(rt: &mut deno_core::JsRuntime) { - super::super::reg_json_sync( - rt, - "op_webgpu_create_texture", - op_webgpu_create_texture, - ); - super::super::reg_json_sync( - rt, - "op_webgpu_create_texture_view", - op_webgpu_create_texture_view, - ); -} - pub fn serialize_texture_format( format: String, ) -> Result { From 8bbccbc569c32a834670ab835ee45d16210fa8df Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sat, 6 Feb 2021 01:47:45 +0100 Subject: [PATCH 042/144] change to new resource table --- op_crates/webgpu/14_webgpu.js | 6 +- op_crates/webgpu/binding.rs | 117 ++++++++++------ op_crates/webgpu/buffer.rs | 78 +++++++---- op_crates/webgpu/bundle.rs | 153 +++++++++++---------- op_crates/webgpu/command_encoder.rs | 205 +++++++++++++++++----------- op_crates/webgpu/compute_pass.rs | 93 +++++++------ op_crates/webgpu/lib.rs | 49 +++++-- op_crates/webgpu/pipeline.rs | 95 ++++++++----- op_crates/webgpu/queue.rs | 56 ++++---- op_crates/webgpu/render_pass.rs | 169 ++++++++++++----------- op_crates/webgpu/sampler.rs | 21 ++- op_crates/webgpu/shader.rs | 23 ++-- op_crates/webgpu/texture.rs | 42 ++++-- 13 files changed, 662 insertions(+), 445 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 99f242ed794bb2..5d1ca88b76a2cb 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -411,7 +411,8 @@ } getMappedRange(offset = 0, size = undefined) { - const { buffer, rid } = core.jsonOpSync( + const buffer = new Uint8Array(size ?? this.#mappedSize); + const { rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { instanceRid, @@ -419,10 +420,11 @@ offset, size: size ?? this.#mappedSize, }, + buffer, ); this.#mappedRid = rid; - this.#mappedBuffer = new Uint8Array(buffer); + this.#mappedBuffer = buffer; return this.#mappedBuffer.buffer; } diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index c6de0bf534f0d4..dac5804e1ae1f7 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -5,11 +5,25 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgc::id::BindGroupLayoutId); +impl Resource for WebGPUBindGroupLayout { + fn name(&self) -> Cow { + "webGPUBindGroupLayout".into() + } +} + +pub(crate) struct WebGPUBindGroup(pub(crate) wgc::id::BindGroupId); +impl Resource for WebGPUBindGroup { + fn name(&self) -> Cow { + "webGPUBindGroup".into() + } +} + fn serialize_texture_component_type( component_type: String, ) -> Result { @@ -52,14 +66,16 @@ pub fn op_webgpu_create_bind_group_layout( ) -> Result { let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let mut entries = vec![]; @@ -137,7 +153,7 @@ pub fn op_webgpu_create_bind_group_layout( let rid = state .resource_table - .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + .add(WebGPUBindGroupLayout(bind_group_layout)); Ok(json!({ "rid": rid, @@ -160,25 +176,27 @@ pub fn op_webgpu_create_pipeline_layout( ) -> Result { let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; + let device = device_resource.0; let mut bind_group_layouts = vec![]; for rid in &args.bind_group_layouts { - let id = state + let bind_group_layout = state .resource_table - .get::(*rid) + .get::(*rid) .ok_or_else(bad_resource_id)?; - bind_group_layouts.push(*id); + bind_group_layouts.push(bind_group_layout.0); } - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), @@ -193,7 +211,7 @@ pub fn op_webgpu_create_pipeline_layout( let rid = state .resource_table - .add("webGPUPipelineLayout", Box::new(pipeline_layout)); + .add(super::pipeline::WebGPUPipelineLayout(pipeline_layout)); Ok(json!({ "rid": rid, @@ -227,10 +245,11 @@ pub fn op_webgpu_create_bind_group( ) -> Result { let args: CreateBindGroupArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; + let device = device_resource.0; let mut entries = vec![]; @@ -238,47 +257,57 @@ pub fn op_webgpu_create_bind_group( let e = wgc::binding_model::BindGroupEntry { binding: entry.binding, resource: match entry.kind.as_str() { - "GPUSampler" => wgc::binding_model::BindingResource::Sampler( - *state + "GPUSampler" => { + let sampler_resource = state + .resource_table + .get::(entry.resource) + .ok_or_else(bad_resource_id)?; + wgc::binding_model::BindingResource::Sampler(sampler_resource.0) + } + "GPUTextureView" => { + let texture_view_resource = state .resource_table - .get::(entry.resource) - .ok_or_else(bad_resource_id)?, - ), - "GPUTextureView" => wgc::binding_model::BindingResource::TextureView( - *state + .get::(entry.resource) + .ok_or_else(bad_resource_id)?; + wgc::binding_model::BindingResource::TextureView( + texture_view_resource.0, + ) + } + "GPUBufferBinding" => { + let buffer_resource = state .resource_table - .get::(entry.resource) - .ok_or_else(bad_resource_id)?, - ), - "GPUBufferBinding" => wgc::binding_model::BindingResource::Buffer( - wgc::binding_model::BufferBinding { - buffer_id: *state - .resource_table - .get::(entry.resource) - .ok_or_else(bad_resource_id)?, - offset: entry.offset.unwrap_or(0), - size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), - }, - ), + .get::(entry.resource) + .ok_or_else(bad_resource_id)?; + wgc::binding_model::BindingResource::Buffer( + wgc::binding_model::BufferBinding { + buffer_id: buffer_resource.0, + offset: entry.offset.unwrap_or(0), + size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), + }, + ) + } _ => unreachable!(), }, }; entries.push(e); } + let bind_group_layout = state + .resource_table + .get::(args.layout) + .ok_or_else(bad_resource_id)?; + let descriptor = wgc::binding_model::BindGroupDescriptor { label: args.label.map(Cow::Owned), - layout: *state - .resource_table - .get::(args.layout) - .ok_or_else(bad_resource_id)?, + layout: bind_group_layout.0, entries: Cow::Owned(entries), }; - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( device, @@ -286,9 +315,7 @@ pub fn op_webgpu_create_bind_group( std::marker::PhantomData ))?; - let rid = state - .resource_table - .add("webGPUBindGroup", Box::new(bind_group)); + let rid = state.resource_table.add(WebGPUBindGroup(bind_group)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 883c9d122e094c..54ef8551d9f3ba 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -5,14 +5,28 @@ use deno_core::error::AnyError; use deno_core::futures::channel::oneshot; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +pub(crate) struct WebGPUBuffer(pub(crate) wgc::id::BufferId); +impl Resource for WebGPUBuffer { + fn name(&self) -> Cow { + "webGPUBuffer".into() + } +} + +struct WebGPUBufferMapped(RefCell>); +impl Resource for WebGPUBufferMapped { + fn name(&self) -> Cow { + "webGPUBufferMapped".into() + } +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBufferArgs { @@ -31,14 +45,16 @@ pub fn op_webgpu_create_buffer( ) -> Result { let args: CreateBufferArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::resource::BufferDescriptor { label: args.label.map(Cow::Owned), @@ -52,7 +68,7 @@ pub fn op_webgpu_create_buffer( std::marker::PhantomData ))?; - let rid = state.resource_table.add("webGPUBuffer", Box::new(buffer)); + let rid = state.resource_table.add(WebGPUBuffer(buffer)); Ok(json!({ "rid": rid, @@ -76,15 +92,17 @@ pub async fn op_webgpu_buffer_get_map_async( ) -> Result { let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; - let mut state = state.borrow_mut(); - let buffer = *state + let state = state.borrow_mut(); + let buffer_resource = state .resource_table - .get_mut::(args.buffer_rid) + .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let buffer = buffer_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let (sender, receiver) = oneshot::channel::>(); @@ -136,18 +154,20 @@ struct BufferGetMappedRangeArgs { pub fn op_webgpu_buffer_get_mapped_range( state: &mut OpState, args: Value, - _zero_copy: &mut [ZeroCopyBuf], + zero_copy: &mut [ZeroCopyBuf], ) -> Result { let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; - let buffer = *state + let buffer_resource = state .resource_table - .get::(args.buffer_rid) + .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let buffer = buffer_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -158,17 +178,14 @@ pub fn op_webgpu_buffer_get_mapped_range( let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) }; - - let mut buf: Vec = vec![0; slice.len()]; - buf.copy_from_slice(slice); + zero_copy[0].copy_from_slice(slice); let rid = state .resource_table - .add("webGPUBufferMapped", Box::new(slice)); + .add(WebGPUBufferMapped(RefCell::new(slice.to_vec()))); Ok(json!({ "rid": rid, - "buffer": buf, })) } @@ -187,20 +204,25 @@ pub fn op_webgpu_buffer_unmap( ) -> Result { let args: BufferUnmapArgs = serde_json::from_value(args)?; - let buffer = *state + let buffer_resource = state .resource_table - .get::(args.buffer_rid) + .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; - let mapped = *state + let buffer = buffer_resource.0; + let mapped_resource = state .resource_table - .remove::<&mut [u8]>(args.mapped_rid) + .get::(args.mapped_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; - mapped.copy_from_slice(&*zero_copy[0]); + mapped_resource + .0 + .borrow_mut() + .copy_from_slice(&zero_copy[0]); wgc::gfx_select!(buffer => instance.buffer_unmap(buffer))?; diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 382cdf545558ab..734d2663807302 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -5,10 +5,26 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use std::cell::RefCell; +use std::rc::Rc; + +struct WebGPURenderBundleEncoder(RefCell); +impl Resource for WebGPURenderBundleEncoder { + fn name(&self) -> Cow { + "webGPURenderBundleEncoder".into() + } +} + +pub(crate) struct WebGPURenderBundle(pub(crate) wgc::id::RenderBundleId); +impl Resource for WebGPURenderBundle { + fn name(&self) -> Cow { + "webGPURenderBundle".into() + } +} #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -27,10 +43,11 @@ pub fn op_webgpu_create_render_bundle_encoder( ) -> Result { let args: CreateRenderBundleEncoderArgs = serde_json::from_value(args)?; - let device = state + let device_resource = state .resource_table - .get_mut::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; + let device = device_resource.0; let mut color_formats = vec![]; @@ -48,11 +65,13 @@ pub fn op_webgpu_create_render_bundle_encoder( sample_count: args.sample_count.unwrap_or(1), }; let render_bundle_encoder = - wgc::command::RenderBundleEncoder::new(&descriptor, *device, None)?; + wgc::command::RenderBundleEncoder::new(&descriptor, device, None)?; let rid = state .resource_table - .add("webGPURenderBundleEncoder", Box::new(render_bundle_encoder)); + .add(WebGPURenderBundleEncoder(RefCell::new( + render_bundle_encoder, + ))); Ok(json!({ "rid": rid, @@ -74,14 +93,16 @@ pub fn op_webgpu_render_bundle_encoder_finish( ) -> Result { let args: RenderBundleEncoderFinishArgs = serde_json::from_value(args)?; - let render_bundle_encoder = *state + let render_bundle_encoder_resource = state .resource_table - .remove::(args.render_bundle_encoder_rid) + .take::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let render_bundle_encoder = Rc::try_unwrap(render_bundle_encoder_resource).ok().expect("unwrapping render_bundle_encoder_resource should succeed").0.into_inner(); + let instance_resource = state .resource_table - .get::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, @@ -91,9 +112,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( std::marker::PhantomData ))?; - let rid = state - .resource_table - .add("webGPURenderBundle", Box::new(render_bundle)); + let rid = state.resource_table.add(WebGPURenderBundle(render_bundle)); Ok(json!({ "rid": rid, @@ -118,22 +137,20 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( ) -> Result { let args: RenderBundleEncoderSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_id = *state + let bind_group_resource = state .resource_table - .get::(args.bind_group) + .get::(args.bind_group) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; unsafe { wgc::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), args.index, - bind_group_id, + bind_group_resource.0, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), None => { @@ -165,17 +182,15 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( let args: RenderBundleEncoderPushDebugGroupArgs = serde_json::from_value(args)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::bundle_ffi::wgpu_render_bundle_push_debug_group( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), label.as_ptr(), ); } @@ -197,16 +212,14 @@ pub fn op_webgpu_render_bundle_encoder_pop_debug_group( let args: RenderBundleEncoderPopDebugGroupArgs = serde_json::from_value(args)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; unsafe { wgc::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), ); } @@ -228,17 +241,15 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( let args: RenderBundleEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), label.as_ptr(), ); } @@ -260,20 +271,18 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( ) -> Result { let args: RenderBundleEncoderSetPipelineArgs = serde_json::from_value(args)?; - let pipeline_id = *state + let render_pipeline_resource = state .resource_table - .get::(args.pipeline) + .get::(args.pipeline) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_set_pipeline( - render_bundle_encoder, - pipeline_id, + &mut render_bundle_encoder_resource.0.borrow_mut(), + render_pipeline_resource.0, ); Ok(json!({})) @@ -297,20 +306,18 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( let args: RenderBundleEncoderSetIndexBufferArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.buffer) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_set_index_buffer( - render_bundle_encoder, - buffer_id, + &mut render_bundle_encoder_resource.0.borrow_mut(), + buffer_resource.0, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -336,21 +343,19 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( let args: RenderBundleEncoderSetVertexBufferArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.buffer) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), args.slot, - buffer_id, + buffer_resource.0, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -375,15 +380,13 @@ pub fn op_webgpu_render_bundle_encoder_draw( ) -> Result { let args: RenderBundleEncoderDrawArgs = serde_json::from_value(args)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), args.vertex_count, args.instance_count, args.first_vertex, @@ -411,15 +414,13 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( ) -> Result { let args: RenderBundleEncoderDrawIndexedArgs = serde_json::from_value(args)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw_indexed( - render_bundle_encoder, + &mut render_bundle_encoder_resource.0.borrow_mut(), args.index_count, args.instance_count, args.first_index, @@ -445,20 +446,18 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect( ) -> Result { let args: RenderBundleEncoderDrawIndirectArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.indirect_buffer) + .get::(args.indirect_buffer) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = state + let render_bundle_encoder_resource = state .resource_table - .get_mut::( - args.render_bundle_encoder_rid, - ) + .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; wgc::command::bundle_ffi::wgpu_render_bundle_draw_indirect( - render_bundle_encoder, - buffer_id, + &mut render_bundle_encoder_resource.0.borrow_mut(), + buffer_resource.0, args.indirect_offset, ); diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 71277ef393476e..70ea0ae0be0c81 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -4,10 +4,25 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use std::cell::RefCell; + +pub(crate) struct WebGPUCommandEncoder(pub(crate) wgc::id::CommandEncoderId); +impl Resource for WebGPUCommandEncoder { + fn name(&self) -> Cow { + "webGPUCommandEncoder".into() + } +} + +pub(crate) struct WebGPUCommandBuffer(pub(crate) wgc::id::CommandBufferId); +impl Resource for WebGPUCommandBuffer { + fn name(&self) -> Cow { + "webGPUCommandBuffer".into() + } +} fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { match store_op.as_str() { @@ -33,14 +48,16 @@ pub fn op_webgpu_create_command_encoder( ) -> Result { let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), @@ -53,7 +70,7 @@ pub fn op_webgpu_create_command_encoder( let rid = state .resource_table - .add("webGPUCommandEncoder", Box::new(command_encoder)); + .add(WebGPUCommandEncoder(command_encoder)); Ok(json!({ "rid": rid, @@ -102,29 +119,31 @@ pub fn op_webgpu_command_encoder_begin_render_pass( ) -> Result { let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let mut color_attachments = vec![]; for color_attachment in args.color_attachments { + let texture_view_resource = state + .resource_table + .get::(color_attachment.attachment) + .ok_or_else(bad_resource_id)?; + let attachment = wgc::command::ColorAttachmentDescriptor { - attachment: *state - .resource_table - .get_mut::(color_attachment.attachment) - .ok_or_else(bad_resource_id)?, + attachment: texture_view_resource.0, resolve_target: color_attachment .resolve_target .map(|rid| { state .resource_table - .get_mut::(rid) + .get::(rid) .ok_or_else(bad_resource_id) }) .transpose()? - .map(|texture| *texture), + .map(|texture| texture.0), channel: match color_attachment.load_op.as_str() { "load" => wgc::command::PassChannel { load_op: wgc::command::LoadOp::Load, @@ -160,11 +179,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass( let mut depth_stencil_attachment = None; if let Some(attachment) = args.depth_stencil_attachment { + let texture_view_resource = state + .resource_table + .get::(attachment.attachment) + .ok_or_else(bad_resource_id)?; + let attachment = wgc::command::DepthStencilAttachmentDescriptor { - attachment: *state - .resource_table - .get_mut::(attachment.attachment) - .ok_or_else(bad_resource_id)?, + attachment: texture_view_resource.0, depth: match attachment.depth_load_op.as_str() { "load" => wgc::command::PassChannel { load_op: wgc::command::LoadOp::Load, @@ -201,7 +222,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( } let render_pass = wgc::command::RenderPass::new( - command_encoder, + command_encoder_resource.0, wgc::command::RenderPassDescriptor { color_attachments: Cow::Owned(color_attachments), depth_stencil_attachment: depth_stencil_attachment.as_ref(), @@ -210,7 +231,9 @@ pub fn op_webgpu_command_encoder_begin_render_pass( let rid = state .resource_table - .add("webGPURenderPass", Box::new(render_pass)); + .add(super::render_pass::WebGPURenderPass(RefCell::new( + render_pass, + ))); Ok(json!({ "rid": rid, @@ -231,16 +254,18 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( ) -> Result { let args: CommandEncoderBeginComputePassArgs = serde_json::from_value(args)?; - let command_encoder = state + let command_encoder_resource = state .resource_table - .get_mut::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let compute_pass = wgc::command::ComputePass::new(*command_encoder); + let compute_pass = wgc::command::ComputePass::new(command_encoder_resource.0); let rid = state .resource_table - .add("webGPUComputePass", Box::new(compute_pass)); + .add(super::compute_pass::WebGPUComputePass(RefCell::new( + compute_pass, + ))); Ok(json!({ "rid": rid, @@ -267,28 +292,32 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( let args: CommandEncoderCopyBufferToBufferArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let source = *state + let command_encoder = command_encoder_resource.0; + let source_buffer_resource = state .resource_table - .get::(args.source) + .get::(args.source) .ok_or_else(bad_resource_id)?; - let destination = *state + let source_buffer = source_buffer_resource.0; + let destination_buffer_resource = state .resource_table - .get::(args.destination) + .get::(args.destination) .ok_or_else(bad_resource_id)?; - let instance = state + let destination_buffer = destination_buffer_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, - source, + source_buffer, args.source_offset, - destination, + destination_buffer, args.destination_offset, args.size ))?; @@ -339,25 +368,27 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( let args: CommandEncoderCopyBufferToTextureArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let source_buffer_id = *state + let command_encoder = command_encoder_resource.0; + let source_buffer_resource = state .resource_table - .get::(args.source.buffer) + .get::(args.source.buffer) .ok_or_else(bad_resource_id)?; - let destination_texture_id = *state + let destination_texture_resource = state .resource_table - .get::(args.destination.texture) + .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let source = wgc::command::BufferCopyView { - buffer: source_buffer_id, + buffer: source_buffer_resource.0, layout: wgt::TextureDataLayout { offset: args.source.offset.unwrap_or(0), bytes_per_row: args.source.bytes_per_row.unwrap_or(0), @@ -365,7 +396,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( }, }; let destination = wgc::command::TextureCopyView { - texture: destination_texture_id, + texture: destination_texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination @@ -408,25 +439,27 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( let args: CommandEncoderCopyTextureToBufferArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let source_texture_id = *state + let command_encoder = command_encoder_resource.0; + let source_texture_resource = state .resource_table - .get::(args.source.texture) + .get::(args.source.texture) .ok_or_else(bad_resource_id)?; - let destination_buffer_id = *state + let destination_buffer_resource = state .resource_table - .get::(args.destination.buffer) + .get::(args.destination.buffer) .ok_or_else(bad_resource_id)?; - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let source = wgc::command::TextureCopyView { - texture: source_texture_id, + texture: source_texture_resource.0, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { wgt::Origin3d { @@ -437,7 +470,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( }), }; let destination = wgc::command::BufferCopyView { - buffer: destination_buffer_id, + buffer: destination_buffer_resource.0, layout: wgt::TextureDataLayout { offset: args.destination.offset.unwrap_or(0), bytes_per_row: args.destination.bytes_per_row.unwrap_or(0), @@ -476,25 +509,27 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let source_texture_id = *state + let command_encoder = command_encoder_resource.0; + let source_texture_resource = state .resource_table - .get::(args.source.texture) + .get::(args.source.texture) .ok_or_else(bad_resource_id)?; - let destination_texture_id = *state + let destination_texture_resource = state .resource_table - .get::(args.destination.texture) + .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let source = wgc::command::TextureCopyView { - texture: source_texture_id, + texture: source_texture_resource.0, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { wgt::Origin3d { @@ -505,7 +540,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( }), }; let destination = wgc::command::TextureCopyView { - texture: destination_texture_id, + texture: destination_texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination @@ -545,14 +580,16 @@ pub fn op_webgpu_command_encoder_push_debug_group( ) -> Result { let args: CommandEncoderPushDebugGroupArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let command_encoder = command_encoder_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; wgc::gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -574,14 +611,16 @@ pub fn op_webgpu_command_encoder_pop_debug_group( ) -> Result { let args: CommandEncoderPopDebugGroupArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let command_encoder = command_encoder_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -603,14 +642,16 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( ) -> Result { let args: CommandEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let command_encoder = command_encoder_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -635,14 +676,16 @@ pub fn op_webgpu_command_encoder_finish( ) -> Result { let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let command_encoder = command_encoder_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), @@ -654,7 +697,7 @@ pub fn op_webgpu_command_encoder_finish( let rid = state .resource_table - .add("webGPUCommandBuffer", Box::new(command_buffer)); + .add(WebGPUCommandBuffer(command_buffer)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 9c3b9fe4053703..0cef99803a099e 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -4,9 +4,20 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; +use std::borrow::Cow; +use std::cell::RefCell; + +pub(crate) struct WebGPUComputePass( + pub(crate) RefCell, +); +impl Resource for WebGPUComputePass { + fn name(&self) -> Cow { + "webGPUComputePass".into() + } +} #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -22,18 +33,18 @@ pub fn op_webgpu_compute_pass_set_pipeline( ) -> Result { let args: ComputePassSetPipelineArgs = serde_json::from_value(args)?; - let pipeline_id = *state + let compute_pipeline_resource = state .resource_table - .get_mut::(args.pipeline) + .get::(args.pipeline) .ok_or_else(bad_resource_id)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::compute_ffi::wgpu_compute_pass_set_pipeline( - compute_pass, - pipeline_id, + &mut compute_pass_resource.0.borrow_mut(), + compute_pipeline_resource.0, ); Ok(json!({})) @@ -55,13 +66,13 @@ pub fn op_webgpu_compute_pass_dispatch( ) -> Result { let args: ComputePassDispatchArgs = serde_json::from_value(args)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::compute_ffi::wgpu_compute_pass_dispatch( - compute_pass, + &mut compute_pass_resource.0.borrow_mut(), args.x, args.y, args.z, @@ -85,18 +96,18 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( ) -> Result { let args: ComputePassDispatchIndirectArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get_mut::(args.indirect_buffer) + .get::(args.indirect_buffer) .ok_or_else(bad_resource_id)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( - compute_pass, - buffer_id, + &mut compute_pass_resource.0.borrow_mut(), + buffer_resource.0, args.indirect_offset, ); @@ -118,18 +129,23 @@ pub fn op_webgpu_compute_pass_end_pass( ) -> Result { let args: ComputePassEndPassArgs = serde_json::from_value(args)?; - let instance = state + let instance_resource = state .resource_table - .get::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let command_encoder = *state + let ref instance = instance_resource.0; + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::( + args.command_encoder_rid, + ) .ok_or_else(bad_resource_id)?; - let compute_pass = state + let command_encoder = command_encoder_resource.0; + let compute_pass_resource = state .resource_table - .get::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; + let ref compute_pass = compute_pass_resource.0.borrow(); wgc::gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( command_encoder, @@ -157,21 +173,20 @@ pub fn op_webgpu_compute_pass_set_bind_group( ) -> Result { let args: ComputePassSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_id = *state + let bind_group_resource = state .resource_table - .get::(args.bind_group) + .get::(args.bind_group) .ok_or_else(bad_resource_id)?; - - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { wgc::command::compute_ffi::wgpu_compute_pass_set_bind_group( - compute_pass, + &mut compute_pass_resource.0.borrow_mut(), args.index, - bind_group_id, + bind_group_resource.0, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), None => { @@ -202,15 +217,15 @@ pub fn op_webgpu_compute_pass_push_debug_group( ) -> Result { let args: ComputePassPushDebugGroupArgs = serde_json::from_value(args)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::compute_ffi::wgpu_compute_pass_push_debug_group( - compute_pass, + &mut compute_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 ); @@ -232,12 +247,14 @@ pub fn op_webgpu_compute_pass_pop_debug_group( ) -> Result { let args: ComputePassPopDebugGroupArgs = serde_json::from_value(args)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::compute_ffi::wgpu_compute_pass_pop_debug_group(compute_pass); + wgc::command::compute_ffi::wgpu_compute_pass_pop_debug_group( + &mut compute_pass_resource.0.borrow_mut(), + ); Ok(json!({})) } @@ -256,15 +273,15 @@ pub fn op_webgpu_compute_pass_insert_debug_marker( ) -> Result { let args: ComputePassInsertDebugMarkerArgs = serde_json::from_value(args)?; - let compute_pass = state + let compute_pass_resource = state .resource_table - .get_mut::(args.compute_pass_rid) + .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( - compute_pass, + &mut compute_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 ); diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 50aca05791f48e..85df6a5bea4652 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -18,13 +18,35 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::BufVec; use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; use serde::Deserialize; +use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +struct WebGPUInstance(wgc::hub::Global); +impl Resource for WebGPUInstance { + fn name(&self) -> Cow { + "webGPUInstance".into() + } +} + +struct WebGPUAdapter(wgc::id::AdapterId); +impl Resource for WebGPUAdapter { + fn name(&self) -> Cow { + "webGPUAdapter".into() + } +} + +struct WebGPUDevice(wgc::id::DeviceId); +impl Resource for WebGPUDevice { + fn name(&self) -> Cow { + "webGPUDevice".into() + } +} + /// Execute this crates' JS source files. pub fn init(isolate: &mut deno_core::JsRuntime) { let files = vec![( @@ -49,8 +71,6 @@ fn deserialize_features(features: &wgt::Features) -> Vec<&str> { return_features } -type WgcInstance = wgc::hub::Global; - pub fn op_webgpu_create_instance( state: &mut OpState, _args: Value, @@ -62,9 +82,7 @@ pub fn op_webgpu_create_instance( wgt::BackendBit::PRIMARY, ); - let rid = state - .resource_table - .add("webGPUInstance", Box::new(instance)); + let rid = state.resource_table.add(WebGPUInstance(instance)); Ok(json!({ "rid": rid, @@ -86,10 +104,11 @@ pub async fn op_webgpu_request_adapter( let args: RequestAdapterArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); - let instance = state + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -115,7 +134,7 @@ pub async fn op_webgpu_request_adapter( wgc::gfx_select!(adapter => instance.adapter_features(adapter))?; let features = deserialize_features(&adapter_features); - let rid = state.resource_table.add("webGPUAdapter", Box::new(adapter)); + let rid = state.resource_table.add(WebGPUAdapter(adapter)); Ok(json!({ "rid": rid, @@ -156,14 +175,16 @@ pub async fn op_webgpu_request_device( let args: RequestDeviceArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); - let adapter = *state + let adapter_resource = state .resource_table - .get_mut::(args.adapter_rid) + .get::(args.adapter_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let adapter = adapter_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let mut features = wgt::Features::default(); @@ -233,7 +254,7 @@ pub async fn op_webgpu_request_device( "max_uniform_buffer_binding_size": limits.max_uniform_buffer_binding_size, }); - let rid = state.resource_table.add("webGPUDevice", Box::new(device)); + let rid = state.resource_table.add(WebGPUDevice(device)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index c0237fa1b52730..a35ca525fbbd66 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -6,20 +6,44 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +pub(crate) struct WebGPUPipelineLayout(pub(crate) wgc::id::PipelineLayoutId); +impl Resource for WebGPUPipelineLayout { + fn name(&self) -> Cow { + "webGPUPipelineLayout".into() + } +} + +pub(crate) struct WebGPUComputePipeline(pub(crate) wgc::id::ComputePipelineId); +impl Resource for WebGPUComputePipeline { + fn name(&self) -> Cow { + "webGPUComputePipeline".into() + } +} + +pub(crate) struct WebGPURenderPipeline(pub(crate) wgc::id::RenderPipelineId); +impl Resource for WebGPURenderPipeline { + fn name(&self) -> Cow { + "webGPURenderPipeline".into() + } +} + fn serialize_programmable_stage_descriptor( state: &OpState, programmable_stage_descriptor: GPUProgrammableStageDescriptor, ) -> Result { + let shader_module_resource = state + .resource_table + .get::( + programmable_stage_descriptor.module, + ) + .ok_or_else(bad_resource_id)?; Ok(wgc::pipeline::ProgrammableStageDescriptor { - module: *state - .resource_table - .get::(programmable_stage_descriptor.module) - .ok_or_else(bad_resource_id)?, + module: shader_module_resource.0, entry_point: Cow::Owned(programmable_stage_descriptor.entry_point), }) } @@ -142,22 +166,23 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; - let instance = state + let device_resource = state .resource_table - .get::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - - let device = *state + let device = device_resource.0; + let instance_resource = state .resource_table - .get::(args.device_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; - let layout = if let Some(rid) = args.layout { + let pipeline_layout = if let Some(rid) = args.layout { let id = state .resource_table - .get::(rid) + .get::(rid) .ok_or_else(bad_resource_id)?; - Some(*id) + Some(id.0) } else { None }; @@ -167,7 +192,7 @@ pub fn op_webgpu_create_compute_pipeline( let descriptor = wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(Cow::Owned), - layout, + layout: pipeline_layout, compute_stage, }; let implicit_pipelines = match args.layout { @@ -187,7 +212,7 @@ pub fn op_webgpu_create_compute_pipeline( let rid = state .resource_table - .add("webGPUComputePipeline", Box::new(compute_pipeline)); + .add(WebGPUComputePipeline(compute_pipeline)); Ok(json!({ "rid": rid, @@ -210,21 +235,23 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( let args: ComputePipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; - let compute_pipeline = *state + let compute_pipeline_resource = state .resource_table - .get::(args.compute_pipeline_rid) + .get::(args.compute_pipeline_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let compute_pipeline = compute_pipeline_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; let rid = state .resource_table - .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + .add(super::binding::WebGPUBindGroupLayout(bind_group_layout)); Ok(json!({ "rid": rid, @@ -329,14 +356,16 @@ pub fn op_webgpu_create_render_pipeline( ) -> Result { let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; - let instance = state + let device_resource = state .resource_table - .get::(args.instance_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let device = *state + let device = device_resource.0; + let instance_resource = state .resource_table - .get::(args.device_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let mut color_states = vec![]; @@ -388,9 +417,9 @@ pub fn op_webgpu_create_render_pipeline( let layout = if let Some(rid) = args.layout { let id = state .resource_table - .get::(rid) + .get::(rid) .ok_or_else(bad_resource_id)?; - Some(*id) + Some(id.0) } else { None }; @@ -560,7 +589,7 @@ pub fn op_webgpu_create_render_pipeline( let rid = state .resource_table - .add("webGPURenderPipeline", Box::new(render_pipeline)); + .add(WebGPURenderPipeline(render_pipeline)); Ok(json!({ "rid": rid, @@ -583,21 +612,23 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; - let render_pipeline = *state + let render_pipeline_resource = state .resource_table - .get_mut::(args.render_pipeline_rid) + .get::(args.render_pipeline_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let render_pipeline = render_pipeline_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let bind_group_layout = wgc::gfx_select!(render_pipeline => instance .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; let rid = state .resource_table - .add("webGPUBindGroupLayout", Box::new(bind_group_layout)); + .add(super::binding::WebGPUBindGroupLayout(bind_group_layout)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index aaa3863242d647..c1ef79a167dbe8 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -8,6 +8,8 @@ use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; +type WebGPUQueue = super::WebGPUDevice; + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueSubmitArgs { @@ -23,26 +25,27 @@ pub fn op_webgpu_queue_submit( ) -> Result { let args: QueueSubmitArgs = serde_json::from_value(args)?; - let queue = *state + let queue_resource = state + .resource_table + .get::(args.queue_rid) + .ok_or_else(bad_resource_id)?; + let queue = queue_resource.0; + let instance_resource = state .resource_table - .get::(args.queue_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let mut ids = vec![]; - for rid in &args.command_buffers { - let buffer_id = state + for rid in args.command_buffers { + let buffer_resource = state .resource_table - .get::(*rid) + .get::(rid) .ok_or_else(bad_resource_id)?; - ids.push(*buffer_id); + ids.push(buffer_resource.0); } - let instance = state - .resource_table - .get_mut::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - wgc::gfx_select!(queue => instance.queue_submit(queue, &ids))?; Ok(json!({})) @@ -74,18 +77,21 @@ pub fn op_webgpu_write_buffer( ) -> Result { let args: QueueWriteBufferArgs = serde_json::from_value(args)?; - let queue = *state + let buffer_resource = state .resource_table - .get::(args.queue_rid) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - let buffer = *state + let buffer = buffer_resource.0; + let queue_resource = state .resource_table - .get::(args.buffer) + .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let queue = queue_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -118,21 +124,23 @@ pub fn op_webgpu_write_texture( ) -> Result { let args: QueueWriteTextureArgs = serde_json::from_value(args)?; - let texture = *state + let texture_resource = state .resource_table - .get::(args.destination.texture) + .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let queue = *state + let queue_resource = state .resource_table - .get::(args.queue_rid) + .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let queue = queue_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let destination = wgc::command::TextureCopyView { - texture, + texture: texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 9d012f41bdf41e..c89a46e0142944 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -4,9 +4,20 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; +use std::borrow::Cow; +use std::cell::RefCell; + +pub(crate) struct WebGPURenderPass( + pub(crate) RefCell, +); +impl Resource for WebGPURenderPass { + fn name(&self) -> Cow { + "webGPURenderPass".into() + } +} #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -27,13 +38,13 @@ pub fn op_webgpu_render_pass_set_viewport( ) -> Result { let args: RenderPassSetViewportArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_viewport( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.x, args.y, args.width, @@ -62,13 +73,13 @@ pub fn op_webgpu_render_pass_set_scissor_rect( ) -> Result { let args: RenderPassSetScissorRectArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_scissor_rect( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.x, args.y, args.width, @@ -101,13 +112,13 @@ pub fn op_webgpu_render_pass_set_blend_color( ) -> Result { let args: RenderPassSetBlendColorArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_blend_color( - render_pass, + &mut render_pass_resource.0.borrow_mut(), &wgt::Color { r: args.color.r, g: args.color.g, @@ -133,13 +144,13 @@ pub fn op_webgpu_render_pass_set_stencil_reference( ) -> Result { let args: RenderPassSetStencilReferenceArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_stencil_reference( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.reference, ); @@ -163,21 +174,21 @@ pub fn op_webgpu_render_pass_execute_bundles( let mut render_bundle_ids = vec![]; for rid in &args.bundles { - let bundle_id = state + let render_bundle_resource = state .resource_table - .get::(*rid) + .get::(*rid) .ok_or_else(bad_resource_id)?; - render_bundle_ids.push(*bundle_id); + render_bundle_ids.push(render_bundle_resource.0); } - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { wgc::command::render_ffi::wgpu_render_pass_execute_bundles( - render_pass, + &mut render_pass_resource.0.borrow_mut(), render_bundle_ids.as_ptr(), args.bundles.len(), ); @@ -201,19 +212,21 @@ pub fn op_webgpu_render_pass_end_pass( ) -> Result { let args: RenderPassEndPassArgs = serde_json::from_value(args)?; - let command_encoder = *state + let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let command_encoder = command_encoder_resource.0; + let instance_resource = state .resource_table - .get::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let render_pass = state + let ref instance = instance_resource.0; + let render_pass_resource = state .resource_table - .get::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - + let ref render_pass = render_pass_resource.0.borrow(); wgc::gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; Ok(json!({})) @@ -237,20 +250,20 @@ pub fn op_webgpu_render_pass_set_bind_group( ) -> Result { let args: RenderPassSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_id = *state + let bind_group_resource = state .resource_table - .get::(args.bind_group) + .get::(args.bind_group) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { wgc::command::render_ffi::wgpu_render_pass_set_bind_group( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.index, - bind_group_id, + bind_group_resource.0, match args.dynamic_offsets_data { Some(data) => data.as_ptr(), None => { @@ -281,15 +294,15 @@ pub fn op_webgpu_render_pass_push_debug_group( ) -> Result { let args: RenderPassPushDebugGroupArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); wgc::command::render_ffi::wgpu_render_pass_push_debug_group( - render_pass, + &mut render_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 ); @@ -311,12 +324,14 @@ pub fn op_webgpu_render_pass_pop_debug_group( ) -> Result { let args: RenderPassPopDebugGroupArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_pop_debug_group(render_pass); + wgc::command::render_ffi::wgpu_render_pass_pop_debug_group( + &mut render_pass_resource.0.borrow_mut(), + ); Ok(json!({})) } @@ -335,15 +350,15 @@ pub fn op_webgpu_render_pass_insert_debug_marker( ) -> Result { let args: RenderPassInsertDebugMarkerArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); wgc::command::render_ffi::wgpu_render_pass_insert_debug_marker( - render_pass, + &mut render_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 ); @@ -366,18 +381,18 @@ pub fn op_webgpu_render_pass_set_pipeline( ) -> Result { let args: RenderPassSetPipelineArgs = serde_json::from_value(args)?; - let pipeline_id = *state + let render_pipeline_resource = state .resource_table - .get::(args.pipeline) + .get::(args.pipeline) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_pipeline( - render_pass, - pipeline_id, + &mut render_pass_resource.0.borrow_mut(), + render_pipeline_resource.0, ); Ok(json!({})) @@ -400,18 +415,18 @@ pub fn op_webgpu_render_pass_set_index_buffer( ) -> Result { let args: RenderPassSetIndexBufferArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.buffer) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_index_buffer( - render_pass, - buffer_id, + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.0, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -436,19 +451,19 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( ) -> Result { let args: RenderPassSetVertexBufferArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.buffer) + .get::(args.buffer) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_set_vertex_buffer( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.slot, - buffer_id, + buffer_resource.0, args.offset, std::num::NonZeroU64::new(args.size), ); @@ -473,13 +488,13 @@ pub fn op_webgpu_render_pass_draw( ) -> Result { let args: RenderPassDrawArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_draw( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.vertex_count, args.instance_count, args.first_vertex, @@ -507,13 +522,13 @@ pub fn op_webgpu_render_pass_draw_indexed( ) -> Result { let args: RenderPassDrawIndexedArgs = serde_json::from_value(args)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_draw_indexed( - render_pass, + &mut render_pass_resource.0.borrow_mut(), args.index_count, args.instance_count, args.first_index, @@ -539,18 +554,18 @@ pub fn op_webgpu_render_pass_draw_indirect( ) -> Result { let args: RenderPassDrawIndirectArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.indirect_buffer) + .get::(args.indirect_buffer) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_draw_indirect( - render_pass, - buffer_id, + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.0, args.indirect_offset, ); @@ -572,18 +587,18 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect( ) -> Result { let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; - let buffer_id = *state + let buffer_resource = state .resource_table - .get::(args.indirect_buffer) + .get::(args.indirect_buffer) .ok_or_else(bad_resource_id)?; - let render_pass = state + let render_pass_resource = state .resource_table - .get_mut::(args.render_pass_rid) + .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; wgc::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( - render_pass, - buffer_id, + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.0, args.indirect_offset, ); diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index b947aea54afd27..ccec042171b92b 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -4,11 +4,18 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +pub(crate) struct WebGPUSampler(pub(crate) wgc::id::SamplerId); +impl Resource for WebGPUSampler { + fn name(&self) -> Cow { + "webGPUSampler".into() + } +} + fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { match address_mode { Some(address_mode) => match address_mode.as_str() { @@ -71,14 +78,16 @@ pub fn op_webgpu_create_sampler( ) -> Result { let args: CreateSamplerArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), @@ -108,7 +117,7 @@ pub fn op_webgpu_create_sampler( std::marker::PhantomData ))?; - let rid = state.resource_table.add("webGPUTexture", Box::new(sampler)); + let rid = state.resource_table.add(WebGPUSampler(sampler)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 01228604d71f15..76e86ceb1a435e 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -4,11 +4,18 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +pub(crate) struct WebGPUShaderModule(pub(crate) wgc::id::ShaderModuleId); +impl Resource for WebGPUShaderModule { + fn name(&self) -> Cow { + "webGPUShaderModule".into() + } +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateShaderModuleArgs { @@ -26,14 +33,16 @@ pub fn op_webgpu_create_shader_module( ) -> Result { let args: CreateShaderModuleArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let source = match args.code { Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), @@ -50,9 +59,7 @@ pub fn op_webgpu_create_shader_module( std::marker::PhantomData ))?; - let rid = state - .resource_table - .add("webGPUShaderModule", Box::new(shader_module)); + let rid = state.resource_table.add(WebGPUShaderModule(shader_module)); Ok(json!({ "rid": rid, diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index e41263da459892..4d832a216cd2a4 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -4,11 +4,25 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +pub(crate) struct WebGPUTexture(pub(crate) wgc::id::TextureId); +impl Resource for WebGPUTexture { + fn name(&self) -> Cow { + "webGPUTexture".into() + } +} + +pub(crate) struct WebGPUTextureView(pub(crate) wgc::id::TextureViewId); +impl Resource for WebGPUTextureView { + fn name(&self) -> Cow { + "webGPUTextureView".into() + } +} + pub fn serialize_texture_format( format: String, ) -> Result { @@ -134,14 +148,16 @@ pub fn op_webgpu_create_texture( ) -> Result { let args: CreateTextureArgs = serde_json::from_value(args)?; - let device = *state + let device_resource = state .resource_table - .get::(args.device_rid) + .get::(args.device_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let device = device_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), @@ -171,7 +187,7 @@ pub fn op_webgpu_create_texture( std::marker::PhantomData ))?; - let rid = state.resource_table.add("webGPUTexture", Box::new(texture)); + let rid = state.resource_table.add(WebGPUTexture(texture)); Ok(json!({ "rid": rid, @@ -200,14 +216,16 @@ pub fn op_webgpu_create_texture_view( ) -> Result { let args: CreateTextureViewArgs = serde_json::from_value(args)?; - let texture = *state + let texture_resource = state .resource_table - .get_mut::(args.texture_rid) + .get::(args.texture_rid) .ok_or_else(bad_resource_id)?; - let instance = state + let texture = texture_resource.0; + let instance_resource = state .resource_table - .get_mut::(args.instance_rid) + .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; + let ref instance = instance_resource.0; let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), @@ -235,9 +253,7 @@ pub fn op_webgpu_create_texture_view( std::marker::PhantomData ))?; - let rid = state - .resource_table - .add("webGPUTextureView", Box::new(texture_view)); + let rid = state.resource_table.add(WebGPUTextureView(texture_view)); Ok(json!({ "rid": rid, From d875d852b9ddd370b31c7e7afb2a2f654038398d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:15:11 +0100 Subject: [PATCH 043/144] fix lint --- op_crates/webgpu/14_webgpu.js | 6 +++--- op_crates/webgpu/binding.rs | 15 ++++++++------- op_crates/webgpu/buffer.rs | 28 +++++++++++++++------------- op_crates/webgpu/bundle.rs | 17 +++++++++++------ op_crates/webgpu/command_encoder.rs | 24 ++++++++++++------------ op_crates/webgpu/compute_pass.rs | 10 +++++----- op_crates/webgpu/lib.rs | 28 ++++++++++++++-------------- op_crates/webgpu/pipeline.rs | 19 ++++++++++--------- op_crates/webgpu/queue.rs | 12 ++++++------ op_crates/webgpu/render_pass.rs | 14 ++++++++------ op_crates/webgpu/sampler.rs | 8 ++++---- op_crates/webgpu/shader.rs | 8 ++++---- op_crates/webgpu/texture.rs | 10 +++++----- 13 files changed, 105 insertions(+), 94 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 5d1ca88b76a2cb..1a0c801a73d7c0 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -97,7 +97,7 @@ } } - // TODO: https://gpuweb.github.io/gpuweb/#errors-and-debugging + // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging class GPUDevice extends EventTarget { #rid; #adapter; @@ -533,7 +533,7 @@ }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO: label? + const bindGroupLayout = new GPUBindGroupLayout(); // TODO(@crowlKats): label? GPUBindGroupLayoutMap.set(bindGroupLayout, rid); return bindGroupLayout; } @@ -558,7 +558,7 @@ }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO: label? + const bindGroupLayout = new GPUBindGroupLayout(); // TODO(@crowlKats): label? GPUBindGroupLayoutMap.set(bindGroupLayout, rid); return bindGroupLayout; } diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index dac5804e1ae1f7..3f5a6e8fba6516 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -1,15 +1,16 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use super::texture::{serialize_dimension, serialize_texture_format}; -use deno_core::error::AnyError; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::texture::{serialize_dimension, serialize_texture_format}; + pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgc::id::BindGroupLayoutId); impl Resource for WebGPUBindGroupLayout { fn name(&self) -> Cow { @@ -75,7 +76,7 @@ pub fn op_webgpu_create_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let mut entries = vec![]; @@ -196,7 +197,7 @@ pub fn op_webgpu_create_pipeline_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), @@ -307,7 +308,7 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( device, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 54ef8551d9f3ba..9bb8281a98a386 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -1,17 +1,19 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use std::borrow::Cow; +use std::cell::RefCell; +use std::rc::Rc; + +use serde::Deserialize; + +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::futures::channel::oneshot; +use deno_core::OpState; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{BufVec, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; pub(crate) struct WebGPUBuffer(pub(crate) wgc::id::BufferId); impl Resource for WebGPUBuffer { @@ -54,7 +56,7 @@ pub fn op_webgpu_create_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::resource::BufferDescriptor { label: args.label.map(Cow::Owned), @@ -92,7 +94,7 @@ pub async fn op_webgpu_buffer_get_map_async( ) -> Result { let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; - let state = state.borrow_mut(); + let state = state.borrow(); let buffer_resource = state .resource_table .get::(args.buffer_rid) @@ -102,7 +104,7 @@ pub async fn op_webgpu_buffer_get_map_async( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let (sender, receiver) = oneshot::channel::>(); @@ -167,7 +169,7 @@ pub fn op_webgpu_buffer_get_mapped_range( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -217,7 +219,7 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; mapped_resource .0 diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 734d2663807302..c884a6ecef5277 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -1,17 +1,18 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use super::texture::serialize_texture_format; -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +use super::texture::serialize_texture_format; + struct WebGPURenderBundleEncoder(RefCell); impl Resource for WebGPURenderBundleEncoder { fn name(&self) -> Cow { @@ -97,12 +98,16 @@ pub fn op_webgpu_render_bundle_encoder_finish( .resource_table .take::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = Rc::try_unwrap(render_bundle_encoder_resource).ok().expect("unwrapping render_bundle_encoder_resource should succeed").0.into_inner(); + let render_bundle_encoder = Rc::try_unwrap(render_bundle_encoder_resource) + .ok() + .expect("unwrapping render_bundle_encoder_resource should succeed") + .0 + .into_inner(); let instance_resource = state .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 70ea0ae0be0c81..cf3b75d14607e8 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -57,7 +57,7 @@ pub fn op_webgpu_create_command_encoder( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), @@ -311,7 +311,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, @@ -385,7 +385,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let source = wgc::command::BufferCopyView { buffer: source_buffer_resource.0, @@ -456,7 +456,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -526,7 +526,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -589,7 +589,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -620,7 +620,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -651,7 +651,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -685,7 +685,7 @@ pub fn op_webgpu_command_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 0cef99803a099e..6933f605e69830 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -133,7 +133,7 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let command_encoder_resource = state .resource_table .get::( @@ -145,7 +145,7 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - let ref compute_pass = compute_pass_resource.0.borrow(); + let compute_pass = &compute_pass_resource.0.borrow(); wgc::gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( command_encoder, diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 85df6a5bea4652..733fad884c02b5 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -2,6 +2,18 @@ #![deny(warnings)] +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; +use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; +use deno_core::OpState; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use serde::Deserialize; +use std::borrow::Cow; +use std::cell::RefCell; +use std::rc::Rc; + pub mod binding; pub mod buffer; pub mod bundle; @@ -14,18 +26,6 @@ pub mod sampler; pub mod shader; pub mod texture; -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::serde_json::json; -use deno_core::serde_json::Value; -use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{BufVec, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; - struct WebGPUInstance(wgc::hub::Global); impl Resource for WebGPUInstance { fn name(&self) -> Cow { @@ -108,7 +108,7 @@ pub async fn op_webgpu_request_adapter( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -184,7 +184,7 @@ pub async fn op_webgpu_request_device( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let mut features = wgt::Features::default(); diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index a35ca525fbbd66..2ba192835dff24 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -1,16 +1,17 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use super::sampler::serialize_compare_function; -use super::texture::serialize_texture_format; -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::sampler::serialize_compare_function; +use super::texture::serialize_texture_format; + pub(crate) struct WebGPUPipelineLayout(pub(crate) wgc::id::PipelineLayoutId); impl Resource for WebGPUPipelineLayout { fn name(&self) -> Cow { @@ -175,7 +176,7 @@ pub fn op_webgpu_create_compute_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let pipeline_layout = if let Some(rid) = args.layout { let id = state @@ -244,7 +245,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; @@ -365,7 +366,7 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let mut color_states = vec![]; @@ -621,7 +622,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let bind_group_layout = wgc::gfx_select!(render_pipeline => instance .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index c1ef79a167dbe8..12c527557e645c 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; +use deno_core::OpState; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; type WebGPUQueue = super::WebGPUDevice; @@ -34,7 +34,7 @@ pub fn op_webgpu_queue_submit( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let mut ids = vec![]; @@ -91,7 +91,7 @@ pub fn op_webgpu_write_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -137,7 +137,7 @@ pub fn op_webgpu_write_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let destination = wgc::command::TextureCopyView { texture: texture_resource.0, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index c89a46e0142944..3a7b0029767774 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -214,19 +214,21 @@ pub fn op_webgpu_render_pass_end_pass( let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .get::( + args.command_encoder_rid, + ) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; let instance_resource = state .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let render_pass_resource = state .resource_table .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - let ref render_pass = render_pass_resource.0.borrow(); + let render_pass = &render_pass_resource.0.borrow(); wgc::gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; Ok(json!({})) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index ccec042171b92b..dc90168f58ce53 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -87,7 +87,7 @@ pub fn op_webgpu_create_sampler( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 76e86ceb1a435e..93dd0c343c4158 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::bad_resource_id; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::AnyError; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -42,7 +42,7 @@ pub fn op_webgpu_create_shader_module( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let source = match args.code { Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 4d832a216cd2a4..e45791c4854e40 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; +use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; -use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -157,7 +157,7 @@ pub fn op_webgpu_create_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), @@ -225,7 +225,7 @@ pub fn op_webgpu_create_texture_view( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let ref instance = instance_resource.0; + let instance = &instance_resource.0; let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), From 0f5a904ea5668c15b30b00cd1ce3be4da962ebf0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:28:19 +0100 Subject: [PATCH 044/144] stuff --- op_crates/webgpu/binding.rs | 8 ++++---- op_crates/webgpu/buffer.rs | 10 +++++----- op_crates/webgpu/bundle.rs | 4 ++-- op_crates/webgpu/command_encoder.rs | 20 ++++++++++---------- op_crates/webgpu/compute_pass.rs | 4 ++-- op_crates/webgpu/lib.rs | 10 +++++----- op_crates/webgpu/pipeline.rs | 10 +++++----- op_crates/webgpu/queue.rs | 8 ++++---- op_crates/webgpu/render_pass.rs | 4 ++-- op_crates/webgpu/sampler.rs | 4 ++-- op_crates/webgpu/shader.rs | 4 ++-- op_crates/webgpu/texture.rs | 6 +++--- 12 files changed, 46 insertions(+), 46 deletions(-) diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index 3f5a6e8fba6516..9759d7fa43ba46 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::error::AnyError; @@ -76,7 +76,7 @@ pub fn op_webgpu_create_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let mut entries = vec![]; @@ -197,7 +197,7 @@ pub fn op_webgpu_create_pipeline_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), @@ -308,7 +308,7 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( device, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 9bb8281a98a386..5117d6c8e3e582 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use serde::Deserialize; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{BufVec, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -56,7 +56,7 @@ pub fn op_webgpu_create_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgc::resource::BufferDescriptor { label: args.label.map(Cow::Owned), @@ -104,7 +104,7 @@ pub async fn op_webgpu_buffer_get_map_async( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = &RcRef::map(&instance_resource, |r| &r.0).borrow().await; let (sender, receiver) = oneshot::channel::>(); @@ -169,7 +169,7 @@ pub fn op_webgpu_buffer_get_mapped_range( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -219,7 +219,7 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); mapped_resource .0 diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index c884a6ecef5277..7473f3282af7f1 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -107,7 +107,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index cf3b75d14607e8..dce002555d5a51 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -57,7 +57,7 @@ pub fn op_webgpu_create_command_encoder( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), @@ -311,7 +311,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, @@ -385,7 +385,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let source = wgc::command::BufferCopyView { buffer: source_buffer_resource.0, @@ -456,7 +456,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -526,7 +526,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -589,7 +589,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); wgc::gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -620,7 +620,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -651,7 +651,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -685,7 +685,7 @@ pub fn op_webgpu_command_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 6933f605e69830..fab9335c70f45b 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -133,7 +133,7 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let command_encoder_resource = state .resource_table .get::( diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 733fad884c02b5..ebcdbeef99ff20 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -2,7 +2,7 @@ #![deny(warnings)] -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, AsyncRefCell, RcRef}; use deno_core::{BufVec, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -26,7 +26,7 @@ pub mod sampler; pub mod shader; pub mod texture; -struct WebGPUInstance(wgc::hub::Global); +struct WebGPUInstance(AsyncRefCell>); impl Resource for WebGPUInstance { fn name(&self) -> Cow { "webGPUInstance".into() @@ -82,7 +82,7 @@ pub fn op_webgpu_create_instance( wgt::BackendBit::PRIMARY, ); - let rid = state.resource_table.add(WebGPUInstance(instance)); + let rid = state.resource_table.add(WebGPUInstance(AsyncRefCell::new(instance))); Ok(json!({ "rid": rid, @@ -108,7 +108,7 @@ pub async fn op_webgpu_request_adapter( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = &RcRef::map(&instance_resource, |r| &r.0).borrow().await; let descriptor = wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -184,7 +184,7 @@ pub async fn op_webgpu_request_device( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let mut features = wgt::Features::default(); diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 2ba192835dff24..6dcfe8eb28ae2a 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -176,7 +176,7 @@ pub fn op_webgpu_create_compute_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let pipeline_layout = if let Some(rid) = args.layout { let id = state @@ -245,7 +245,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; @@ -366,7 +366,7 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let mut color_states = vec![]; @@ -622,7 +622,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let bind_group_layout = wgc::gfx_select!(render_pipeline => instance .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index 12c527557e645c..555098b52bd831 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; use deno_core::OpState; @@ -34,7 +34,7 @@ pub fn op_webgpu_queue_submit( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let mut ids = vec![]; @@ -91,7 +91,7 @@ pub fn op_webgpu_write_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -137,7 +137,7 @@ pub fn op_webgpu_write_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let destination = wgc::command::TextureCopyView { texture: texture_resource.0, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 3a7b0029767774..cd62882e8dfee2 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -223,7 +223,7 @@ pub fn op_webgpu_render_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let render_pass_resource = state .resource_table .get::(args.render_pass_rid) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index dc90168f58ce53..539ac4416ee3ad 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -87,7 +87,7 @@ pub fn op_webgpu_create_sampler( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgc::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 93dd0c343c4158..1f63f7e2037d6b 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::AnyError; use deno_core::error::bad_resource_id; @@ -42,7 +42,7 @@ pub fn op_webgpu_create_shader_module( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let source = match args.code { Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index e45791c4854e40..8f1af02024ab59 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf, RcRef}; use deno_core::{OpState, Resource}; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::error::AnyError; @@ -157,7 +157,7 @@ pub fn op_webgpu_create_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), @@ -225,7 +225,7 @@ pub fn op_webgpu_create_texture_view( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), From 12b28705112f86264c60d654748f801bd5f7d33d Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 8 Feb 2021 17:38:02 +0100 Subject: [PATCH 045/144] dont hold refcell over await point --- op_crates/webgpu/buffer.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 5117d6c8e3e582..99493009009f68 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -94,17 +94,21 @@ pub async fn op_webgpu_buffer_get_map_async( ) -> Result { let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; - let state = state.borrow(); - let buffer_resource = state - .resource_table - .get::(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &RcRef::map(&instance_resource, |r| &r.0).borrow().await; + let buffer; + let instance; + { + let state = state.borrow(); + let buffer_resource = state + .resource_table + .get::(args.buffer_rid) + .ok_or_else(bad_resource_id)?; + buffer = buffer_resource.0; + let instance_resource = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + instance = RcRef::map(&instance_resource, |r| &r.0).borrow().await; + } let (sender, receiver) = oneshot::channel::>(); From 536fe2b1549902a7f623ae26417e0f987865a35b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 8 Feb 2021 17:38:53 +0100 Subject: [PATCH 046/144] fmt --- op_crates/webgpu/binding.rs | 18 ++++++++----- op_crates/webgpu/buffer.rs | 20 +++++++++----- op_crates/webgpu/bundle.rs | 10 ++++--- op_crates/webgpu/command_encoder.rs | 42 ++++++++++++++++++++--------- op_crates/webgpu/compute_pass.rs | 10 ++++--- op_crates/webgpu/lib.rs | 20 +++++++++----- op_crates/webgpu/pipeline.rs | 22 ++++++++++----- op_crates/webgpu/queue.rs | 18 ++++++++----- op_crates/webgpu/render_pass.rs | 10 ++++--- op_crates/webgpu/sampler.rs | 10 ++++--- op_crates/webgpu/shader.rs | 10 ++++--- op_crates/webgpu/texture.rs | 14 ++++++---- 12 files changed, 134 insertions(+), 70 deletions(-) diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index 9759d7fa43ba46..a0936e9f700702 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::{bad_resource_id, not_supported}; use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -76,7 +76,9 @@ pub fn op_webgpu_create_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let mut entries = vec![]; @@ -197,7 +199,9 @@ pub fn op_webgpu_create_pipeline_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), @@ -308,7 +312,9 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( device, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 99493009009f68..2562136b90d0e8 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -6,14 +6,14 @@ use std::rc::Rc; use serde::Deserialize; -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{BufVec, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::futures::channel::oneshot; -use deno_core::OpState; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::OpState; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; pub(crate) struct WebGPUBuffer(pub(crate) wgc::id::BufferId); impl Resource for WebGPUBuffer { @@ -56,7 +56,9 @@ pub fn op_webgpu_create_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgc::resource::BufferDescriptor { label: args.label.map(Cow::Owned), @@ -173,7 +175,9 @@ pub fn op_webgpu_buffer_get_mapped_range( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -223,7 +227,9 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); mapped_resource .0 diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 7473f3282af7f1..3483446a4b9780 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -107,7 +107,9 @@ pub fn op_webgpu_render_bundle_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index dce002555d5a51..94d3256c55b4cb 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -57,7 +57,9 @@ pub fn op_webgpu_create_command_encoder( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), @@ -311,7 +313,9 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, @@ -385,7 +389,9 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let source = wgc::command::BufferCopyView { buffer: source_buffer_resource.0, @@ -456,7 +462,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -526,7 +534,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -589,7 +599,9 @@ pub fn op_webgpu_command_encoder_push_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); wgc::gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -620,7 +632,9 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -651,7 +665,9 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -685,7 +701,9 @@ pub fn op_webgpu_command_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index fab9335c70f45b..97d414e4f541ca 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -133,7 +133,9 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let command_encoder_resource = state .resource_table .get::( diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index ebcdbeef99ff20..903a0e2952858c 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -2,13 +2,13 @@ #![deny(warnings)] -use deno_core::{serde_json, ZeroCopyBuf, AsyncRefCell, RcRef}; -use deno_core::{BufVec, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; -use deno_core::OpState; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::OpState; +use deno_core::{serde_json, AsyncRefCell, RcRef, ZeroCopyBuf}; +use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -26,7 +26,9 @@ pub mod sampler; pub mod shader; pub mod texture; -struct WebGPUInstance(AsyncRefCell>); +struct WebGPUInstance( + AsyncRefCell>, +); impl Resource for WebGPUInstance { fn name(&self) -> Cow { "webGPUInstance".into() @@ -82,7 +84,9 @@ pub fn op_webgpu_create_instance( wgt::BackendBit::PRIMARY, ); - let rid = state.resource_table.add(WebGPUInstance(AsyncRefCell::new(instance))); + let rid = state + .resource_table + .add(WebGPUInstance(AsyncRefCell::new(instance))); Ok(json!({ "rid": rid, @@ -184,7 +188,9 @@ pub async fn op_webgpu_request_device( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let mut features = wgt::Features::default(); diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 6dcfe8eb28ae2a..1db13c3722edfd 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -176,7 +176,9 @@ pub fn op_webgpu_create_compute_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let pipeline_layout = if let Some(rid) = args.layout { let id = state @@ -245,7 +247,9 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; @@ -366,7 +370,9 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let mut color_states = vec![]; @@ -622,7 +628,9 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let bind_group_layout = wgc::gfx_select!(render_pipeline => instance .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index 555098b52bd831..b8999b6497ed5c 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; -use deno_core::OpState; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::OpState; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; use serde::Deserialize; type WebGPUQueue = super::WebGPUDevice; @@ -34,7 +34,9 @@ pub fn op_webgpu_queue_submit( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let mut ids = vec![]; @@ -91,7 +93,9 @@ pub fn op_webgpu_write_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -137,7 +141,9 @@ pub fn op_webgpu_write_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let destination = wgc::command::TextureCopyView { texture: texture_resource.0, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index cd62882e8dfee2..24bde39b38aab4 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -223,7 +223,9 @@ pub fn op_webgpu_render_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let render_pass_resource = state .resource_table .get::(args.render_pass_rid) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 539ac4416ee3ad..051ddab5f72955 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -87,7 +87,9 @@ pub fn op_webgpu_create_sampler( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgc::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 1f63f7e2037d6b..9440be2ca3a482 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -42,7 +42,9 @@ pub fn op_webgpu_create_shader_module( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let source = match args.code { Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 8f1af02024ab59..22f3f2d69b646a 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -1,11 +1,11 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use deno_core::{serde_json, ZeroCopyBuf, RcRef}; -use deno_core::{OpState, Resource}; -use deno_core::error::{bad_resource_id, not_supported}; use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -157,7 +157,9 @@ pub fn op_webgpu_create_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), @@ -225,7 +227,9 @@ pub fn op_webgpu_create_texture_view( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0).try_borrow().unwrap(); + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), From c34bf29dc951158a00885c6250aa22d8819b1f9c Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 8 Feb 2021 19:57:12 +0100 Subject: [PATCH 047/144] poll device during buffer_map_async --- Cargo.lock | 1 + op_crates/webgpu/14_webgpu.js | 6 ++++- op_crates/webgpu/Cargo.toml | 1 + op_crates/webgpu/buffer.rs | 41 ++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 103a6924419628..32db42a4dcdefc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -685,6 +685,7 @@ version = "0.1.0" dependencies = [ "deno_core", "serde", + "tokio", "wgpu-core", "wgpu-types", ] diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 1a0c801a73d7c0..16bfec5accf03c 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -137,6 +137,7 @@ const buffer = new GPUBuffer( rid, + this.#rid, descriptor.label, descriptor.size, descriptor.mappedAtCreation, @@ -381,14 +382,16 @@ const GPUBufferMap = new WeakMap(); class GPUBuffer { #rid; + #deviceRid; #size; #mappedSize; #mappedOffset; #mappedRid; #mappedBuffer; - constructor(rid, label, size, mappedAtCreation) { + constructor(rid, deviceRid, label, size, mappedAtCreation) { this.#rid = rid; + this.#deviceRid = deviceRid; this.label = label ?? null; this.#size = size; @@ -404,6 +407,7 @@ await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { instanceRid, bufferRid: this.#rid, + deviceRid: this.#deviceRid, mode, offset, size: this.#mappedSize, diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index 5769a98960e3a2..49c232308bdd94 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.77.1", path = "../../core" } +tokio = { version = "1.1.1", features = ["full"] } serde = { version = "1.0.121", features = ["derive"] } wgc = { package = "wgpu-core", version = "0.6.5" } wgt = { package = "wgpu-types", version = "0.6.1" } diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 2562136b90d0e8..69b7edb0b2c4b3 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +use std::time::Duration; use serde::Deserialize; @@ -84,6 +85,7 @@ pub fn op_webgpu_create_buffer( struct BufferGetMapAsyncArgs { instance_rid: u32, buffer_rid: u32, + device_rid: u32, mode: u32, offset: u64, size: u64, @@ -97,6 +99,7 @@ pub async fn op_webgpu_buffer_get_map_async( let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; let buffer; + let device; let instance; { let state = state.borrow(); @@ -105,6 +108,11 @@ pub async fn op_webgpu_buffer_get_map_async( .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; buffer = buffer_resource.0; + let device_resource = state + .resource_table + .get::(args.device_rid) + .ok_or_else(bad_resource_id)?; + device = device_resource.0.clone(); let instance_resource = state .resource_table .get::(args.instance_rid) @@ -144,8 +152,39 @@ pub async fn op_webgpu_buffer_get_map_async( user_data: sender_ptr, } ))?; + drop(instance); + + let done = Rc::new(RefCell::new(false)); + let done_ = done.clone(); + let instance_rid = args.instance_rid; + let device_poll_fut = async move { + while !*done.borrow() { + { + let state = state.borrow(); + let instance_resource = state + .resource_table + .get::(instance_rid); + if let Some(instance_resource) = instance_resource { + let instance = + RcRef::map(&instance_resource, |r| &r.0).borrow().await; + wgc::gfx_select!(device.clone() => instance.device_poll(device, false)).unwrap() + } else { + break; + } + } + tokio::time::sleep(Duration::from_millis(10)).await; + } + Ok::<(), AnyError>(()) + }; + + let receiver_fut = async move { + receiver.await??; + let mut done = done_.borrow_mut(); + *done = true; + Ok::<(), AnyError>(()) + }; - receiver.await??; + tokio::try_join!(device_poll_fut, receiver_fut)?; Ok(json!({})) } From e7e149d4551a672a8d936b73054f5d63e182f9a8 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 8 Feb 2021 20:06:27 +0100 Subject: [PATCH 048/144] fix --- op_crates/webgpu/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index 49c232308bdd94..8bb469a6ca2d18 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -14,7 +14,7 @@ repository = "https://github.com/denoland/deno" path = "lib.rs" [dependencies] -deno_core = { version = "0.77.1", path = "../../core" } +deno_core = { version = "0.78.0", path = "../../core" } tokio = { version = "1.1.1", features = ["full"] } serde = { version = "1.0.121", features = ["derive"] } wgc = { package = "wgpu-core", version = "0.6.5" } From 4f4697984e9ea273a371651006bdabac4ee4f137 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 8 Feb 2021 23:10:59 +0100 Subject: [PATCH 049/144] remove AsyncRefCell --- cli/main.rs | 2 + op_crates/webgpu/binding.rs | 14 ++---- op_crates/webgpu/buffer.rs | 67 ++++++++++++----------------- op_crates/webgpu/bundle.rs | 6 +-- op_crates/webgpu/command_encoder.rs | 38 +++++----------- op_crates/webgpu/compute_pass.rs | 6 +-- op_crates/webgpu/lib.rs | 16 +++---- op_crates/webgpu/pipeline.rs | 18 +++----- op_crates/webgpu/queue.rs | 14 ++---- op_crates/webgpu/render_pass.rs | 6 +-- op_crates/webgpu/sampler.rs | 6 +-- op_crates/webgpu/shader.rs | 6 +-- op_crates/webgpu/texture.rs | 10 ++--- 13 files changed, 70 insertions(+), 139 deletions(-) diff --git a/cli/main.rs b/cli/main.rs index d98313f545a3ca..20e1ca8316771c 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1123,6 +1123,8 @@ fn init_logger(maybe_level: Option) { ) // https://github.com/denoland/deno/issues/6641 .filter_module("rustyline", LevelFilter::Off) + // wgpu backend crates (gfx_backend), have a lot of useless INFO and WARN logs + .filter_module("gfx", LevelFilter::Error) .format(|buf, record| { let mut target = record.target().to_string(); if let Some(line_no) = record.line() { diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index a0936e9f700702..024a75e72aea94 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -4,7 +4,7 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -76,9 +76,7 @@ pub fn op_webgpu_create_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let mut entries = vec![]; @@ -199,9 +197,7 @@ pub fn op_webgpu_create_pipeline_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), @@ -312,9 +308,7 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( device, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 69b7edb0b2c4b3..ed783990ff7f14 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -13,7 +13,7 @@ use deno_core::futures::channel::oneshot; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{BufVec, Resource}; pub(crate) struct WebGPUBuffer(pub(crate) wgc::id::BufferId); @@ -57,9 +57,7 @@ pub fn op_webgpu_create_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgc::resource::BufferDescriptor { label: args.label.map(Cow::Owned), @@ -98,30 +96,25 @@ pub async fn op_webgpu_buffer_get_map_async( ) -> Result { let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; - let buffer; - let device; - let instance; - { - let state = state.borrow(); - let buffer_resource = state - .resource_table - .get::(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - buffer = buffer_resource.0; - let device_resource = state - .resource_table - .get::(args.device_rid) - .ok_or_else(bad_resource_id)?; - device = device_resource.0.clone(); - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - instance = RcRef::map(&instance_resource, |r| &r.0).borrow().await; - } - let (sender, receiver) = oneshot::channel::>(); + let state_ = state.borrow(); + let buffer_resource = state_ + .resource_table + .get::(args.buffer_rid) + .ok_or_else(bad_resource_id)?; + let buffer = buffer_resource.0; + let device_resource = state_ + .resource_table + .get::(args.device_rid) + .ok_or_else(bad_resource_id)?; + let device = device_resource.0; + let instance_resource = state_ + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = &instance_resource.0; + let boxed_sender = Box::new(sender); let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; @@ -153,6 +146,7 @@ pub async fn op_webgpu_buffer_get_map_async( } ))?; drop(instance); + drop(state_); let done = Rc::new(RefCell::new(false)); let done_ = done.clone(); @@ -163,14 +157,11 @@ pub async fn op_webgpu_buffer_get_map_async( let state = state.borrow(); let instance_resource = state .resource_table - .get::(instance_rid); - if let Some(instance_resource) = instance_resource { - let instance = - RcRef::map(&instance_resource, |r| &r.0).borrow().await; - wgc::gfx_select!(device.clone() => instance.device_poll(device, false)).unwrap() - } else { - break; - } + .get::(instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = &instance_resource.0; + wgc::gfx_select!(device => instance.device_poll(device, false)) + .unwrap() } tokio::time::sleep(Duration::from_millis(10)).await; } @@ -214,9 +205,7 @@ pub fn op_webgpu_buffer_get_mapped_range( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -266,9 +255,7 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; mapped_resource .0 diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 3483446a4b9780..d45d349eef8ed0 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -107,9 +107,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 94d3256c55b4cb..ab712b729fb10e 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -57,9 +57,7 @@ pub fn op_webgpu_create_command_encoder( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), @@ -313,9 +311,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, @@ -389,9 +385,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let source = wgc::command::BufferCopyView { buffer: source_buffer_resource.0, @@ -462,9 +456,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -534,9 +526,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let source = wgc::command::TextureCopyView { texture: source_texture_resource.0, @@ -599,9 +589,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -632,9 +620,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -665,9 +651,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -701,9 +685,7 @@ pub fn op_webgpu_command_encoder_finish( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 97d414e4f541ca..33c215d578b071 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -133,9 +133,7 @@ pub fn op_webgpu_compute_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let command_encoder_resource = state .resource_table .get::( diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 903a0e2952858c..d61504ddb0cf28 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -7,7 +7,7 @@ use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, AsyncRefCell, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -26,9 +26,7 @@ pub mod sampler; pub mod shader; pub mod texture; -struct WebGPUInstance( - AsyncRefCell>, -); +struct WebGPUInstance(wgc::hub::Global); impl Resource for WebGPUInstance { fn name(&self) -> Cow { "webGPUInstance".into() @@ -84,9 +82,7 @@ pub fn op_webgpu_create_instance( wgt::BackendBit::PRIMARY, ); - let rid = state - .resource_table - .add(WebGPUInstance(AsyncRefCell::new(instance))); + let rid = state.resource_table.add(WebGPUInstance(instance)); Ok(json!({ "rid": rid, @@ -112,7 +108,7 @@ pub async fn op_webgpu_request_adapter( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = &RcRef::map(&instance_resource, |r| &r.0).borrow().await; + let instance = &instance_resource.0; let descriptor = wgc::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -188,9 +184,7 @@ pub async fn op_webgpu_request_device( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let mut features = wgt::Features::default(); diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 1db13c3722edfd..eccedfed158f34 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -176,9 +176,7 @@ pub fn op_webgpu_create_compute_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let pipeline_layout = if let Some(rid) = args.layout { let id = state @@ -247,9 +245,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; @@ -370,9 +366,7 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let mut color_states = vec![]; @@ -628,9 +622,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let bind_group_layout = wgc::gfx_select!(render_pipeline => instance .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index b8999b6497ed5c..c8c5f9dc301b36 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -5,7 +5,7 @@ use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use serde::Deserialize; type WebGPUQueue = super::WebGPUDevice; @@ -34,9 +34,7 @@ pub fn op_webgpu_queue_submit( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let mut ids = vec![]; @@ -93,9 +91,7 @@ pub fn op_webgpu_write_buffer( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -141,9 +137,7 @@ pub fn op_webgpu_write_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let destination = wgc::command::TextureCopyView { texture: texture_resource.0, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 24bde39b38aab4..ccac5473045e93 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -223,9 +223,7 @@ pub fn op_webgpu_render_pass_end_pass( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let render_pass_resource = state .resource_table .get::(args.render_pass_rid) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 051ddab5f72955..54d6513cb7936f 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -87,9 +87,7 @@ pub fn op_webgpu_create_sampler( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgc::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 9440be2ca3a482..7ce01b1d3022d5 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -42,9 +42,7 @@ pub fn op_webgpu_create_shader_module( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let source = match args.code { Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 22f3f2d69b646a..331d22c77c1751 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -4,7 +4,7 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, RcRef, ZeroCopyBuf}; +use deno_core::{serde_json, ZeroCopyBuf}; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -157,9 +157,7 @@ pub fn op_webgpu_create_texture( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), @@ -227,9 +225,7 @@ pub fn op_webgpu_create_texture_view( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), From aae3eaf596158bd5486578b7bb49d6aab2e9f6e0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 01:36:40 +0100 Subject: [PATCH 050/144] update wgpu --- Cargo.lock | 191 ++++++++--- op_crates/webgpu/14_webgpu.js | 39 ++- op_crates/webgpu/Cargo.toml | 4 +- op_crates/webgpu/binding.rs | 213 +++++++----- op_crates/webgpu/buffer.rs | 6 +- op_crates/webgpu/bundle.rs | 15 +- op_crates/webgpu/command_encoder.rs | 157 ++++----- op_crates/webgpu/lib.rs | 35 +- op_crates/webgpu/pipeline.rs | 492 ++++++++++++++-------------- op_crates/webgpu/queue.rs | 13 +- op_crates/webgpu/render_pass.rs | 6 +- op_crates/webgpu/sampler.rs | 7 +- op_crates/webgpu/shader.rs | 14 +- op_crates/webgpu/texture.rs | 33 +- 14 files changed, 728 insertions(+), 497 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a391e61970d76..4f0aa317f2cdd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + [[package]] name = "aho-corasick" version = "0.7.15" @@ -303,6 +309,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.19" @@ -1176,9 +1188,9 @@ dependencies = [ [[package]] name = "gfx-auxil" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cd956b592970f08545b9325b87580eb95a51843b6f39da27b8667fec1a1216" +checksum = "e7b33ecf067f2117668d91c9b0f2e5f223ebd1ffec314caa2f3de27bb580186d" dependencies = [ "fxhash", "gfx-hal", @@ -1187,9 +1199,9 @@ dependencies = [ [[package]] name = "gfx-backend-dx11" -version = "0.6.17" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b43f06089866bdffe59b5a6801022c86b74d2c1dd28940a9cf301d3d014fbc" +checksum = "f851d03c2e8f117e3702bf41201a4fafa447d5cb1276d5375870ae7573d069dd" dependencies = [ "arrayvec", "bitflags", @@ -1209,9 +1221,9 @@ dependencies = [ [[package]] name = "gfx-backend-dx12" -version = "0.6.13" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375014deed24d76b03604736dd899f0925158a1a96db90cbefb9cce070f71af7" +checksum = "36dc6ba2b7647e2c2b27b8f74ff5ccdd53c703776588eee5b1de515fdcbd6bc9" dependencies = [ "arrayvec", "bit-set", @@ -1220,6 +1232,7 @@ dependencies = [ "gfx-auxil", "gfx-hal", "log", + "parking_lot", "range-alloc", "raw-window-handle", "smallvec", @@ -1229,20 +1242,43 @@ dependencies = [ [[package]] name = "gfx-backend-empty" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2085227c12b78f6657a900c829f2d0deb46a9be3eaf86844fde263cdc218f77c" +checksum = "9f07ef26a65954cfdd7b4c587f485100d1bb3b0bd6a51b02d817d6c87cca7a91" dependencies = [ "gfx-hal", "log", "raw-window-handle", ] +[[package]] +name = "gfx-backend-gl" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17fd85420547bceb851fadb90f196f168abfc252d57528bd2d749db0d18b75f" +dependencies = [ + "arrayvec", + "bitflags", + "gfx-auxil", + "gfx-hal", + "glow", + "js-sys", + "khronos-egl", + "libloading", + "log", + "naga", + "parking_lot", + "raw-window-handle", + "spirv_cross", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gfx-backend-metal" -version = "0.6.5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "273d60d5207f96d99e0d11d0718995f67e56533a9df1444d83baf787f4c3cb32" +checksum = "8dc54b456ece69ef49f8893269ebf24ac70969ed34ba2719c3f3abcc8fbff14e" dependencies = [ "arrayvec", "bitflags", @@ -1252,23 +1288,22 @@ dependencies = [ "foreign-types", "gfx-auxil", "gfx-hal", - "lazy_static", "log", "metal", + "naga", "objc", "parking_lot", "range-alloc", "raw-window-handle", - "smallvec", "spirv_cross", "storage-map", ] [[package]] name = "gfx-backend-vulkan" -version = "0.6.5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3a63cf61067a09b7d1ac480af3cb2ae0c5ede5bed294607bbd814cb1666c45" +checksum = "dabe88b1a5c91e0f969b441cc57e70364858066e4ba937deeb62065654ef9bd9" dependencies = [ "arrayvec", "ash", @@ -1276,47 +1311,78 @@ dependencies = [ "core-graphics-types", "gfx-hal", "inplace_it", - "lazy_static", "log", + "naga", "objc", + "parking_lot", "raw-window-handle", "smallvec", "winapi 0.3.9", ] [[package]] -name = "gfx-descriptor" +name = "gfx-hal" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9cc8d3b573dda62d0baca4f02e0209786e22c562caff001d77c389008781d" +dependencies = [ + "bitflags", + "naga", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "glow" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072136d2c3783f3a92f131acb227bc806d3886278e2a4dc1e9990ec89ef9e70b" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gpu-alloc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7724b9aef57ea36d70faf54e0ee6265f86e41de16bed8333efdeab5b00e16b" +dependencies = [ + "bitflags", + "gpu-alloc-types", + "tracing", +] + +[[package]] +name = "gpu-alloc-types" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8c7afcd000f279d541a490e27117e61037537279b9342279abf4938fe60c6b" +checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" dependencies = [ - "arrayvec", - "fxhash", - "gfx-hal", - "log", + "bitflags", ] [[package]] -name = "gfx-hal" -version = "0.6.0" +name = "gpu-descriptor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d0754f5b7a43915fd7466883b2d1bb0800d7cc4609178d0b27bf143b9e5123" +checksum = "d74668a6a6f0202e29f212a6d47ef8c7e092a76f4ab267b0065b6e0d175e45c6" dependencies = [ "bitflags", - "raw-window-handle", + "gpu-descriptor-types", + "hashbrown", + "tracing", ] [[package]] -name = "gfx-memory" -version = "0.2.2" +name = "gpu-descriptor-types" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dccdda5d2b39412f4ca2cb15c70b5a82783a86b0606f5e985342754c8ed88f05" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" dependencies = [ - "bit-set", - "fxhash", - "gfx-hal", - "log", - "slab", + "bitflags", ] [[package]] @@ -1344,6 +1410,9 @@ name = "hashbrown" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash", +] [[package]] name = "heck" @@ -1600,6 +1669,16 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "khronos-egl" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8020ff3b84f9ac87461216ad0501bc09b33c1cbe17404d8ea405160fd164bab" +dependencies = [ + "libc", + "libloading", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1748,9 +1827,9 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "metal" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf" +checksum = "4598d719460ade24c7d91f335daf055bf2a7eec030728ce751814c50cdd6a26c" dependencies = [ "bitflags", "block", @@ -1801,14 +1880,16 @@ dependencies = [ [[package]] name = "naga" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0873deb76cf44b7454fba7b2ba6a89d3de70c08aceffd2c489379b3d9d08e661" +checksum = "c8f30d7036f137a2f64fd7d53b70a91545d3f09e030b77b3816ff7bd4cf3f789" dependencies = [ + "bit-set", "bitflags", "fxhash", "log", "num-traits", + "petgraph", "spirv_headers", "thiserror", ] @@ -2705,6 +2786,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "slotmap" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c46a3482db8f247956e464d783693ece164ca056e6e67563ee5505bdb86452cd" + [[package]] name = "smallvec" version = "1.6.1" @@ -2746,9 +2833,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spirv_cross" -version = "0.22.2" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ebd49af36be83ecd6290b57147e2a0e26145b832634b17146d934b197ca3713" +checksum = "06db6bd7b6518f761593783e2896eefe55e90455efc5f44511078ce0426ed418" dependencies = [ "cc", "js-sys", @@ -3479,9 +3566,21 @@ checksum = "f7d40a22fd029e33300d8d89a5cc8ffce18bb7c587662f54629e94c9de5487f3" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f080ea7e4107844ef4766459426fa2d5c1ada2e47edba05dc7fa99d9629f47" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.8", + "syn 1.0.60", +] + [[package]] name = "tracing-core" version = "0.1.17" @@ -3862,22 +3961,24 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.6.5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea487deeae90e06d77eb8e6cef945247774e7c0a0a226d238b31e90633594365" +checksum = "0d0b0acbc906c464cb75dac28062a8591ec9fe0ce61e271bb732c43196dc6aa1" dependencies = [ "arrayvec", "bitflags", + "cfg_aliases", "copyless", "fxhash", "gfx-backend-dx11", "gfx-backend-dx12", "gfx-backend-empty", + "gfx-backend-gl", "gfx-backend-metal", "gfx-backend-vulkan", - "gfx-descriptor", "gfx-hal", - "gfx-memory", + "gpu-alloc", + "gpu-descriptor", "naga", "parking_lot", "smallvec", @@ -3888,9 +3989,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e3529528e608b54838ee618c3923b0f46e6db0334cfc6c42a16cf4ceb3bdb57" +checksum = "72fa9ba80626278fd87351555c363378d08122d7601e58319be3d6fa85a87747" dependencies = [ "bitflags", ] diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 16bfec5accf03c..95417a8f0d29c0 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -73,11 +73,16 @@ get features() { return this.#features; } + #limits; + get limits() { + return this.#limits; + } constructor(rid, data) { this.#rid = rid; this.#name = data.name; this.#features = Object.freeze(data.features); + this.#limits = Object.freeze(data.limits); } async requestDevice(descriptor = {}) { @@ -112,9 +117,9 @@ get limits() { return this.#limits; } - #defaultQueue; - get defaultQueue() { - return this.#defaultQueue; + #queue; + get queue() { + return this.#queue; } constructor(adapter, rid, data) { @@ -124,10 +129,12 @@ this.#rid = rid; this.#features = Object.freeze(data.features); this.#limits = data.limits; - this.#defaultQueue = new GPUQueue(rid, data.label); + this.#queue = new GPUQueue(rid, data.label); this.label = data.label; } + destroy() {} // TODO + createBuffer(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { instanceRid, @@ -172,6 +179,18 @@ } createBindGroupLayout(descriptor) { + for (const entry of descriptor.entries) { + let i = 0; + if (descriptor.buffer) i++; + if (descriptor.sampler) i++; + if (descriptor.texture) i++; + if (descriptor.storageTexture) i++; + + if (i !== 1) { + throw new Error(); // TODO + } + } + const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { instanceRid, deviceRid: this.#rid, @@ -285,12 +304,12 @@ return pipeline; } - createReadyComputePipeline(_descriptor) { - throw new Error("Not yet implemented"); // easy polyfill + createComputePipelineAsync(_descriptor) { + throw new Error("Not yet implemented"); // TODO easy polyfill } - createReadyRenderPipeline(_descriptor) { - throw new Error("Not yet implemented"); // easy polyfill + createRenderPipelineAsync(_descriptor) { + throw new Error("Not yet implemented"); // TODO easy polyfill } createCommandEncoder(descriptor = {}) { @@ -336,8 +355,8 @@ ), }); } - createFence(_descriptor = {}) { - throw new Error("Not yet implemented"); + + async onSubmittedWorkDone() { } writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index 8bb469a6ca2d18..e24f1b2e997bc7 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -17,5 +17,5 @@ path = "lib.rs" deno_core = { version = "0.78.0", path = "../../core" } tokio = { version = "1.1.1", features = ["full"] } serde = { version = "1.0.121", features = ["derive"] } -wgc = { package = "wgpu-core", version = "0.6.5" } -wgt = { package = "wgpu-types", version = "0.6.1" } +wgc = { package = "wgpu-core", version = "0.7.0" } +wgt = { package = "wgpu-types", version = "0.7.0" } diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index a0936e9f700702..aea18a6619b5cb 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; +use deno_core::error::bad_resource_id; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::{serde_json, RcRef, ZeroCopyBuf}; @@ -9,8 +9,6 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -use super::texture::{serialize_dimension, serialize_texture_format}; - pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgc::id::BindGroupLayoutId); impl Resource for WebGPUBindGroupLayout { fn name(&self) -> Cow { @@ -25,16 +23,36 @@ impl Resource for WebGPUBindGroup { } } -fn serialize_texture_component_type( - component_type: String, -) -> Result { - Ok(match component_type.as_str() { - "float" => wgt::TextureComponentType::Float, - "sint" => wgt::TextureComponentType::Sint, - "uint" => wgt::TextureComponentType::Uint, - "depth-comparison" => return Err(not_supported()), - _ => unreachable!(), - }) +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUBufferBindingLayout { + #[serde(rename = "type")] + kind: Option, + has_dynamic_offset: Option, + min_binding_size: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUSamplerBindingLayout { + #[serde(rename = "type")] + kind: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUTextureBindingLayout { + sample_type: Option, + view_dimension: Option, + multisampled: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUStorageTextureBindingLayout { + access: String, + format: String, + view_dimension: Option, } #[derive(Deserialize)] @@ -42,13 +60,10 @@ fn serialize_texture_component_type( struct GPUBindGroupLayoutEntry { binding: u32, visibility: u32, - #[serde(rename = "type")] - kind: String, - has_dynamic_offset: Option, - min_buffer_binding_size: Option, - view_dimension: Option, - texture_component_type: Option, - storage_texture_format: Option, + buffer: Option, + sampler: Option, + texture: Option, + storage_texture: Option, } #[derive(Deserialize)] @@ -83,76 +98,110 @@ pub fn op_webgpu_create_bind_group_layout( let mut entries = vec![]; for entry in &args.entries { - let e = wgt::BindGroupLayoutEntry { + entries.push(wgt::BindGroupLayoutEntry { binding: entry.binding, visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), - ty: match entry.kind.as_str() { - "uniform-buffer" => wgt::BindingType::UniformBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - }, - "storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - readonly: false, - }, - "readonly-storage-buffer" => wgt::BindingType::StorageBuffer { - dynamic: entry.has_dynamic_offset.unwrap_or(false), - min_binding_size: std::num::NonZeroU64::new( - entry.min_buffer_binding_size.unwrap_or(0), - ), - readonly: true, - }, - "sampler" => wgt::BindingType::Sampler { comparison: false }, - "comparison-sampler" => wgt::BindingType::Sampler { comparison: true }, - "sampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.clone().unwrap(), - )?, - multisampled: false, - }, - "multisampled-texture" => wgt::BindingType::SampledTexture { - dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), - component_type: serialize_texture_component_type( - entry.texture_component_type.clone().unwrap(), - )?, - multisampled: true, - }, - "readonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.clone().unwrap(), - )?, - readonly: true, - }, - "writeonly-storage-texture" => wgt::BindingType::StorageTexture { - dimension: serialize_dimension(entry.view_dimension.clone().unwrap()), - format: serialize_texture_format( - entry.storage_texture_format.clone().unwrap(), + ty: if let Some(buffer) = &entry.buffer { + wgt::BindingType::Buffer { + ty: match &buffer.kind { + Some(kind) => match kind.as_str() { + "uniform" => wgt::BufferBindingType::Uniform, + "storage" => wgt::BufferBindingType::Storage { read_only: false }, + "read-only-storage" => { + wgt::BufferBindingType::Storage { read_only: true } + } + _ => unreachable!(), + }, + None => wgt::BufferBindingType::Uniform, + }, + has_dynamic_offset: buffer.has_dynamic_offset.unwrap_or(false), + min_binding_size: if let Some(min_binding_size) = + buffer.min_binding_size + { + std::num::NonZeroU64::new(min_binding_size) + } else { + None + }, + } + } else if let Some(sampler) = &entry.sampler { + match &sampler.kind { + Some(kind) => match kind.as_str() { + "filtering" => wgt::BindingType::Sampler { + filtering: true, + comparison: false, + }, + "non-filtering" => wgt::BindingType::Sampler { + filtering: false, + comparison: false, + }, + "comparison" => wgt::BindingType::Sampler { + filtering: false, + comparison: true, + }, + _ => unreachable!(), + }, + None => wgt::BindingType::Sampler { + filtering: true, + comparison: false, + }, + } + } else if let Some(texture) = &entry.texture { + wgt::BindingType::Texture { + sample_type: match &texture.sample_type { + Some(sample_type) => match sample_type.as_str() { + "float" => wgt::TextureSampleType::Float { filterable: true }, + "unfilterable-float" => { + wgt::TextureSampleType::Float { filterable: false } + } + "depth" => wgt::TextureSampleType::Depth, + "sint" => wgt::TextureSampleType::Sint, + "uint" => wgt::TextureSampleType::Uint, + _ => unreachable!(), + }, + None => wgt::TextureSampleType::Float { filterable: true }, + }, + view_dimension: match &texture.view_dimension { + Some(view_dimension) => { + super::texture::serialize_dimension(view_dimension) + } + None => wgt::TextureViewDimension::D2, + }, + multisampled: texture.multisampled.unwrap_or(false), + } + } else if let Some(storage_texture) = &entry.storage_texture { + wgt::BindingType::StorageTexture { + access: match storage_texture.access.as_str() { + "read-only" => wgt::StorageTextureAccess::ReadOnly, + "write-only" => wgt::StorageTextureAccess::WriteOnly, + _ => unreachable!(), + }, + format: super::texture::serialize_texture_format( + &storage_texture.format, )?, - readonly: false, - }, - _ => unreachable!(), + view_dimension: match &storage_texture.view_dimension { + Some(view_dimension) => { + super::texture::serialize_dimension(view_dimension) + } + None => wgt::TextureViewDimension::D2, + }, + } + } else { + unreachable!() }, - count: None, - }; - entries.push(e); + count: None, // native-only + }); } let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { label: args.label.map(Cow::Owned), entries: Cow::Owned(entries), }; - let bind_group_layout = wgc::gfx_select!(device => instance.device_create_bind_group_layout( + // TODO + let (bind_group_layout, _) = wgc::gfx_select!(device => instance.device_create_bind_group_layout( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -208,11 +257,12 @@ pub fn op_webgpu_create_pipeline_layout( bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; - let pipeline_layout = wgc::gfx_select!(device => instance.device_create_pipeline_layout( + // TODO + let (pipeline_layout, _) = wgc::gfx_select!(device => instance.device_create_pipeline_layout( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -316,11 +366,12 @@ pub fn op_webgpu_create_bind_group( .try_borrow() .unwrap(); - let bind_group = wgc::gfx_select!(device => instance.device_create_bind_group( + // TODO + let (bind_group, _) = wgc::gfx_select!(device => instance.device_create_bind_group( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUBindGroup(bind_group)); diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 69b7edb0b2c4b3..64c71141558fd4 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -67,11 +67,13 @@ pub fn op_webgpu_create_buffer( usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }; - let buffer = wgc::gfx_select!(device => instance.device_create_buffer( + + // TODO + let (buffer, _) = wgc::gfx_select!(device => instance.device_create_buffer( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUBuffer(buffer)); diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 3483446a4b9780..ec5a02917b8209 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -53,7 +53,7 @@ pub fn op_webgpu_create_render_bundle_encoder( let mut color_formats = vec![]; for format in &args.color_formats { - color_formats.push(serialize_texture_format(format.clone())?); + color_formats.push(serialize_texture_format(format)?); } let descriptor = wgc::command::RenderBundleEncoderDescriptor { @@ -61,7 +61,7 @@ pub fn op_webgpu_create_render_bundle_encoder( color_formats: Cow::Owned(color_formats), depth_stencil_format: args .depth_stencil_format - .map(serialize_texture_format) + .map(|s| serialize_texture_format(&s)) .transpose()?, sample_count: args.sample_count.unwrap_or(1), }; @@ -111,13 +111,14 @@ pub fn op_webgpu_render_bundle_encoder_finish( .try_borrow() .unwrap(); - let render_bundle = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + // TODO + let (render_bundle, _) = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgc::command::RenderBundleDescriptor { label: args.label.map(Cow::Owned), }, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPURenderBundle(render_bundle)); @@ -300,7 +301,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( struct RenderBundleEncoderSetIndexBufferArgs { render_bundle_encoder_rid: u32, buffer: u32, - _index_format: String, // wgpu#978 + index_format: String, offset: u64, size: u64, } @@ -322,9 +323,9 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_set_index_buffer( - &mut render_bundle_encoder_resource.0.borrow_mut(), + render_bundle_encoder_resource.0.borrow_mut().set_index_buffer( buffer_resource.0, + super::pipeline::serialize_index_format(args.index_format), args.offset, std::num::NonZeroU64::new(args.size), ); diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 94d3256c55b4cb..e1af0f3a770b40 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -64,11 +64,13 @@ pub fn op_webgpu_create_command_encoder( let descriptor = wgt::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), }; - let command_encoder = wgc::gfx_select!(device => instance.device_create_command_encoder( + + // TODO + let (command_encoder, _) = wgc::gfx_select!(device => instance.device_create_command_encoder( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -81,8 +83,8 @@ pub fn op_webgpu_create_command_encoder( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPURenderPassColorAttachmentDescriptor { - attachment: u32, +struct GPURenderPassColorAttachment { + view: u32, resolve_target: Option, load_op: String, load_value: Option, @@ -91,8 +93,8 @@ struct GPURenderPassColorAttachmentDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPURenderPassDepthStencilAttachmentDescriptor { - attachment: u32, +struct GPURenderPassDepthStencilAttachment { + view: u32, depth_load_op: String, depth_load_value: Option, depth_store_op: String, @@ -107,11 +109,10 @@ struct GPURenderPassDepthStencilAttachmentDescriptor { #[serde(rename_all = "camelCase")] struct CommandEncoderBeginRenderPassArgs { command_encoder_rid: u32, - _label: Option, // wgpu#974 - color_attachments: Vec, - depth_stencil_attachment: - Option, - _occlusion_query_set: u32, // wgpu#721 + label: Option, + color_attachments: Vec, + depth_stencil_attachment: Option, + _occlusion_query_set: u32, // TODO wgpu#721 } pub fn op_webgpu_command_encoder_begin_render_pass( @@ -131,7 +132,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( for color_attachment in args.color_attachments { let texture_view_resource = state .resource_table - .get::(color_attachment.attachment) + .get::(color_attachment.view) .ok_or_else(bad_resource_id)?; let attachment = wgc::command::ColorAttachmentDescriptor { @@ -183,53 +184,53 @@ pub fn op_webgpu_command_encoder_begin_render_pass( if let Some(attachment) = args.depth_stencil_attachment { let texture_view_resource = state .resource_table - .get::(attachment.attachment) + .get::(attachment.view) .ok_or_else(bad_resource_id)?; - let attachment = wgc::command::DepthStencilAttachmentDescriptor { - attachment: texture_view_resource.0, - depth: match attachment.depth_load_op.as_str() { - "load" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Load, - store_op: serialize_store_op(attachment.depth_store_op), - clear_value: 0.0, - read_only: attachment.depth_read_only.unwrap_or(false), - }, - "clear" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, - store_op: serialize_store_op(attachment.depth_store_op), - clear_value: attachment.depth_load_value.unwrap(), - read_only: attachment.depth_read_only.unwrap_or(false), - }, - _ => unreachable!(), - }, - stencil: match attachment.stencil_load_op.as_str() { - "load" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Load, - store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: 0, - read_only: attachment.stencil_read_only.unwrap_or(false), + depth_stencil_attachment = + Some(wgc::command::DepthStencilAttachmentDescriptor { + attachment: texture_view_resource.0, + depth: match attachment.depth_load_op.as_str() { + "load" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Load, + store_op: serialize_store_op(attachment.depth_store_op), + clear_value: 0.0, + read_only: attachment.depth_read_only.unwrap_or(false), + }, + "clear" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, + store_op: serialize_store_op(attachment.depth_store_op), + clear_value: attachment.depth_load_value.unwrap(), + read_only: attachment.depth_read_only.unwrap_or(false), + }, + _ => unreachable!(), }, - "clear" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, - store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: attachment.stencil_load_value.unwrap(), - read_only: attachment.stencil_read_only.unwrap_or(false), + stencil: match attachment.stencil_load_op.as_str() { + "load" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Load, + store_op: serialize_store_op(attachment.stencil_store_op), + clear_value: 0, + read_only: attachment.stencil_read_only.unwrap_or(false), + }, + "clear" => wgc::command::PassChannel { + load_op: wgc::command::LoadOp::Clear, + store_op: serialize_store_op(attachment.stencil_store_op), + clear_value: attachment.stencil_load_value.unwrap(), + read_only: attachment.stencil_read_only.unwrap_or(false), + }, + _ => unreachable!(), }, - _ => unreachable!(), - }, - }; - - depth_stencil_attachment = Some(attachment); + }); } - let render_pass = wgc::command::RenderPass::new( - command_encoder_resource.0, - wgc::command::RenderPassDescriptor { - color_attachments: Cow::Owned(color_attachments), - depth_stencil_attachment: depth_stencil_attachment.as_ref(), - }, - ); + let descriptor = wgc::command::RenderPassDescriptor { + label: args.label.map(Cow::Owned), + color_attachments: Cow::Owned(color_attachments), + depth_stencil_attachment: depth_stencil_attachment.as_ref(), + }; + + let render_pass = + wgc::command::RenderPass::new(command_encoder_resource.0, &descriptor); let rid = state .resource_table @@ -246,7 +247,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( #[serde(rename_all = "camelCase")] struct CommandEncoderBeginComputePassArgs { command_encoder_rid: u32, - _label: Option, // wgpu#974 + label: Option, } pub fn op_webgpu_command_encoder_begin_compute_pass( @@ -261,7 +262,12 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let compute_pass = wgc::command::ComputePass::new(command_encoder_resource.0); + let descriptor = wgc::command::ComputePassDescriptor { + label: args.label.map(Cow::Owned), + }; + + let compute_pass = + wgc::command::ComputePass::new(command_encoder_resource.0, &descriptor); let rid = state .resource_table @@ -331,7 +337,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -pub struct GPUBufferCopyView { +pub struct GPUImageCopyBuffer { buffer: u32, offset: Option, bytes_per_row: Option, @@ -348,10 +354,11 @@ pub struct GPUOrigin3D { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -pub struct GPUTextureCopyView { +pub struct GPUImageCopyTexture { pub texture: u32, pub mip_level: Option, pub origin: Option, + pub aspect: Option, // TODO } #[derive(Deserialize)] @@ -359,8 +366,8 @@ pub struct GPUTextureCopyView { struct CommandEncoderCopyBufferToTextureArgs { instance_rid: u32, command_encoder_rid: u32, - source: GPUBufferCopyView, - destination: GPUTextureCopyView, + source: GPUImageCopyBuffer, + destination: GPUImageCopyTexture, copy_size: super::texture::GPUExtent3D, } @@ -418,9 +425,9 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( &source, &destination, &wgt::Extent3d { - width: args.copy_size.width, - height: args.copy_size.height, - depth: args.copy_size.depth, + width: args.copy_size.width.unwrap_or(1), + height: args.copy_size.height.unwrap_or(1), + depth: args.copy_size.depth.unwrap_or(1), } ))?; @@ -432,8 +439,8 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( struct CommandEncoderCopyTextureToBufferArgs { instance_rid: u32, command_encoder_rid: u32, - source: GPUTextureCopyView, - destination: GPUBufferCopyView, + source: GPUImageCopyTexture, + destination: GPUImageCopyBuffer, copy_size: super::texture::GPUExtent3D, } @@ -490,9 +497,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( &source, &destination, &wgt::Extent3d { - width: args.copy_size.width, - height: args.copy_size.height, - depth: args.copy_size.depth, + width: args.copy_size.width.unwrap_or(1), + height: args.copy_size.height.unwrap_or(1), + depth: args.copy_size.depth.unwrap_or(1), } ))?; @@ -504,8 +511,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( struct CommandEncoderCopyTextureToTextureArgs { instance_rid: u32, command_encoder_rid: u32, - source: GPUTextureCopyView, - destination: GPUTextureCopyView, + source: GPUImageCopyTexture, + destination: GPUImageCopyTexture, copy_size: super::texture::GPUExtent3D, } @@ -566,9 +573,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( &source, &destination, &wgt::Extent3d { - width: args.copy_size.width, - height: args.copy_size.height, - depth: args.copy_size.depth, + width: args.copy_size.width.unwrap_or(1), + height: args.copy_size.height.unwrap_or(1), + depth: args.copy_size.depth.unwrap_or(1), } ))?; @@ -708,10 +715,12 @@ pub fn op_webgpu_command_encoder_finish( let descriptor = wgt::CommandBufferDescriptor { label: args.label.map(Cow::Owned), }; - let command_buffer = wgc::gfx_select!(command_encoder => instance.command_encoder_finish( + + // TODO + let (command_buffer, _) = wgc::gfx_select!(command_encoder => instance.command_encoder_finish( command_encoder, &descriptor - ))?; + )); let rid = state .resource_table diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 903a0e2952858c..4cb091f2364947 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -121,7 +121,7 @@ pub async fn op_webgpu_request_adapter( "high-performance" => wgt::PowerPreference::HighPerformance, _ => unreachable!(), }, - None => wgt::PowerPreference::Default, + None => Default::default(), }, compatible_surface: None, // windowless }; @@ -137,6 +137,20 @@ pub async fn op_webgpu_request_adapter( let adapter_features = wgc::gfx_select!(adapter => instance.adapter_features(adapter))?; let features = deserialize_features(&adapter_features); + let adapter_limits = + wgc::gfx_select!(adapter => instance.adapter_limits(adapter))?; + + let limits = json!({ + "maxBindGroups": adapter_limits.max_bind_groups, + "maxDynamicUniformBuffersPerPipelineLayout": adapter_limits.max_dynamic_uniform_buffers_per_pipeline_layout, + "maxDynamicStorageBuffersPerPipelineLayout": adapter_limits.max_dynamic_storage_buffers_per_pipeline_layout, + "maxSampledTexturesPerShaderStage": adapter_limits.max_sampled_textures_per_shader_stage, + "maxSamplersPerShaderStage": adapter_limits.max_samplers_per_shader_stage, + "maxStorageBuffersPerShaderStage": adapter_limits.max_storage_buffers_per_shader_stage, + "maxStorageTexturesPerShaderStage": adapter_limits.max_storage_textures_per_shader_stage, + "maxUniformBuffersPerShaderStage": adapter_limits.max_uniform_buffers_per_shader_stage, + "maxUniformBufferBindingSize": adapter_limits.max_uniform_buffer_binding_size + }); let rid = state.resource_table.add(WebGPUAdapter(adapter)); @@ -144,6 +158,7 @@ pub async fn op_webgpu_request_adapter( "rid": rid, "name": name, "features": features, + "limits": limits })) } @@ -166,9 +181,9 @@ struct GPULimits { struct RequestDeviceArgs { instance_rid: u32, adapter_rid: u32, - _label: Option, // wgpu#976 - features: Option>, - limits: Option, + label: Option, + non_guaranteed_features: Option>, + non_guaranteed_limits: Option, // TODO } pub async fn op_webgpu_request_device( @@ -194,19 +209,21 @@ pub async fn op_webgpu_request_device( let mut features = wgt::Features::default(); - if let Some(passed_features) = args.features { + if let Some(passed_features) = args.non_guaranteed_features { if passed_features.contains(&"depth-clamping".to_string()) { features.set(wgt::Features::DEPTH_CLAMPING, true); } if passed_features.contains(&"texture-compression-bc".to_string()) { features.set(wgt::Features::TEXTURE_COMPRESSION_BC, true); } + // TODO } let descriptor = wgt::DeviceDescriptor { + label: args.label.map(Cow::Owned), features, limits: args - .limits + .non_guaranteed_limits .map_or(Default::default(), |limits| wgt::Limits { max_bind_groups: limits.max_bind_groups.unwrap_or(4), max_dynamic_uniform_buffers_per_pipeline_layout: limits @@ -235,14 +252,14 @@ pub async fn op_webgpu_request_device( .unwrap_or(16384), max_push_constant_size: 0, }), - shader_validation: false, }; - let device = wgc::gfx_select!(adapter => instance.adapter_request_device( + // TODO + let (device, _) = wgc::gfx_select!(adapter => instance.adapter_request_device( adapter, &descriptor, None, std::marker::PhantomData - ))?; + )); let device_features = wgc::gfx_select!(device => instance.device_features(device))?; diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 1db13c3722edfd..052fc70df25265 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -11,6 +11,7 @@ use std::borrow::Cow; use super::sampler::serialize_compare_function; use super::texture::serialize_texture_format; +use crate::shader::WebGPUShaderModule; pub(crate) struct WebGPUPipelineLayout(pub(crate) wgc::id::PipelineLayoutId); impl Resource for WebGPUPipelineLayout { @@ -33,20 +34,12 @@ impl Resource for WebGPURenderPipeline { } } -fn serialize_programmable_stage_descriptor( - state: &OpState, - programmable_stage_descriptor: GPUProgrammableStageDescriptor, -) -> Result { - let shader_module_resource = state - .resource_table - .get::( - programmable_stage_descriptor.module, - ) - .ok_or_else(bad_resource_id)?; - Ok(wgc::pipeline::ProgrammableStageDescriptor { - module: shader_module_resource.0, - entry_point: Cow::Owned(programmable_stage_descriptor.entry_point), - }) +pub fn serialize_index_format(format: String) -> wgt::IndexFormat { + match format.as_str() { + "uint16" => wgt::IndexFormat::Uint16, + "uint32" => wgt::IndexFormat::Uint32, + _ => unreachable!(), + } } fn serialize_stencil_operation(operation: &str) -> wgt::StencilOperation { @@ -63,10 +56,8 @@ fn serialize_stencil_operation(operation: &str) -> wgt::StencilOperation { } } -fn serialize_stencil_state_face_descriptor( - state: &GPUStencilStateFaceDescriptor, -) -> wgt::StencilStateFaceDescriptor { - wgt::StencilStateFaceDescriptor { +fn serialize_stencil_face_state(state: GPUStencilFaceState) -> wgt::StencilFaceState { + wgt::StencilFaceState { compare: state .compare .as_ref() @@ -113,10 +104,8 @@ fn serialize_blend_factor(blend_factor: &str) -> wgt::BlendFactor { } } -fn serialize_blend_descriptor( - blend: &GPUBlendDescriptor, -) -> wgt::BlendDescriptor { - wgt::BlendDescriptor { +fn serialize_blend_component(blend: GPUBlendComponent) -> wgt::BlendState { + wgt::BlendState { src_factor: blend .src_factor .as_ref() @@ -145,7 +134,7 @@ fn serialize_blend_descriptor( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUProgrammableStageDescriptor { +struct GPUProgrammableStage { module: u32, entry_point: String, } @@ -157,7 +146,7 @@ struct CreateComputePipelineArgs { device_rid: u32, label: Option, layout: Option, - compute_stage: GPUProgrammableStageDescriptor, + compute: GPUProgrammableStage, } pub fn op_webgpu_create_compute_pipeline( @@ -190,13 +179,18 @@ pub fn op_webgpu_create_compute_pipeline( None }; - let compute_stage = - serialize_programmable_stage_descriptor(state, args.compute_stage)?; + let compute_shader_module_resource = state + .resource_table + .get::(args.compute.module) + .ok_or_else(bad_resource_id)?; let descriptor = wgc::pipeline::ComputePipelineDescriptor { label: args.label.map(Cow::Owned), layout: pipeline_layout, - compute_stage, + stage: wgc::pipeline::ProgrammableStageDescriptor { + module: compute_shader_module_resource.0, + entry_point: Cow::Owned(args.compute.entry_point) + }, }; let implicit_pipelines = match args.layout { Some(_) => None, @@ -206,12 +200,13 @@ pub fn op_webgpu_create_compute_pipeline( }), }; - let (compute_pipeline, _) = wgc::gfx_select!(device => instance.device_create_compute_pipeline( + // TODO + let (compute_pipeline, _, _) = wgc::gfx_select!(device => instance.device_create_compute_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines - ))?; + )); let rid = state .resource_table @@ -251,8 +246,8 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .try_borrow() .unwrap(); - let bind_group_layout = wgc::gfx_select!(compute_pipeline => instance - .compute_pipeline_get_bind_group_layout(compute_pipeline, args.index))?; + // TODO + let (bind_group_layout, _) = wgc::gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); let rid = state .resource_table @@ -265,35 +260,39 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPURasterizationStateDescriptor { +struct GPUPrimitiveState { + topology: Option, + strip_index_format: Option, front_face: Option, cull_mode: Option, - clamp_depth: Option, - depth_bias: Option, - depth_bias_slope_scale: Option, - depth_bias_clamp: Option, } -#[derive(Deserialize)] +#[derive(Deserialize, Clone)] #[serde(rename_all = "camelCase")] -struct GPUBlendDescriptor { +struct GPUBlendComponent { src_factor: Option, dst_factor: Option, operation: Option, } +#[derive(Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +struct GPUBlendState { + color: GPUBlendComponent, + alpha: GPUBlendComponent, +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUColorStateDescriptor { +struct GPUColorTargetState { format: String, - alpha_blend: Option, - color_blend: Option, + blend: Option, write_mask: Option, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUStencilStateFaceDescriptor { +struct GPUStencilFaceState { compare: Option, fail_op: Option, depth_fail_op: Option, @@ -302,19 +301,23 @@ struct GPUStencilStateFaceDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUDepthStencilStateDescriptor { +struct GPUDepthStencilState { format: String, depth_write_enabled: Option, depth_compare: Option, - stencil_front: Option, - stencil_back: Option, + stencil_front: Option, + stencil_back: Option, stencil_read_mask: Option, stencil_write_mask: Option, + depth_bias: Option, + depth_bias_slope_scale: Option, + depth_bias_clamp: Option, + clamp_depth: Option, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUVertexAttributeDescriptor { +struct GPUVertexAttribute { format: String, offset: u64, shader_location: u32, @@ -322,17 +325,34 @@ struct GPUVertexAttributeDescriptor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUVertexBufferLayoutDescriptor { +struct GPUVertexBufferLayout { array_stride: u64, step_mode: Option, - attributes: Vec, + attributes: Vec, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUVertexStateDescriptor { - index_format: Option, - vertex_buffers: Option>>, +struct GPUVertexState { + module: u32, + entry_point: String, + vertex_buffers: Option>>, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUMultisampleState { + count: Option, + mask: Option, // against spec, but future proof + alpha_to_coverage_enabled: Option, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct GPUFragmentState { + targets: Vec, + module: u32, + entry_point: String, } #[derive(Deserialize)] @@ -342,16 +362,11 @@ struct CreateRenderPipelineArgs { device_rid: u32, label: Option, layout: Option, - vertex_stage: GPUProgrammableStageDescriptor, - fragment_stage: Option, - primitive_topology: String, - rasterization_state: Option, - color_states: Vec, - depth_stencil_state: Option, - vertex_state: Option, - sample_count: Option, - sample_mask: Option, - alpha_to_coverage_enabled: Option, + vertex: GPUVertexState, + primitive: Option, + depth_stencil: Option, + multisample: Option, + fragment: Option, } pub fn op_webgpu_create_render_pipeline( @@ -374,84 +389,110 @@ pub fn op_webgpu_create_render_pipeline( .try_borrow() .unwrap(); - let mut color_states = vec![]; - - for color_state in &args.color_states { - let state = wgt::ColorStateDescriptor { - format: serialize_texture_format(color_state.format.clone())?, - alpha_blend: color_state - .alpha_blend - .as_ref() - .map_or(Default::default(), serialize_blend_descriptor), - color_blend: color_state - .color_blend - .as_ref() - .map_or(Default::default(), serialize_blend_descriptor), - write_mask: color_state.write_mask.map_or(Default::default(), |mask| { - wgt::ColorWrite::from_bits(mask).unwrap() - }), - }; - color_states.push(state); - } - - let mut depth_stencil_state = None; - - if let Some(state) = &args.depth_stencil_state { - depth_stencil_state = Some(wgt::DepthStencilStateDescriptor { - format: serialize_texture_format(state.format.clone())?, - depth_write_enabled: state.depth_write_enabled.unwrap_or(false), - depth_compare: state - .depth_compare - .as_ref() - .map_or(wgt::CompareFunction::Always, |compare| { - serialize_compare_function(compare) - }), - stencil: wgt::StencilStateDescriptor { - front: state.stencil_front.as_ref().map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - back: state.stencil_back.as_ref().map_or( - wgt::StencilStateFaceDescriptor::IGNORE, - serialize_stencil_state_face_descriptor, - ), - read_mask: state.stencil_read_mask.unwrap_or(0xFFFFFFFF), - write_mask: state.stencil_write_mask.unwrap_or(0xFFFFFFFF), - }, - }); - } - let layout = if let Some(rid) = args.layout { - let id = state + let pipeline_layout_resource = state .resource_table .get::(rid) .ok_or_else(bad_resource_id)?; - Some(id.0) + Some(pipeline_layout_resource.0) } else { None }; - let fragment_stage = - if let Some(programmable_stage_descriptor) = args.fragment_stage { - Some(serialize_programmable_stage_descriptor( - state, - programmable_stage_descriptor, - )?) - } else { - None - }; - - let vertex_stage = - serialize_programmable_stage_descriptor(state, args.vertex_stage)?; + let vertex_shader_module_resource = state + .resource_table + .get::(args.vertex.module) + .ok_or_else(bad_resource_id)?; let descriptor = wgc::pipeline::RenderPipelineDescriptor { label: args.label.map(Cow::Owned), layout, - vertex_stage, - fragment_stage, - rasterization_state: args.rasterization_state.map(|rasterization_state| { - wgt::RasterizationStateDescriptor { - front_face: match rasterization_state.front_face { + vertex: wgc::pipeline::VertexState { + stage: wgc::pipeline::ProgrammableStageDescriptor { + module: vertex_shader_module_resource.0, + entry_point: Cow::Owned(args.vertex.entry_point), + }, + buffers: Cow::Owned(if let Some(buffers) = args.vertex.vertex_buffers { + let mut return_buffers = vec![]; + for buffer in buffers { + if let Some(buffer) = buffer { + return_buffers.push(wgc::pipeline::VertexBufferLayout { + array_stride: buffer.array_stride, + step_mode: match buffer.step_mode { + Some(step_mode) => match step_mode.as_str() { + "vertex" => wgt::InputStepMode::Vertex, + "instance" => wgt::InputStepMode::Instance, + _ => unreachable!(), + }, + None => wgt::InputStepMode::Vertex, + }, + attributes: Cow::Owned( + buffer + .attributes + .iter() + .map(|attribute| wgt::VertexAttribute { + format: match attribute.format.as_str() { + "uchar2" => wgt::VertexFormat::Uchar2, + "uchar4" => wgt::VertexFormat::Uchar4, + "char2" => wgt::VertexFormat::Char2, + "char4" => wgt::VertexFormat::Char4, + "uchar2norm" => wgt::VertexFormat::Uchar2Norm, + "uchar4norm" => wgt::VertexFormat::Uchar4, + "char2norm" => wgt::VertexFormat::Char2Norm, + "char4norm" => wgt::VertexFormat::Char4Norm, + "ushort2" => wgt::VertexFormat::Ushort2, + "ushort4" => wgt::VertexFormat::Ushort4, + "short2" => wgt::VertexFormat::Short2, + "short4" => wgt::VertexFormat::Short4, + "ushort2norm" => wgt::VertexFormat::Ushort2Norm, + "ushort4norm" => wgt::VertexFormat::Ushort4Norm, + "short2norm" => wgt::VertexFormat::Short2Norm, + "short4norm" => wgt::VertexFormat::Short4Norm, + "half2" => wgt::VertexFormat::Half2, + "half4" => wgt::VertexFormat::Half4, + "float" => wgt::VertexFormat::Float, + "float2" => wgt::VertexFormat::Float2, + "float3" => wgt::VertexFormat::Float3, + "float4" => wgt::VertexFormat::Float4, + "uint" => wgt::VertexFormat::Uint, + "uint2" => wgt::VertexFormat::Uint2, + "uint3" => wgt::VertexFormat::Uint3, + "uint4" => wgt::VertexFormat::Uint4, + "int" => wgt::VertexFormat::Int, + "int2" => wgt::VertexFormat::Int2, + "int3" => wgt::VertexFormat::Int3, + "int4" => wgt::VertexFormat::Int4, + _ => unreachable!(), + }, + offset: attribute.offset, + shader_location: attribute.shader_location, + }) + .collect(), + ), + }) + } + } + return_buffers + } else { + vec![] + }), + }, + primitive: args.primitive.map_or(Default::default(), |primitive| { + // TODO + wgt::PrimitiveState { + topology: match primitive.topology { + Some(topology) => match topology.as_str() { + "point-list" => wgt::PrimitiveTopology::PointList, + "line-list" => wgt::PrimitiveTopology::LineList, + "line-strip" => wgt::PrimitiveTopology::LineStrip, + "triangle-list" => wgt::PrimitiveTopology::TriangleList, + "triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, + _ => unreachable!(), + }, + None => wgt::PrimitiveTopology::TriangleList, + }, + strip_index_format: primitive.strip_index_format.map(serialize_index_format), + front_face: match primitive.front_face { Some(front_face) => match front_face.as_str() { "ccw" => wgt::FrontFace::Ccw, "cw" => wgt::FrontFace::Cw, @@ -459,7 +500,7 @@ pub fn op_webgpu_create_render_pipeline( }, None => wgt::FrontFace::Ccw, }, - cull_mode: match rasterization_state.cull_mode { + cull_mode: match primitive.cull_mode { Some(cull_mode) => match cull_mode.as_str() { "none" => wgt::CullMode::None, "front" => wgt::CullMode::Front, @@ -468,117 +509,91 @@ pub fn op_webgpu_create_render_pipeline( }, None => wgt::CullMode::None, }, - clamp_depth: rasterization_state.clamp_depth.unwrap_or(false), - depth_bias: rasterization_state.depth_bias.unwrap_or(0), - depth_bias_slope_scale: rasterization_state - .depth_bias_slope_scale - .unwrap_or(0.0), - depth_bias_clamp: rasterization_state.depth_bias_clamp.unwrap_or(0.0), + polygon_mode: Default::default(), // native-only } }), - primitive_topology: match args.primitive_topology.as_str() { - "point-list" => wgt::PrimitiveTopology::PointList, - "line-list" => wgt::PrimitiveTopology::LineList, - "line-strip" => wgt::PrimitiveTopology::LineStrip, - "triangle-list" => wgt::PrimitiveTopology::TriangleList, - "triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, - _ => unreachable!(), - }, - color_states: Cow::Owned(color_states), - depth_stencil_state, - vertex_state: args.vertex_state.map_or( - wgc::pipeline::VertexStateDescriptor { - index_format: Default::default(), - vertex_buffers: Default::default(), - }, - |state| wgc::pipeline::VertexStateDescriptor { - index_format: state.index_format.map_or(Default::default(), |format| { - match format.as_str() { - "uint16" => wgt::IndexFormat::Uint16, - "uint32" => wgt::IndexFormat::Uint32, - _ => unreachable!(), + depth_stencil: args.depth_stencil.map(|depth_stencil| { + wgt::DepthStencilState { + format: super::texture::serialize_texture_format(&depth_stencil.format) + .unwrap(), + depth_write_enabled: depth_stencil.depth_write_enabled.unwrap_or(false), + depth_compare: match depth_stencil.depth_compare { + Some(depth_compare) => { + super::sampler::serialize_compare_function(&depth_compare) } - }), - vertex_buffers: state.vertex_buffers.map_or( - Default::default(), - |vertex_buffers| { - Cow::Owned( - vertex_buffers - .iter() - .map(|buffer| { - if let Some(buffer) = buffer { - wgc::pipeline::VertexBufferDescriptor { - stride: buffer.array_stride, - step_mode: match buffer.step_mode.clone() { - Some(step_mode) => match step_mode.as_str() { - "vertex" => wgt::InputStepMode::Vertex, - "instance" => wgt::InputStepMode::Instance, - _ => unreachable!(), - }, - None => wgt::InputStepMode::Vertex, - }, - attributes: Cow::Owned( - buffer - .attributes - .iter() - .map(|attribute| wgt::VertexAttributeDescriptor { - offset: attribute.offset, - format: match attribute.format.as_str() { - "uchar2" => wgt::VertexFormat::Uchar2, - "uchar4" => wgt::VertexFormat::Uchar4, - "char2" => wgt::VertexFormat::Char2, - "char4" => wgt::VertexFormat::Char4, - "uchar2norm" => wgt::VertexFormat::Uchar2Norm, - "uchar4norm" => wgt::VertexFormat::Uchar4, - "char2norm" => wgt::VertexFormat::Char2Norm, - "char4norm" => wgt::VertexFormat::Char4Norm, - "ushort2" => wgt::VertexFormat::Ushort2, - "ushort4" => wgt::VertexFormat::Ushort4, - "short2" => wgt::VertexFormat::Short2, - "short4" => wgt::VertexFormat::Short4, - "ushort2norm" => wgt::VertexFormat::Ushort2Norm, - "ushort4norm" => wgt::VertexFormat::Ushort4Norm, - "short2norm" => wgt::VertexFormat::Short2Norm, - "short4norm" => wgt::VertexFormat::Short4Norm, - "half2" => wgt::VertexFormat::Half2, - "half4" => wgt::VertexFormat::Half4, - "float" => wgt::VertexFormat::Float, - "float2" => wgt::VertexFormat::Float2, - "float3" => wgt::VertexFormat::Float3, - "float4" => wgt::VertexFormat::Float4, - "uint" => wgt::VertexFormat::Uint, - "uint2" => wgt::VertexFormat::Uint2, - "uint3" => wgt::VertexFormat::Uint3, - "uint4" => wgt::VertexFormat::Uint4, - "int" => wgt::VertexFormat::Int, - "int2" => wgt::VertexFormat::Int2, - "int3" => wgt::VertexFormat::Int3, - "int4" => wgt::VertexFormat::Int4, - _ => unreachable!(), - }, - shader_location: attribute.shader_location, - }) - .collect::>(), - ), - } - } else { - wgc::pipeline::VertexBufferDescriptor { - stride: 0, - step_mode: wgt::InputStepMode::Vertex, - attributes: Default::default(), - } - } - }) - .collect::>(), - ) - }, + None => wgt::CompareFunction::Always, + }, + stencil: wgt::StencilState { + front: depth_stencil + .stencil_front + .map_or(Default::default(), serialize_stencil_face_state), + back: depth_stencil + .stencil_back + .map_or(Default::default(), serialize_stencil_face_state), + read_mask: depth_stencil.stencil_read_mask.unwrap_or(0xFFFFFFFF), + write_mask: depth_stencil.stencil_write_mask.unwrap_or(0xFFFFFFFF), + }, + bias: wgt::DepthBiasState { + constant: depth_stencil.depth_bias.unwrap_or(0), + slope_scale: depth_stencil.depth_bias_slope_scale.unwrap_or(0.0), + clamp: depth_stencil.depth_bias_clamp.unwrap_or(0.0), + }, + clamp_depth: depth_stencil.clamp_depth.unwrap_or(false), + } + }), + multisample: args.multisample.map_or(Default::default(), |multisample| { + wgt::MultisampleState { + // TODO + count: multisample.count.unwrap_or(1), + mask: multisample.mask.unwrap_or(0xFFFFFFFF), + alpha_to_coverage_enabled: multisample + .alpha_to_coverage_enabled + .unwrap_or(false), + } + }), + fragment: args.fragment.map(|fragment| { + let fragment_shader_module_resource = state + .resource_table + .get::(fragment.module) + .ok_or_else(bad_resource_id) + .unwrap(); // TODO + + wgc::pipeline::FragmentState { + stage: wgc::pipeline::ProgrammableStageDescriptor { + module: fragment_shader_module_resource.0, + entry_point: Cow::Owned(fragment.entry_point), + }, + targets: Cow::Owned( + fragment + .targets + .iter() + .map(|target| { + let blends = target.blend.clone().map(|blend| { + ( + serialize_blend_component(blend.alpha), + serialize_blend_component(blend.color), + ) + }); + + wgt::ColorTargetState { + format: serialize_texture_format(&target.format).unwrap(), + alpha_blend: blends.clone() + .map_or(Default::default(), |states| states.0), + color_blend: blends + .map_or(Default::default(), |states| states.1), + write_mask: target + .write_mask + .map_or(Default::default(), |mask| { + wgt::ColorWrite::from_bits(mask).unwrap() + }), + } + }) + .collect(), ), - }, - ), - sample_count: args.sample_count.unwrap_or(1), - sample_mask: args.sample_mask.unwrap_or(0xFFFFFFFF), - alpha_to_coverage_enabled: args.alpha_to_coverage_enabled.unwrap_or(false), + } + }), }; + let implicit_pipelines = match args.layout { Some(_) => None, None => Some(wgc::device::ImplicitPipelineIds { @@ -587,12 +602,13 @@ pub fn op_webgpu_create_render_pipeline( }), }; - let (render_pipeline, _) = wgc::gfx_select!(device => instance.device_create_render_pipeline( + // TODO + let (render_pipeline, _, _) = wgc::gfx_select!(device => instance.device_create_render_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines - ))?; + )); let rid = state .resource_table @@ -632,8 +648,8 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .try_borrow() .unwrap(); - let bind_group_layout = wgc::gfx_select!(render_pipeline => instance - .render_pipeline_get_bind_group_layout(render_pipeline, args.index))?; + // TODO + let (bind_group_layout, _) = wgc::gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); let rid = state .resource_table diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index b8999b6497ed5c..804b0bd7b9973e 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -55,7 +55,7 @@ pub fn op_webgpu_queue_submit( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPUTextureDataLayout { +struct GPUImageDataLayout { offset: Option, bytes_per_row: Option, rows_per_image: Option, @@ -116,8 +116,8 @@ pub fn op_webgpu_write_buffer( struct QueueWriteTextureArgs { instance_rid: u32, queue_rid: u32, - destination: super::command_encoder::GPUTextureCopyView, - data_layout: GPUTextureDataLayout, + destination: super::command_encoder::GPUImageCopyTexture, + data_layout: GPUImageDataLayout, size: super::texture::GPUExtent3D, } @@ -162,15 +162,16 @@ pub fn op_webgpu_write_texture( bytes_per_row: args.data_layout.bytes_per_row.unwrap_or(0), rows_per_image: args.data_layout.rows_per_image.unwrap_or(0), }; + wgc::gfx_select!(queue => instance.queue_write_texture( queue, &destination, &*zero_copy[0], &data_layout, &wgt::Extent3d { - width: args.size.width, - height: args.size.height, - depth: args.size.depth, + width: args.size.width.unwrap_or(1), + height: args.size.height.unwrap_or(1), + depth: args.size.depth.unwrap_or(1), } ))?; diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 24bde39b38aab4..5ae962a9470d66 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -407,7 +407,7 @@ pub fn op_webgpu_render_pass_set_pipeline( struct RenderPassSetIndexBufferArgs { render_pass_rid: u32, buffer: u32, - _index_format: String, // wgpu#978 + index_format: String, offset: u64, size: u64, } @@ -428,9 +428,9 @@ pub fn op_webgpu_render_pass_set_index_buffer( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_index_buffer( - &mut render_pass_resource.0.borrow_mut(), + render_pass_resource.0.borrow_mut().set_index_buffer( buffer_resource.0, + super::pipeline::serialize_index_format(args.index_format), args.offset, std::num::NonZeroU64::new(args.size), ); diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 051ddab5f72955..bddb8813b1bb15 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -112,12 +112,15 @@ pub fn op_webgpu_create_sampler( anisotropy_clamp: std::num::NonZeroU8::new( args.max_anisotropy.unwrap_or(0), ), + border_color: None, // native-only }; - let sampler = wgc::gfx_select!(device => instance.device_create_sampler( + + // TODO + let (sampler, _) = wgc::gfx_select!(device => instance.device_create_sampler( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUSampler(sampler)); diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 9440be2ca3a482..91a3e30c8f8dd5 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -21,7 +21,7 @@ impl Resource for WebGPUShaderModule { struct CreateShaderModuleArgs { instance_rid: u32, device_rid: u32, - _label: Option, // wgpu#977 + label: Option, code: Option, _source_map: Option<()>, // not in wgpu } @@ -55,11 +55,19 @@ pub fn op_webgpu_create_shader_module( data })), }; - let shader_module = wgc::gfx_select!(device => instance.device_create_shader_module( + + let descriptor = wgc::pipeline::ShaderModuleDescriptor { + label: args.label.map(Cow::Owned), + flags: Default::default() + }; + + // TODO + let (shader_module, _) = wgc::gfx_select!(device => instance.device_create_shader_module( device, + &descriptor, source, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUShaderModule(shader_module)); diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 22f3f2d69b646a..7b8112b4d323b4 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -24,7 +24,7 @@ impl Resource for WebGPUTextureView { } pub fn serialize_texture_format( - format: String, + format: &String, ) -> Result { Ok(match format.as_str() { // 8-bit formats @@ -107,7 +107,7 @@ pub fn serialize_texture_format( }) } -pub fn serialize_dimension(dimension: String) -> wgt::TextureViewDimension { +pub fn serialize_dimension(dimension: &String) -> wgt::TextureViewDimension { match dimension.as_str() { "1d" => wgt::TextureViewDimension::D1, "2d" => wgt::TextureViewDimension::D2, @@ -122,9 +122,9 @@ pub fn serialize_dimension(dimension: String) -> wgt::TextureViewDimension { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct GPUExtent3D { - pub width: u32, - pub height: u32, - pub depth: u32, + pub width: Option, + pub height: Option, + pub depth: Option, } #[derive(Deserialize)] @@ -164,9 +164,9 @@ pub fn op_webgpu_create_texture( let descriptor = wgc::resource::TextureDescriptor { label: args.label.map(Cow::Owned), size: wgt::Extent3d { - width: args.size.width, - height: args.size.height, - depth: args.size.depth, + width: args.size.width.unwrap_or(1), + height: args.size.height.unwrap_or(1), + depth: args.size.depth.unwrap_or(1), }, mip_level_count: args.mip_level_count.unwrap_or(1), sample_count: args.sample_count.unwrap_or(1), @@ -179,15 +179,16 @@ pub fn op_webgpu_create_texture( }, None => wgt::TextureDimension::D2, }, - format: serialize_texture_format(args.format)?, + format: serialize_texture_format(&args.format)?, usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), }; - let texture = wgc::gfx_select!(device => instance.device_create_texture( + // TODO + let (texture, _) = wgc::gfx_select!(device => instance.device_create_texture( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUTexture(texture)); @@ -233,8 +234,8 @@ pub fn op_webgpu_create_texture_view( let descriptor = wgc::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), - format: args.format.map(serialize_texture_format).transpose()?, - dimension: args.dimension.map(serialize_dimension), + format: args.format.map(|s| serialize_texture_format(&s)).transpose()?, + dimension: args.dimension.map(|s| serialize_dimension(&s)), aspect: match args.aspect { Some(aspect) => match aspect.as_str() { "all" => wgt::TextureAspect::All, @@ -251,11 +252,13 @@ pub fn op_webgpu_create_texture_view( args.array_layer_count.unwrap_or(0), ), }; - let texture_view = wgc::gfx_select!(texture => instance.texture_create_view( + + // TODO + let (texture_view, _) = wgc::gfx_select!(texture => instance.texture_create_view( texture, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUTextureView(texture_view)); From b99cfbd81bfc05d683c999dfbd3fcb0b4965f04a Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 01:53:37 +0100 Subject: [PATCH 051/144] remove crate aliases --- op_crates/webgpu/Cargo.toml | 4 +- op_crates/webgpu/binding.rs | 72 ++++----- op_crates/webgpu/buffer.rs | 26 ++-- op_crates/webgpu/bundle.rs | 30 ++-- op_crates/webgpu/command_encoder.rs | 104 ++++++------- op_crates/webgpu/compute_pass.rs | 18 +-- op_crates/webgpu/lib.rs | 69 ++++++--- op_crates/webgpu/pipeline.rs | 232 ++++++++++++++-------------- op_crates/webgpu/queue.rs | 14 +- op_crates/webgpu/render_pass.rs | 36 ++--- op_crates/webgpu/sampler.rs | 44 +++--- op_crates/webgpu/shader.rs | 10 +- op_crates/webgpu/texture.rs | 152 +++++++++--------- 13 files changed, 416 insertions(+), 395 deletions(-) diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index e24f1b2e997bc7..0d4b96f5be4e07 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -17,5 +17,5 @@ path = "lib.rs" deno_core = { version = "0.78.0", path = "../../core" } tokio = { version = "1.1.1", features = ["full"] } serde = { version = "1.0.121", features = ["derive"] } -wgc = { package = "wgpu-core", version = "0.7.0" } -wgt = { package = "wgpu-types", version = "0.7.0" } +wgpu-core = "0.7.0" +wgpu-types = "0.7.0" diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index aea18a6619b5cb..836d1cf6d3bbf9 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -9,14 +9,14 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgc::id::BindGroupLayoutId); +pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgpu_core::id::BindGroupLayoutId); impl Resource for WebGPUBindGroupLayout { fn name(&self) -> Cow { "webGPUBindGroupLayout".into() } } -pub(crate) struct WebGPUBindGroup(pub(crate) wgc::id::BindGroupId); +pub(crate) struct WebGPUBindGroup(pub(crate) wgpu_core::id::BindGroupId); impl Resource for WebGPUBindGroup { fn name(&self) -> Cow { "webGPUBindGroup".into() @@ -98,21 +98,21 @@ pub fn op_webgpu_create_bind_group_layout( let mut entries = vec![]; for entry in &args.entries { - entries.push(wgt::BindGroupLayoutEntry { + entries.push(wgpu_types::BindGroupLayoutEntry { binding: entry.binding, - visibility: wgt::ShaderStage::from_bits(entry.visibility).unwrap(), + visibility: wgpu_types::ShaderStage::from_bits(entry.visibility).unwrap(), ty: if let Some(buffer) = &entry.buffer { - wgt::BindingType::Buffer { + wgpu_types::BindingType::Buffer { ty: match &buffer.kind { Some(kind) => match kind.as_str() { - "uniform" => wgt::BufferBindingType::Uniform, - "storage" => wgt::BufferBindingType::Storage { read_only: false }, + "uniform" => wgpu_types::BufferBindingType::Uniform, + "storage" => wgpu_types::BufferBindingType::Storage { read_only: false }, "read-only-storage" => { - wgt::BufferBindingType::Storage { read_only: true } + wgpu_types::BufferBindingType::Storage { read_only: true } } _ => unreachable!(), }, - None => wgt::BufferBindingType::Uniform, + None => wgpu_types::BufferBindingType::Uniform, }, has_dynamic_offset: buffer.has_dynamic_offset.unwrap_or(false), min_binding_size: if let Some(min_binding_size) = @@ -126,53 +126,53 @@ pub fn op_webgpu_create_bind_group_layout( } else if let Some(sampler) = &entry.sampler { match &sampler.kind { Some(kind) => match kind.as_str() { - "filtering" => wgt::BindingType::Sampler { + "filtering" => wgpu_types::BindingType::Sampler { filtering: true, comparison: false, }, - "non-filtering" => wgt::BindingType::Sampler { + "non-filtering" => wgpu_types::BindingType::Sampler { filtering: false, comparison: false, }, - "comparison" => wgt::BindingType::Sampler { + "comparison" => wgpu_types::BindingType::Sampler { filtering: false, comparison: true, }, _ => unreachable!(), }, - None => wgt::BindingType::Sampler { + None => wgpu_types::BindingType::Sampler { filtering: true, comparison: false, }, } } else if let Some(texture) = &entry.texture { - wgt::BindingType::Texture { + wgpu_types::BindingType::Texture { sample_type: match &texture.sample_type { Some(sample_type) => match sample_type.as_str() { - "float" => wgt::TextureSampleType::Float { filterable: true }, + "float" => wgpu_types::TextureSampleType::Float { filterable: true }, "unfilterable-float" => { - wgt::TextureSampleType::Float { filterable: false } + wgpu_types::TextureSampleType::Float { filterable: false } } - "depth" => wgt::TextureSampleType::Depth, - "sint" => wgt::TextureSampleType::Sint, - "uint" => wgt::TextureSampleType::Uint, + "depth" => wgpu_types::TextureSampleType::Depth, + "sint" => wgpu_types::TextureSampleType::Sint, + "uint" => wgpu_types::TextureSampleType::Uint, _ => unreachable!(), }, - None => wgt::TextureSampleType::Float { filterable: true }, + None => wgpu_types::TextureSampleType::Float { filterable: true }, }, view_dimension: match &texture.view_dimension { Some(view_dimension) => { super::texture::serialize_dimension(view_dimension) } - None => wgt::TextureViewDimension::D2, + None => wgpu_types::TextureViewDimension::D2, }, multisampled: texture.multisampled.unwrap_or(false), } } else if let Some(storage_texture) = &entry.storage_texture { - wgt::BindingType::StorageTexture { + wgpu_types::BindingType::StorageTexture { access: match storage_texture.access.as_str() { - "read-only" => wgt::StorageTextureAccess::ReadOnly, - "write-only" => wgt::StorageTextureAccess::WriteOnly, + "read-only" => wgpu_types::StorageTextureAccess::ReadOnly, + "write-only" => wgpu_types::StorageTextureAccess::WriteOnly, _ => unreachable!(), }, format: super::texture::serialize_texture_format( @@ -182,7 +182,7 @@ pub fn op_webgpu_create_bind_group_layout( Some(view_dimension) => { super::texture::serialize_dimension(view_dimension) } - None => wgt::TextureViewDimension::D2, + None => wgpu_types::TextureViewDimension::D2, }, } } else { @@ -192,12 +192,12 @@ pub fn op_webgpu_create_bind_group_layout( }); } - let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { + let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { label: args.label.map(Cow::Owned), entries: Cow::Owned(entries), }; // TODO - let (bind_group_layout, _) = wgc::gfx_select!(device => instance.device_create_bind_group_layout( + let (bind_group_layout, _) = gfx_select!(device => instance.device_create_bind_group_layout( device, &descriptor, std::marker::PhantomData @@ -252,13 +252,13 @@ pub fn op_webgpu_create_pipeline_layout( .try_borrow() .unwrap(); - let descriptor = wgc::binding_model::PipelineLayoutDescriptor { + let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::Owned), bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; // TODO - let (pipeline_layout, _) = wgc::gfx_select!(device => instance.device_create_pipeline_layout( + let (pipeline_layout, _) = gfx_select!(device => instance.device_create_pipeline_layout( device, &descriptor, std::marker::PhantomData @@ -309,7 +309,7 @@ pub fn op_webgpu_create_bind_group( let mut entries = vec![]; for entry in &args.entries { - let e = wgc::binding_model::BindGroupEntry { + let e = wgpu_core::binding_model::BindGroupEntry { binding: entry.binding, resource: match entry.kind.as_str() { "GPUSampler" => { @@ -317,14 +317,14 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(entry.resource) .ok_or_else(bad_resource_id)?; - wgc::binding_model::BindingResource::Sampler(sampler_resource.0) + wgpu_core::binding_model::BindingResource::Sampler(sampler_resource.0) } "GPUTextureView" => { let texture_view_resource = state .resource_table .get::(entry.resource) .ok_or_else(bad_resource_id)?; - wgc::binding_model::BindingResource::TextureView( + wgpu_core::binding_model::BindingResource::TextureView( texture_view_resource.0, ) } @@ -333,8 +333,8 @@ pub fn op_webgpu_create_bind_group( .resource_table .get::(entry.resource) .ok_or_else(bad_resource_id)?; - wgc::binding_model::BindingResource::Buffer( - wgc::binding_model::BufferBinding { + wgpu_core::binding_model::BindingResource::Buffer( + wgpu_core::binding_model::BufferBinding { buffer_id: buffer_resource.0, offset: entry.offset.unwrap_or(0), size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), @@ -352,7 +352,7 @@ pub fn op_webgpu_create_bind_group( .get::(args.layout) .ok_or_else(bad_resource_id)?; - let descriptor = wgc::binding_model::BindGroupDescriptor { + let descriptor = wgpu_core::binding_model::BindGroupDescriptor { label: args.label.map(Cow::Owned), layout: bind_group_layout.0, entries: Cow::Owned(entries), @@ -367,7 +367,7 @@ pub fn op_webgpu_create_bind_group( .unwrap(); // TODO - let (bind_group, _) = wgc::gfx_select!(device => instance.device_create_bind_group( + let (bind_group, _) = gfx_select!(device => instance.device_create_bind_group( device, &descriptor, std::marker::PhantomData diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 64c71141558fd4..922060eac47b14 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -16,7 +16,7 @@ use deno_core::OpState; use deno_core::{serde_json, RcRef, ZeroCopyBuf}; use deno_core::{BufVec, Resource}; -pub(crate) struct WebGPUBuffer(pub(crate) wgc::id::BufferId); +pub(crate) struct WebGPUBuffer(pub(crate) wgpu_core::id::BufferId); impl Resource for WebGPUBuffer { fn name(&self) -> Cow { "webGPUBuffer".into() @@ -61,15 +61,15 @@ pub fn op_webgpu_create_buffer( .try_borrow() .unwrap(); - let descriptor = wgc::resource::BufferDescriptor { + let descriptor = wgpu_core::resource::BufferDescriptor { label: args.label.map(Cow::Owned), size: args.size, - usage: wgt::BufferUsage::from_bits(args.usage).unwrap(), + usage: wgpu_types::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }; // TODO - let (buffer, _) = wgc::gfx_select!(device => instance.device_create_buffer( + let (buffer, _) = gfx_select!(device => instance.device_create_buffer( device, &descriptor, std::marker::PhantomData @@ -128,26 +128,26 @@ pub async fn op_webgpu_buffer_get_map_async( let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; extern "C" fn buffer_map_future_wrapper( - status: wgc::resource::BufferMapAsyncStatus, + status: wgpu_core::resource::BufferMapAsyncStatus, user_data: *mut u8, ) { let sender_ptr = user_data as *mut oneshot::Sender>; let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; boxed_sender .send(match status { - wgc::resource::BufferMapAsyncStatus::Success => Ok(()), + wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()), _ => unreachable!(), // TODO }) .unwrap(); } - wgc::gfx_select!(buffer => instance.buffer_map_async( + gfx_select!(buffer => instance.buffer_map_async( buffer, args.offset..(args.offset + args.size), - wgc::resource::BufferMapOperation { + wgpu_core::resource::BufferMapOperation { host: match args.mode { - 1 => wgc::device::HostMap::Read, - 2 => wgc::device::HostMap::Write, + 1 => wgpu_core::device::HostMap::Read, + 2 => wgpu_core::device::HostMap::Write, _ => unreachable!(), }, callback: buffer_map_future_wrapper, @@ -169,7 +169,7 @@ pub async fn op_webgpu_buffer_get_map_async( if let Some(instance_resource) = instance_resource { let instance = RcRef::map(&instance_resource, |r| &r.0).borrow().await; - wgc::gfx_select!(device.clone() => instance.device_poll(device, false)).unwrap() + gfx_select!(device.clone() => instance.device_poll(device, false)).unwrap() } else { break; } @@ -220,7 +220,7 @@ pub fn op_webgpu_buffer_get_mapped_range( .try_borrow() .unwrap(); - let slice_pointer = wgc::gfx_select!(buffer => instance.buffer_get_mapped_range( + let slice_pointer = gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, args.offset, std::num::NonZeroU64::new(args.size) @@ -277,7 +277,7 @@ pub fn op_webgpu_buffer_unmap( .borrow_mut() .copy_from_slice(&zero_copy[0]); - wgc::gfx_select!(buffer => instance.buffer_unmap(buffer))?; + gfx_select!(buffer => instance.buffer_unmap(buffer))?; Ok(json!({})) } diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index ec5a02917b8209..e8ed066f200ec2 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -13,14 +13,14 @@ use std::rc::Rc; use super::texture::serialize_texture_format; -struct WebGPURenderBundleEncoder(RefCell); +struct WebGPURenderBundleEncoder(RefCell); impl Resource for WebGPURenderBundleEncoder { fn name(&self) -> Cow { "webGPURenderBundleEncoder".into() } } -pub(crate) struct WebGPURenderBundle(pub(crate) wgc::id::RenderBundleId); +pub(crate) struct WebGPURenderBundle(pub(crate) wgpu_core::id::RenderBundleId); impl Resource for WebGPURenderBundle { fn name(&self) -> Cow { "webGPURenderBundle".into() @@ -56,7 +56,7 @@ pub fn op_webgpu_create_render_bundle_encoder( color_formats.push(serialize_texture_format(format)?); } - let descriptor = wgc::command::RenderBundleEncoderDescriptor { + let descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { label: args.label.map(Cow::Owned), color_formats: Cow::Owned(color_formats), depth_stencil_format: args @@ -66,7 +66,7 @@ pub fn op_webgpu_create_render_bundle_encoder( sample_count: args.sample_count.unwrap_or(1), }; let render_bundle_encoder = - wgc::command::RenderBundleEncoder::new(&descriptor, device, None)?; + wgpu_core::command::RenderBundleEncoder::new(&descriptor, device, None)?; let rid = state .resource_table @@ -112,9 +112,9 @@ pub fn op_webgpu_render_bundle_encoder_finish( .unwrap(); // TODO - let (render_bundle, _) = wgc::gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + let (render_bundle, _) = gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, - &wgc::command::RenderBundleDescriptor { + &wgpu_core::command::RenderBundleDescriptor { label: args.label.map(Cow::Owned), }, std::marker::PhantomData @@ -155,7 +155,7 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( &mut render_bundle_encoder_resource.0.borrow_mut(), args.index, bind_group_resource.0, @@ -197,7 +197,7 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); - wgc::command::bundle_ffi::wgpu_render_bundle_push_debug_group( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_push_debug_group( &mut render_bundle_encoder_resource.0.borrow_mut(), label.as_ptr(), ); @@ -226,7 +226,7 @@ pub fn op_webgpu_render_bundle_encoder_pop_debug_group( .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( &mut render_bundle_encoder_resource.0.borrow_mut(), ); } @@ -256,7 +256,7 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgc::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( &mut render_bundle_encoder_resource.0.borrow_mut(), label.as_ptr(), ); @@ -288,7 +288,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_set_pipeline( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline( &mut render_bundle_encoder_resource.0.borrow_mut(), render_pipeline_resource.0, ); @@ -360,7 +360,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( &mut render_bundle_encoder_resource.0.borrow_mut(), args.slot, buffer_resource.0, @@ -393,7 +393,7 @@ pub fn op_webgpu_render_bundle_encoder_draw( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_draw( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw( &mut render_bundle_encoder_resource.0.borrow_mut(), args.vertex_count, args.instance_count, @@ -427,7 +427,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_draw_indexed( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed( &mut render_bundle_encoder_resource.0.borrow_mut(), args.index_count, args.instance_count, @@ -463,7 +463,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - wgc::command::bundle_ffi::wgpu_render_bundle_draw_indirect( + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect( &mut render_bundle_encoder_resource.0.borrow_mut(), buffer_resource.0, args.indirect_offset, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index e1af0f3a770b40..cc863d782c9af7 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -10,24 +10,24 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; -pub(crate) struct WebGPUCommandEncoder(pub(crate) wgc::id::CommandEncoderId); +pub(crate) struct WebGPUCommandEncoder(pub(crate) wgpu_core::id::CommandEncoderId); impl Resource for WebGPUCommandEncoder { fn name(&self) -> Cow { "webGPUCommandEncoder".into() } } -pub(crate) struct WebGPUCommandBuffer(pub(crate) wgc::id::CommandBufferId); +pub(crate) struct WebGPUCommandBuffer(pub(crate) wgpu_core::id::CommandBufferId); impl Resource for WebGPUCommandBuffer { fn name(&self) -> Cow { "webGPUCommandBuffer".into() } } -fn serialize_store_op(store_op: String) -> wgc::command::StoreOp { +fn serialize_store_op(store_op: String) -> wgpu_core::command::StoreOp { match store_op.as_str() { - "store" => wgc::command::StoreOp::Store, - "clear" => wgc::command::StoreOp::Clear, + "store" => wgpu_core::command::StoreOp::Store, + "clear" => wgpu_core::command::StoreOp::Clear, _ => unreachable!(), } } @@ -61,12 +61,12 @@ pub fn op_webgpu_create_command_encoder( .try_borrow() .unwrap(); - let descriptor = wgt::CommandEncoderDescriptor { + let descriptor = wgpu_types::CommandEncoderDescriptor { label: args.label.map(Cow::Owned), }; // TODO - let (command_encoder, _) = wgc::gfx_select!(device => instance.device_create_command_encoder( + let (command_encoder, _) = gfx_select!(device => instance.device_create_command_encoder( device, &descriptor, std::marker::PhantomData @@ -135,7 +135,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .get::(color_attachment.view) .ok_or_else(bad_resource_id)?; - let attachment = wgc::command::ColorAttachmentDescriptor { + let attachment = wgpu_core::command::ColorAttachmentDescriptor { attachment: texture_view_resource.0, resolve_target: color_attachment .resolve_target @@ -148,22 +148,22 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .transpose()? .map(|texture| texture.0), channel: match color_attachment.load_op.as_str() { - "load" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Load, + "load" => wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Load, store_op: color_attachment .store_op - .map_or(wgc::command::StoreOp::Store, serialize_store_op), + .map_or(wgpu_core::command::StoreOp::Store, serialize_store_op), clear_value: Default::default(), read_only: false, }, "clear" => { let color = color_attachment.load_value.unwrap(); - wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, + wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Clear, store_op: color_attachment .store_op - .map_or(wgc::command::StoreOp::Store, serialize_store_op), - clear_value: wgt::Color { + .map_or(wgpu_core::command::StoreOp::Store, serialize_store_op), + clear_value: wgpu_types::Color { r: color.r, g: color.g, b: color.b, @@ -188,17 +188,17 @@ pub fn op_webgpu_command_encoder_begin_render_pass( .ok_or_else(bad_resource_id)?; depth_stencil_attachment = - Some(wgc::command::DepthStencilAttachmentDescriptor { + Some(wgpu_core::command::DepthStencilAttachmentDescriptor { attachment: texture_view_resource.0, depth: match attachment.depth_load_op.as_str() { - "load" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Load, + "load" => wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Load, store_op: serialize_store_op(attachment.depth_store_op), clear_value: 0.0, read_only: attachment.depth_read_only.unwrap_or(false), }, - "clear" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, + "clear" => wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Clear, store_op: serialize_store_op(attachment.depth_store_op), clear_value: attachment.depth_load_value.unwrap(), read_only: attachment.depth_read_only.unwrap_or(false), @@ -206,14 +206,14 @@ pub fn op_webgpu_command_encoder_begin_render_pass( _ => unreachable!(), }, stencil: match attachment.stencil_load_op.as_str() { - "load" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Load, + "load" => wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Load, store_op: serialize_store_op(attachment.stencil_store_op), clear_value: 0, read_only: attachment.stencil_read_only.unwrap_or(false), }, - "clear" => wgc::command::PassChannel { - load_op: wgc::command::LoadOp::Clear, + "clear" => wgpu_core::command::PassChannel { + load_op: wgpu_core::command::LoadOp::Clear, store_op: serialize_store_op(attachment.stencil_store_op), clear_value: attachment.stencil_load_value.unwrap(), read_only: attachment.stencil_read_only.unwrap_or(false), @@ -223,14 +223,14 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }); } - let descriptor = wgc::command::RenderPassDescriptor { + let descriptor = wgpu_core::command::RenderPassDescriptor { label: args.label.map(Cow::Owned), color_attachments: Cow::Owned(color_attachments), depth_stencil_attachment: depth_stencil_attachment.as_ref(), }; let render_pass = - wgc::command::RenderPass::new(command_encoder_resource.0, &descriptor); + wgpu_core::command::RenderPass::new(command_encoder_resource.0, &descriptor); let rid = state .resource_table @@ -262,12 +262,12 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; - let descriptor = wgc::command::ComputePassDescriptor { + let descriptor = wgpu_core::command::ComputePassDescriptor { label: args.label.map(Cow::Owned), }; let compute_pass = - wgc::command::ComputePass::new(command_encoder_resource.0, &descriptor); + wgpu_core::command::ComputePass::new(command_encoder_resource.0, &descriptor); let rid = state .resource_table @@ -323,7 +323,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .try_borrow() .unwrap(); - wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( + gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, source_buffer, args.source_offset, @@ -400,31 +400,31 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .try_borrow() .unwrap(); - let source = wgc::command::BufferCopyView { + let source = wgpu_core::command::BufferCopyView { buffer: source_buffer_resource.0, - layout: wgt::TextureDataLayout { + layout: wgpu_types::TextureDataLayout { offset: args.source.offset.unwrap_or(0), bytes_per_row: args.source.bytes_per_row.unwrap_or(0), rows_per_image: args.source.rows_per_image.unwrap_or(0), }, }; - let destination = wgc::command::TextureCopyView { + let destination = wgpu_core::command::TextureCopyView { texture: destination_texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination .origin - .map_or(Default::default(), |origin| wgt::Origin3d { + .map_or(Default::default(), |origin| wgpu_types::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), }), }; - wgc::gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_texture( + gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_texture( command_encoder, &source, &destination, - &wgt::Extent3d { + &wgpu_types::Extent3d { width: args.copy_size.width.unwrap_or(1), height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), @@ -473,30 +473,30 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .try_borrow() .unwrap(); - let source = wgc::command::TextureCopyView { + let source = wgpu_core::command::TextureCopyView { texture: source_texture_resource.0, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { + wgpu_types::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), } }), }; - let destination = wgc::command::BufferCopyView { + let destination = wgpu_core::command::BufferCopyView { buffer: destination_buffer_resource.0, - layout: wgt::TextureDataLayout { + layout: wgpu_types::TextureDataLayout { offset: args.destination.offset.unwrap_or(0), bytes_per_row: args.destination.bytes_per_row.unwrap_or(0), rows_per_image: args.destination.rows_per_image.unwrap_or(0), }, }; - wgc::gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_buffer( + gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_buffer( command_encoder, &source, &destination, - &wgt::Extent3d { + &wgpu_types::Extent3d { width: args.copy_size.width.unwrap_or(1), height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), @@ -545,34 +545,34 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .try_borrow() .unwrap(); - let source = wgc::command::TextureCopyView { + let source = wgpu_core::command::TextureCopyView { texture: source_texture_resource.0, mip_level: args.source.mip_level.unwrap_or(0), origin: args.source.origin.map_or(Default::default(), |origin| { - wgt::Origin3d { + wgpu_types::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), } }), }; - let destination = wgc::command::TextureCopyView { + let destination = wgpu_core::command::TextureCopyView { texture: destination_texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination .origin - .map_or(Default::default(), |origin| wgt::Origin3d { + .map_or(Default::default(), |origin| wgpu_types::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), }), }; - wgc::gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_texture( + gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_texture( command_encoder, &source, &destination, - &wgt::Extent3d { + &wgpu_types::Extent3d { width: args.copy_size.width.unwrap_or(1), height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), @@ -610,7 +610,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .try_borrow() .unwrap(); - wgc::gfx_select!(command_encoder => instance + gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; Ok(json!({})) @@ -643,7 +643,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .try_borrow() .unwrap(); - wgc::gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; + gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; Ok(json!({})) } @@ -676,7 +676,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .try_borrow() .unwrap(); - wgc::gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( + gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, &args.marker_label ))?; @@ -712,12 +712,12 @@ pub fn op_webgpu_command_encoder_finish( .try_borrow() .unwrap(); - let descriptor = wgt::CommandBufferDescriptor { + let descriptor = wgpu_types::CommandBufferDescriptor { label: args.label.map(Cow::Owned), }; // TODO - let (command_buffer, _) = wgc::gfx_select!(command_encoder => instance.command_encoder_finish( + let (command_buffer, _) = gfx_select!(command_encoder => instance.command_encoder_finish( command_encoder, &descriptor )); diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 97d414e4f541ca..b016141df6e4d2 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -11,7 +11,7 @@ use std::borrow::Cow; use std::cell::RefCell; pub(crate) struct WebGPUComputePass( - pub(crate) RefCell, + pub(crate) RefCell, ); impl Resource for WebGPUComputePass { fn name(&self) -> Cow { @@ -42,7 +42,7 @@ pub fn op_webgpu_compute_pass_set_pipeline( .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::compute_ffi::wgpu_compute_pass_set_pipeline( + wgpu_core::command::compute_ffi::wgpu_compute_pass_set_pipeline( &mut compute_pass_resource.0.borrow_mut(), compute_pipeline_resource.0, ); @@ -71,7 +71,7 @@ pub fn op_webgpu_compute_pass_dispatch( .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::compute_ffi::wgpu_compute_pass_dispatch( + wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch( &mut compute_pass_resource.0.borrow_mut(), args.x, args.y, @@ -105,7 +105,7 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( + wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( &mut compute_pass_resource.0.borrow_mut(), buffer_resource.0, args.indirect_offset, @@ -149,7 +149,7 @@ pub fn op_webgpu_compute_pass_end_pass( .ok_or_else(bad_resource_id)?; let compute_pass = &compute_pass_resource.0.borrow(); - wgc::gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( + gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( command_encoder, compute_pass ))?; @@ -185,7 +185,7 @@ pub fn op_webgpu_compute_pass_set_bind_group( .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::compute_ffi::wgpu_compute_pass_set_bind_group( + wgpu_core::command::compute_ffi::wgpu_compute_pass_set_bind_group( &mut compute_pass_resource.0.borrow_mut(), args.index, bind_group_resource.0, @@ -226,7 +226,7 @@ pub fn op_webgpu_compute_pass_push_debug_group( unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); - wgc::command::compute_ffi::wgpu_compute_pass_push_debug_group( + wgpu_core::command::compute_ffi::wgpu_compute_pass_push_debug_group( &mut compute_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 @@ -254,7 +254,7 @@ pub fn op_webgpu_compute_pass_pop_debug_group( .get::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::compute_ffi::wgpu_compute_pass_pop_debug_group( + wgpu_core::command::compute_ffi::wgpu_compute_pass_pop_debug_group( &mut compute_pass_resource.0.borrow_mut(), ); @@ -282,7 +282,7 @@ pub fn op_webgpu_compute_pass_insert_debug_marker( unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgc::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( + wgpu_core::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( &mut compute_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 4cb091f2364947..0e78a90afde68e 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -14,6 +14,27 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +#[macro_use] +mod macros { + macro_rules! gfx_select { + ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { + match $id.backend() { + #[cfg(all(not(target_arch = "wasm32"), any(not(any(target_os = "ios", target_os = "macos")), feature = "gfx-backend-vulkan")))] + wgpu_types::Backend::Vulkan => $global.$method::( $($param),* ), + #[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))] + wgpu_types::Backend::Metal => $global.$method::( $($param),* ), + #[cfg(all(not(target_arch = "wasm32"), windows))] + wgpu_types::Backend::Dx12 => $global.$method::( $($param),* ), + #[cfg(all(not(target_arch = "wasm32"), windows))] + wgpu_types::Backend::Dx11 => $global.$method::( $($param),* ), + #[cfg(any(target_arch = "wasm32", all(unix, not(any(target_os = "ios", target_os = "macos")))))] + wgpu_types::Backend::Gl => $global.$method::( $($param),+ ), + other => panic!("Unexpected backend {:?}", other), + } + }; + } +} + pub mod binding; pub mod buffer; pub mod bundle; @@ -27,7 +48,7 @@ pub mod shader; pub mod texture; struct WebGPUInstance( - AsyncRefCell>, + AsyncRefCell>, ); impl Resource for WebGPUInstance { fn name(&self) -> Cow { @@ -35,14 +56,14 @@ impl Resource for WebGPUInstance { } } -struct WebGPUAdapter(wgc::id::AdapterId); +struct WebGPUAdapter(wgpu_core::id::AdapterId); impl Resource for WebGPUAdapter { fn name(&self) -> Cow { "webGPUAdapter".into() } } -struct WebGPUDevice(wgc::id::DeviceId); +struct WebGPUDevice(wgpu_core::id::DeviceId); impl Resource for WebGPUDevice { fn name(&self) -> Cow { "webGPUDevice".into() @@ -60,13 +81,13 @@ pub fn init(isolate: &mut deno_core::JsRuntime) { } } -fn deserialize_features(features: &wgt::Features) -> Vec<&str> { +fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { let mut return_features: Vec<&str> = vec![]; - if features.contains(wgt::Features::DEPTH_CLAMPING) { + if features.contains(wgpu_types::Features::DEPTH_CLAMPING) { return_features.push("depth-clamping"); } - if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) { + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { return_features.push("texture-compression-bc"); } @@ -78,10 +99,10 @@ pub fn op_webgpu_create_instance( _args: Value, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let instance = wgc::hub::Global::new( + let instance = wgpu_core::hub::Global::new( "webgpu", - wgc::hub::IdentityManagerFactory, - wgt::BackendBit::PRIMARY, + wgpu_core::hub::IdentityManagerFactory, + wgpu_types::BackendBit::PRIMARY, ); let rid = state @@ -114,11 +135,11 @@ pub async fn op_webgpu_request_adapter( .ok_or_else(bad_resource_id)?; let instance = &RcRef::map(&instance_resource, |r| &r.0).borrow().await; - let descriptor = wgc::instance::RequestAdapterOptions { + let descriptor = wgpu_core::instance::RequestAdapterOptions { power_preference: match args.power_preference { Some(power_preference) => match power_preference.as_str() { - "low-power" => wgt::PowerPreference::LowPower, - "high-performance" => wgt::PowerPreference::HighPerformance, + "low-power" => wgpu_types::PowerPreference::LowPower, + "high-performance" => wgpu_types::PowerPreference::HighPerformance, _ => unreachable!(), }, None => Default::default(), @@ -127,18 +148,18 @@ pub async fn op_webgpu_request_adapter( }; let adapter = instance.request_adapter( &descriptor, - wgc::instance::AdapterInputs::Mask(wgt::BackendBit::PRIMARY, |_| { + wgpu_core::instance::AdapterInputs::Mask(wgpu_types::BackendBit::PRIMARY, |_| { std::marker::PhantomData }), )?; let name = - wgc::gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; + gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; let adapter_features = - wgc::gfx_select!(adapter => instance.adapter_features(adapter))?; + gfx_select!(adapter => instance.adapter_features(adapter))?; let features = deserialize_features(&adapter_features); let adapter_limits = - wgc::gfx_select!(adapter => instance.adapter_limits(adapter))?; + gfx_select!(adapter => instance.adapter_limits(adapter))?; let limits = json!({ "maxBindGroups": adapter_limits.max_bind_groups, @@ -207,24 +228,24 @@ pub async fn op_webgpu_request_device( .try_borrow() .unwrap(); - let mut features = wgt::Features::default(); + let mut features = wgpu_types::Features::default(); if let Some(passed_features) = args.non_guaranteed_features { if passed_features.contains(&"depth-clamping".to_string()) { - features.set(wgt::Features::DEPTH_CLAMPING, true); + features.set(wgpu_types::Features::DEPTH_CLAMPING, true); } if passed_features.contains(&"texture-compression-bc".to_string()) { - features.set(wgt::Features::TEXTURE_COMPRESSION_BC, true); + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true); } // TODO } - let descriptor = wgt::DeviceDescriptor { + let descriptor = wgpu_types::DeviceDescriptor { label: args.label.map(Cow::Owned), features, limits: args .non_guaranteed_limits - .map_or(Default::default(), |limits| wgt::Limits { + .map_or(Default::default(), |limits| wgpu_types::Limits { max_bind_groups: limits.max_bind_groups.unwrap_or(4), max_dynamic_uniform_buffers_per_pipeline_layout: limits .max_dynamic_uniform_buffers_per_pipeline_layout @@ -254,7 +275,7 @@ pub async fn op_webgpu_request_device( }), }; // TODO - let (device, _) = wgc::gfx_select!(adapter => instance.adapter_request_device( + let (device, _) = gfx_select!(adapter => instance.adapter_request_device( adapter, &descriptor, None, @@ -262,9 +283,9 @@ pub async fn op_webgpu_request_device( )); let device_features = - wgc::gfx_select!(device => instance.device_features(device))?; + gfx_select!(device => instance.device_features(device))?; let features = deserialize_features(&device_features); - let limits = wgc::gfx_select!(device => instance.device_limits(device))?; + let limits = gfx_select!(device => instance.device_limits(device))?; let json_limits = json!({ "max_bind_groups": limits.max_bind_groups, "max_dynamic_uniform_buffers_per_pipeline_layout": limits.max_dynamic_uniform_buffers_per_pipeline_layout, diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 052fc70df25265..9da2040fbae1a0 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -13,121 +13,121 @@ use super::sampler::serialize_compare_function; use super::texture::serialize_texture_format; use crate::shader::WebGPUShaderModule; -pub(crate) struct WebGPUPipelineLayout(pub(crate) wgc::id::PipelineLayoutId); +pub(crate) struct WebGPUPipelineLayout(pub(crate) wgpu_core::id::PipelineLayoutId); impl Resource for WebGPUPipelineLayout { fn name(&self) -> Cow { "webGPUPipelineLayout".into() } } -pub(crate) struct WebGPUComputePipeline(pub(crate) wgc::id::ComputePipelineId); +pub(crate) struct WebGPUComputePipeline(pub(crate) wgpu_core::id::ComputePipelineId); impl Resource for WebGPUComputePipeline { fn name(&self) -> Cow { "webGPUComputePipeline".into() } } -pub(crate) struct WebGPURenderPipeline(pub(crate) wgc::id::RenderPipelineId); +pub(crate) struct WebGPURenderPipeline(pub(crate) wgpu_core::id::RenderPipelineId); impl Resource for WebGPURenderPipeline { fn name(&self) -> Cow { "webGPURenderPipeline".into() } } -pub fn serialize_index_format(format: String) -> wgt::IndexFormat { +pub fn serialize_index_format(format: String) -> wgpu_types::IndexFormat { match format.as_str() { - "uint16" => wgt::IndexFormat::Uint16, - "uint32" => wgt::IndexFormat::Uint32, + "uint16" => wgpu_types::IndexFormat::Uint16, + "uint32" => wgpu_types::IndexFormat::Uint32, _ => unreachable!(), } } -fn serialize_stencil_operation(operation: &str) -> wgt::StencilOperation { +fn serialize_stencil_operation(operation: &str) -> wgpu_types::StencilOperation { match operation { - "keep" => wgt::StencilOperation::Keep, - "zero" => wgt::StencilOperation::Zero, - "replace" => wgt::StencilOperation::Replace, - "invert" => wgt::StencilOperation::Invert, - "increment-clamp" => wgt::StencilOperation::IncrementClamp, - "decrement-clamp" => wgt::StencilOperation::DecrementClamp, - "increment-wrap" => wgt::StencilOperation::IncrementWrap, - "decrement-wrap" => wgt::StencilOperation::DecrementWrap, + "keep" => wgpu_types::StencilOperation::Keep, + "zero" => wgpu_types::StencilOperation::Zero, + "replace" => wgpu_types::StencilOperation::Replace, + "invert" => wgpu_types::StencilOperation::Invert, + "increment-clamp" => wgpu_types::StencilOperation::IncrementClamp, + "decrement-clamp" => wgpu_types::StencilOperation::DecrementClamp, + "increment-wrap" => wgpu_types::StencilOperation::IncrementWrap, + "decrement-wrap" => wgpu_types::StencilOperation::DecrementWrap, _ => unreachable!(), } } -fn serialize_stencil_face_state(state: GPUStencilFaceState) -> wgt::StencilFaceState { - wgt::StencilFaceState { +fn serialize_stencil_face_state(state: GPUStencilFaceState) -> wgpu_types::StencilFaceState { + wgpu_types::StencilFaceState { compare: state .compare .as_ref() - .map_or(wgt::CompareFunction::Always, |op| { + .map_or(wgpu_types::CompareFunction::Always, |op| { serialize_compare_function(op) }), fail_op: state .fail_op .as_ref() - .map_or(wgt::StencilOperation::Keep, |op| { + .map_or(wgpu_types::StencilOperation::Keep, |op| { serialize_stencil_operation(op) }), depth_fail_op: state .depth_fail_op .as_ref() - .map_or(wgt::StencilOperation::Keep, |op| { + .map_or(wgpu_types::StencilOperation::Keep, |op| { serialize_stencil_operation(op) }), pass_op: state .pass_op .as_ref() - .map_or(wgt::StencilOperation::Keep, |op| { + .map_or(wgpu_types::StencilOperation::Keep, |op| { serialize_stencil_operation(op) }), } } -fn serialize_blend_factor(blend_factor: &str) -> wgt::BlendFactor { +fn serialize_blend_factor(blend_factor: &str) -> wgpu_types::BlendFactor { match blend_factor { - "zero" => wgt::BlendFactor::Zero, - "one" => wgt::BlendFactor::One, - "src-color" => wgt::BlendFactor::SrcColor, - "one-minus-src-color" => wgt::BlendFactor::OneMinusSrcColor, - "src-alpha" => wgt::BlendFactor::SrcAlpha, - "one-minus-src-alpha" => wgt::BlendFactor::OneMinusSrcAlpha, - "dst-color" => wgt::BlendFactor::DstColor, - "one-minus-dst-color" => wgt::BlendFactor::OneMinusDstColor, - "dst-alpha" => wgt::BlendFactor::DstAlpha, - "one-minus-dst-alpha" => wgt::BlendFactor::OneMinusDstAlpha, - "src-alpha-saturated" => wgt::BlendFactor::SrcAlphaSaturated, - "blend-color" => wgt::BlendFactor::BlendColor, - "one-minus-blend-color" => wgt::BlendFactor::OneMinusBlendColor, + "zero" => wgpu_types::BlendFactor::Zero, + "one" => wgpu_types::BlendFactor::One, + "src-color" => wgpu_types::BlendFactor::SrcColor, + "one-minus-src-color" => wgpu_types::BlendFactor::OneMinusSrcColor, + "src-alpha" => wgpu_types::BlendFactor::SrcAlpha, + "one-minus-src-alpha" => wgpu_types::BlendFactor::OneMinusSrcAlpha, + "dst-color" => wgpu_types::BlendFactor::DstColor, + "one-minus-dst-color" => wgpu_types::BlendFactor::OneMinusDstColor, + "dst-alpha" => wgpu_types::BlendFactor::DstAlpha, + "one-minus-dst-alpha" => wgpu_types::BlendFactor::OneMinusDstAlpha, + "src-alpha-saturated" => wgpu_types::BlendFactor::SrcAlphaSaturated, + "blend-color" => wgpu_types::BlendFactor::BlendColor, + "one-minus-blend-color" => wgpu_types::BlendFactor::OneMinusBlendColor, _ => unreachable!(), } } -fn serialize_blend_component(blend: GPUBlendComponent) -> wgt::BlendState { - wgt::BlendState { +fn serialize_blend_component(blend: GPUBlendComponent) -> wgpu_types::BlendState { + wgpu_types::BlendState { src_factor: blend .src_factor .as_ref() - .map_or(wgt::BlendFactor::One, |factor| { + .map_or(wgpu_types::BlendFactor::One, |factor| { serialize_blend_factor(factor) }), dst_factor: blend .dst_factor .as_ref() - .map_or(wgt::BlendFactor::Zero, |factor| { + .map_or(wgpu_types::BlendFactor::Zero, |factor| { serialize_blend_factor(factor) }), operation: match &blend.operation { Some(operation) => match operation.as_str() { - "add" => wgt::BlendOperation::Add, - "subtract" => wgt::BlendOperation::Subtract, - "reverse-subtract" => wgt::BlendOperation::ReverseSubtract, - "min" => wgt::BlendOperation::Min, - "max" => wgt::BlendOperation::Max, + "add" => wgpu_types::BlendOperation::Add, + "subtract" => wgpu_types::BlendOperation::Subtract, + "reverse-subtract" => wgpu_types::BlendOperation::ReverseSubtract, + "min" => wgpu_types::BlendOperation::Min, + "max" => wgpu_types::BlendOperation::Max, _ => unreachable!(), }, - None => wgt::BlendOperation::Add, + None => wgpu_types::BlendOperation::Add, }, } } @@ -184,24 +184,24 @@ pub fn op_webgpu_create_compute_pipeline( .get::(args.compute.module) .ok_or_else(bad_resource_id)?; - let descriptor = wgc::pipeline::ComputePipelineDescriptor { + let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { label: args.label.map(Cow::Owned), layout: pipeline_layout, - stage: wgc::pipeline::ProgrammableStageDescriptor { + stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: compute_shader_module_resource.0, entry_point: Cow::Owned(args.compute.entry_point) }, }; let implicit_pipelines = match args.layout { Some(_) => None, - None => Some(wgc::device::ImplicitPipelineIds { + None => Some(wgpu_core::device::ImplicitPipelineIds { root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + group_ids: &[std::marker::PhantomData; wgpu_core::MAX_BIND_GROUPS], }), }; // TODO - let (compute_pipeline, _, _) = wgc::gfx_select!(device => instance.device_create_compute_pipeline( + let (compute_pipeline, _, _) = gfx_select!(device => instance.device_create_compute_pipeline( device, &descriptor, std::marker::PhantomData, @@ -247,7 +247,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .unwrap(); // TODO - let (bind_group_layout, _) = wgc::gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); + let (bind_group_layout, _) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); let rid = state .resource_table @@ -404,11 +404,11 @@ pub fn op_webgpu_create_render_pipeline( .get::(args.vertex.module) .ok_or_else(bad_resource_id)?; - let descriptor = wgc::pipeline::RenderPipelineDescriptor { + let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { label: args.label.map(Cow::Owned), layout, - vertex: wgc::pipeline::VertexState { - stage: wgc::pipeline::ProgrammableStageDescriptor { + vertex: wgpu_core::pipeline::VertexState { + stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: vertex_shader_module_resource.0, entry_point: Cow::Owned(args.vertex.entry_point), }, @@ -416,52 +416,52 @@ pub fn op_webgpu_create_render_pipeline( let mut return_buffers = vec![]; for buffer in buffers { if let Some(buffer) = buffer { - return_buffers.push(wgc::pipeline::VertexBufferLayout { + return_buffers.push(wgpu_core::pipeline::VertexBufferLayout { array_stride: buffer.array_stride, step_mode: match buffer.step_mode { Some(step_mode) => match step_mode.as_str() { - "vertex" => wgt::InputStepMode::Vertex, - "instance" => wgt::InputStepMode::Instance, + "vertex" => wgpu_types::InputStepMode::Vertex, + "instance" => wgpu_types::InputStepMode::Instance, _ => unreachable!(), }, - None => wgt::InputStepMode::Vertex, + None => wgpu_types::InputStepMode::Vertex, }, attributes: Cow::Owned( buffer .attributes .iter() - .map(|attribute| wgt::VertexAttribute { + .map(|attribute| wgpu_types::VertexAttribute { format: match attribute.format.as_str() { - "uchar2" => wgt::VertexFormat::Uchar2, - "uchar4" => wgt::VertexFormat::Uchar4, - "char2" => wgt::VertexFormat::Char2, - "char4" => wgt::VertexFormat::Char4, - "uchar2norm" => wgt::VertexFormat::Uchar2Norm, - "uchar4norm" => wgt::VertexFormat::Uchar4, - "char2norm" => wgt::VertexFormat::Char2Norm, - "char4norm" => wgt::VertexFormat::Char4Norm, - "ushort2" => wgt::VertexFormat::Ushort2, - "ushort4" => wgt::VertexFormat::Ushort4, - "short2" => wgt::VertexFormat::Short2, - "short4" => wgt::VertexFormat::Short4, - "ushort2norm" => wgt::VertexFormat::Ushort2Norm, - "ushort4norm" => wgt::VertexFormat::Ushort4Norm, - "short2norm" => wgt::VertexFormat::Short2Norm, - "short4norm" => wgt::VertexFormat::Short4Norm, - "half2" => wgt::VertexFormat::Half2, - "half4" => wgt::VertexFormat::Half4, - "float" => wgt::VertexFormat::Float, - "float2" => wgt::VertexFormat::Float2, - "float3" => wgt::VertexFormat::Float3, - "float4" => wgt::VertexFormat::Float4, - "uint" => wgt::VertexFormat::Uint, - "uint2" => wgt::VertexFormat::Uint2, - "uint3" => wgt::VertexFormat::Uint3, - "uint4" => wgt::VertexFormat::Uint4, - "int" => wgt::VertexFormat::Int, - "int2" => wgt::VertexFormat::Int2, - "int3" => wgt::VertexFormat::Int3, - "int4" => wgt::VertexFormat::Int4, + "uchar2" => wgpu_types::VertexFormat::Uchar2, + "uchar4" => wgpu_types::VertexFormat::Uchar4, + "char2" => wgpu_types::VertexFormat::Char2, + "char4" => wgpu_types::VertexFormat::Char4, + "uchar2norm" => wgpu_types::VertexFormat::Uchar2Norm, + "uchar4norm" => wgpu_types::VertexFormat::Uchar4, + "char2norm" => wgpu_types::VertexFormat::Char2Norm, + "char4norm" => wgpu_types::VertexFormat::Char4Norm, + "ushort2" => wgpu_types::VertexFormat::Ushort2, + "ushort4" => wgpu_types::VertexFormat::Ushort4, + "short2" => wgpu_types::VertexFormat::Short2, + "short4" => wgpu_types::VertexFormat::Short4, + "ushort2norm" => wgpu_types::VertexFormat::Ushort2Norm, + "ushort4norm" => wgpu_types::VertexFormat::Ushort4Norm, + "short2norm" => wgpu_types::VertexFormat::Short2Norm, + "short4norm" => wgpu_types::VertexFormat::Short4Norm, + "half2" => wgpu_types::VertexFormat::Half2, + "half4" => wgpu_types::VertexFormat::Half4, + "float" => wgpu_types::VertexFormat::Float, + "float2" => wgpu_types::VertexFormat::Float2, + "float3" => wgpu_types::VertexFormat::Float3, + "float4" => wgpu_types::VertexFormat::Float4, + "uint" => wgpu_types::VertexFormat::Uint, + "uint2" => wgpu_types::VertexFormat::Uint2, + "uint3" => wgpu_types::VertexFormat::Uint3, + "uint4" => wgpu_types::VertexFormat::Uint4, + "int" => wgpu_types::VertexFormat::Int, + "int2" => wgpu_types::VertexFormat::Int2, + "int3" => wgpu_types::VertexFormat::Int3, + "int4" => wgpu_types::VertexFormat::Int4, _ => unreachable!(), }, offset: attribute.offset, @@ -479,41 +479,41 @@ pub fn op_webgpu_create_render_pipeline( }, primitive: args.primitive.map_or(Default::default(), |primitive| { // TODO - wgt::PrimitiveState { + wgpu_types::PrimitiveState { topology: match primitive.topology { Some(topology) => match topology.as_str() { - "point-list" => wgt::PrimitiveTopology::PointList, - "line-list" => wgt::PrimitiveTopology::LineList, - "line-strip" => wgt::PrimitiveTopology::LineStrip, - "triangle-list" => wgt::PrimitiveTopology::TriangleList, - "triangle-strip" => wgt::PrimitiveTopology::TriangleStrip, + "point-list" => wgpu_types::PrimitiveTopology::PointList, + "line-list" => wgpu_types::PrimitiveTopology::LineList, + "line-strip" => wgpu_types::PrimitiveTopology::LineStrip, + "triangle-list" => wgpu_types::PrimitiveTopology::TriangleList, + "triangle-strip" => wgpu_types::PrimitiveTopology::TriangleStrip, _ => unreachable!(), }, - None => wgt::PrimitiveTopology::TriangleList, + None => wgpu_types::PrimitiveTopology::TriangleList, }, strip_index_format: primitive.strip_index_format.map(serialize_index_format), front_face: match primitive.front_face { Some(front_face) => match front_face.as_str() { - "ccw" => wgt::FrontFace::Ccw, - "cw" => wgt::FrontFace::Cw, + "ccw" => wgpu_types::FrontFace::Ccw, + "cw" => wgpu_types::FrontFace::Cw, _ => unreachable!(), }, - None => wgt::FrontFace::Ccw, + None => wgpu_types::FrontFace::Ccw, }, cull_mode: match primitive.cull_mode { Some(cull_mode) => match cull_mode.as_str() { - "none" => wgt::CullMode::None, - "front" => wgt::CullMode::Front, - "back" => wgt::CullMode::Back, + "none" => wgpu_types::CullMode::None, + "front" => wgpu_types::CullMode::Front, + "back" => wgpu_types::CullMode::Back, _ => unreachable!(), }, - None => wgt::CullMode::None, + None => wgpu_types::CullMode::None, }, polygon_mode: Default::default(), // native-only } }), depth_stencil: args.depth_stencil.map(|depth_stencil| { - wgt::DepthStencilState { + wgpu_types::DepthStencilState { format: super::texture::serialize_texture_format(&depth_stencil.format) .unwrap(), depth_write_enabled: depth_stencil.depth_write_enabled.unwrap_or(false), @@ -521,9 +521,9 @@ pub fn op_webgpu_create_render_pipeline( Some(depth_compare) => { super::sampler::serialize_compare_function(&depth_compare) } - None => wgt::CompareFunction::Always, + None => wgpu_types::CompareFunction::Always, }, - stencil: wgt::StencilState { + stencil: wgpu_types::StencilState { front: depth_stencil .stencil_front .map_or(Default::default(), serialize_stencil_face_state), @@ -533,7 +533,7 @@ pub fn op_webgpu_create_render_pipeline( read_mask: depth_stencil.stencil_read_mask.unwrap_or(0xFFFFFFFF), write_mask: depth_stencil.stencil_write_mask.unwrap_or(0xFFFFFFFF), }, - bias: wgt::DepthBiasState { + bias: wgpu_types::DepthBiasState { constant: depth_stencil.depth_bias.unwrap_or(0), slope_scale: depth_stencil.depth_bias_slope_scale.unwrap_or(0.0), clamp: depth_stencil.depth_bias_clamp.unwrap_or(0.0), @@ -542,7 +542,7 @@ pub fn op_webgpu_create_render_pipeline( } }), multisample: args.multisample.map_or(Default::default(), |multisample| { - wgt::MultisampleState { + wgpu_types::MultisampleState { // TODO count: multisample.count.unwrap_or(1), mask: multisample.mask.unwrap_or(0xFFFFFFFF), @@ -558,8 +558,8 @@ pub fn op_webgpu_create_render_pipeline( .ok_or_else(bad_resource_id) .unwrap(); // TODO - wgc::pipeline::FragmentState { - stage: wgc::pipeline::ProgrammableStageDescriptor { + wgpu_core::pipeline::FragmentState { + stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: fragment_shader_module_resource.0, entry_point: Cow::Owned(fragment.entry_point), }, @@ -575,7 +575,7 @@ pub fn op_webgpu_create_render_pipeline( ) }); - wgt::ColorTargetState { + wgpu_types::ColorTargetState { format: serialize_texture_format(&target.format).unwrap(), alpha_blend: blends.clone() .map_or(Default::default(), |states| states.0), @@ -584,7 +584,7 @@ pub fn op_webgpu_create_render_pipeline( write_mask: target .write_mask .map_or(Default::default(), |mask| { - wgt::ColorWrite::from_bits(mask).unwrap() + wgpu_types::ColorWrite::from_bits(mask).unwrap() }), } }) @@ -596,14 +596,14 @@ pub fn op_webgpu_create_render_pipeline( let implicit_pipelines = match args.layout { Some(_) => None, - None => Some(wgc::device::ImplicitPipelineIds { + None => Some(wgpu_core::device::ImplicitPipelineIds { root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgc::MAX_BIND_GROUPS], + group_ids: &[std::marker::PhantomData; wgpu_core::MAX_BIND_GROUPS], }), }; // TODO - let (render_pipeline, _, _) = wgc::gfx_select!(device => instance.device_create_render_pipeline( + let (render_pipeline, _, _) = gfx_select!(device => instance.device_create_render_pipeline( device, &descriptor, std::marker::PhantomData, @@ -649,7 +649,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .unwrap(); // TODO - let (bind_group_layout, _) = wgc::gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); + let (bind_group_layout, _) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); let rid = state .resource_table diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index 804b0bd7b9973e..e6fef642530da5 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -48,7 +48,7 @@ pub fn op_webgpu_queue_submit( ids.push(buffer_resource.0); } - wgc::gfx_select!(queue => instance.queue_submit(queue, &ids))?; + gfx_select!(queue => instance.queue_submit(queue, &ids))?; Ok(json!({})) } @@ -101,7 +101,7 @@ pub fn op_webgpu_write_buffer( Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], None => &zero_copy[0][args.data_offset..], }; - wgc::gfx_select!(queue => instance.queue_write_buffer( + gfx_select!(queue => instance.queue_write_buffer( queue, buffer, args.buffer_offset, @@ -145,30 +145,30 @@ pub fn op_webgpu_write_texture( .try_borrow() .unwrap(); - let destination = wgc::command::TextureCopyView { + let destination = wgpu_core::command::TextureCopyView { texture: texture_resource.0, mip_level: args.destination.mip_level.unwrap_or(0), origin: args .destination .origin - .map_or(Default::default(), |origin| wgt::Origin3d { + .map_or(Default::default(), |origin| wgpu_types::Origin3d { x: origin.x.unwrap_or(0), y: origin.y.unwrap_or(0), z: origin.z.unwrap_or(0), }), }; - let data_layout = wgt::TextureDataLayout { + let data_layout = wgpu_types::TextureDataLayout { offset: args.data_layout.offset.unwrap_or(0), bytes_per_row: args.data_layout.bytes_per_row.unwrap_or(0), rows_per_image: args.data_layout.rows_per_image.unwrap_or(0), }; - wgc::gfx_select!(queue => instance.queue_write_texture( + gfx_select!(queue => instance.queue_write_texture( queue, &destination, &*zero_copy[0], &data_layout, - &wgt::Extent3d { + &wgpu_types::Extent3d { width: args.size.width.unwrap_or(1), height: args.size.height.unwrap_or(1), depth: args.size.depth.unwrap_or(1), diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 5ae962a9470d66..b9f22127f1e2aa 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -11,7 +11,7 @@ use std::borrow::Cow; use std::cell::RefCell; pub(crate) struct WebGPURenderPass( - pub(crate) RefCell, + pub(crate) RefCell, ); impl Resource for WebGPURenderPass { fn name(&self) -> Cow { @@ -43,7 +43,7 @@ pub fn op_webgpu_render_pass_set_viewport( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_viewport( + wgpu_core::command::render_ffi::wgpu_render_pass_set_viewport( &mut render_pass_resource.0.borrow_mut(), args.x, args.y, @@ -78,7 +78,7 @@ pub fn op_webgpu_render_pass_set_scissor_rect( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_scissor_rect( + wgpu_core::command::render_ffi::wgpu_render_pass_set_scissor_rect( &mut render_pass_resource.0.borrow_mut(), args.x, args.y, @@ -117,9 +117,9 @@ pub fn op_webgpu_render_pass_set_blend_color( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_blend_color( + wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_color( &mut render_pass_resource.0.borrow_mut(), - &wgt::Color { + &wgpu_types::Color { r: args.color.r, g: args.color.g, b: args.color.b, @@ -149,7 +149,7 @@ pub fn op_webgpu_render_pass_set_stencil_reference( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_stencil_reference( + wgpu_core::command::render_ffi::wgpu_render_pass_set_stencil_reference( &mut render_pass_resource.0.borrow_mut(), args.reference, ); @@ -187,7 +187,7 @@ pub fn op_webgpu_render_pass_execute_bundles( .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::render_ffi::wgpu_render_pass_execute_bundles( + wgpu_core::command::render_ffi::wgpu_render_pass_execute_bundles( &mut render_pass_resource.0.borrow_mut(), render_bundle_ids.as_ptr(), args.bundles.len(), @@ -231,7 +231,7 @@ pub fn op_webgpu_render_pass_end_pass( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; let render_pass = &render_pass_resource.0.borrow(); - wgc::gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; + gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; Ok(json!({})) } @@ -264,7 +264,7 @@ pub fn op_webgpu_render_pass_set_bind_group( .ok_or_else(bad_resource_id)?; unsafe { - wgc::command::render_ffi::wgpu_render_pass_set_bind_group( + wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( &mut render_pass_resource.0.borrow_mut(), args.index, bind_group_resource.0, @@ -305,7 +305,7 @@ pub fn op_webgpu_render_pass_push_debug_group( unsafe { let label = std::ffi::CString::new(args.group_label).unwrap(); - wgc::command::render_ffi::wgpu_render_pass_push_debug_group( + wgpu_core::command::render_ffi::wgpu_render_pass_push_debug_group( &mut render_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 @@ -333,7 +333,7 @@ pub fn op_webgpu_render_pass_pop_debug_group( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_pop_debug_group( + wgpu_core::command::render_ffi::wgpu_render_pass_pop_debug_group( &mut render_pass_resource.0.borrow_mut(), ); @@ -361,7 +361,7 @@ pub fn op_webgpu_render_pass_insert_debug_marker( unsafe { let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgc::command::render_ffi::wgpu_render_pass_insert_debug_marker( + wgpu_core::command::render_ffi::wgpu_render_pass_insert_debug_marker( &mut render_pass_resource.0.borrow_mut(), label.as_ptr(), 0, // wgpu#975 @@ -394,7 +394,7 @@ pub fn op_webgpu_render_pass_set_pipeline( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_pipeline( + wgpu_core::command::render_ffi::wgpu_render_pass_set_pipeline( &mut render_pass_resource.0.borrow_mut(), render_pipeline_resource.0, ); @@ -464,7 +464,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_set_vertex_buffer( + wgpu_core::command::render_ffi::wgpu_render_pass_set_vertex_buffer( &mut render_pass_resource.0.borrow_mut(), args.slot, buffer_resource.0, @@ -497,7 +497,7 @@ pub fn op_webgpu_render_pass_draw( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_draw( + wgpu_core::command::render_ffi::wgpu_render_pass_draw( &mut render_pass_resource.0.borrow_mut(), args.vertex_count, args.instance_count, @@ -531,7 +531,7 @@ pub fn op_webgpu_render_pass_draw_indexed( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_draw_indexed( + wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed( &mut render_pass_resource.0.borrow_mut(), args.index_count, args.instance_count, @@ -567,7 +567,7 @@ pub fn op_webgpu_render_pass_draw_indirect( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_draw_indirect( + wgpu_core::command::render_ffi::wgpu_render_pass_draw_indirect( &mut render_pass_resource.0.borrow_mut(), buffer_resource.0, args.indirect_offset, @@ -600,7 +600,7 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - wgc::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( + wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( &mut render_pass_resource.0.borrow_mut(), buffer_resource.0, args.indirect_offset, diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index bddb8813b1bb15..8088c208716629 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -9,46 +9,46 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -pub(crate) struct WebGPUSampler(pub(crate) wgc::id::SamplerId); +pub(crate) struct WebGPUSampler(pub(crate) wgpu_core::id::SamplerId); impl Resource for WebGPUSampler { fn name(&self) -> Cow { "webGPUSampler".into() } } -fn serialize_address_mode(address_mode: Option) -> wgt::AddressMode { +fn serialize_address_mode(address_mode: Option) -> wgpu_types::AddressMode { match address_mode { Some(address_mode) => match address_mode.as_str() { - "clamp-to-edge" => wgt::AddressMode::ClampToEdge, - "repeat" => wgt::AddressMode::Repeat, - "mirror-repeat" => wgt::AddressMode::MirrorRepeat, + "clamp-to-edge" => wgpu_types::AddressMode::ClampToEdge, + "repeat" => wgpu_types::AddressMode::Repeat, + "mirror-repeat" => wgpu_types::AddressMode::MirrorRepeat, _ => unreachable!(), }, - None => wgt::AddressMode::ClampToEdge, + None => wgpu_types::AddressMode::ClampToEdge, } } -fn serialize_filter_mode(filter_mode: Option) -> wgt::FilterMode { +fn serialize_filter_mode(filter_mode: Option) -> wgpu_types::FilterMode { match filter_mode { Some(filter_mode) => match filter_mode.as_str() { - "nearest" => wgt::FilterMode::Nearest, - "linear" => wgt::FilterMode::Linear, + "nearest" => wgpu_types::FilterMode::Nearest, + "linear" => wgpu_types::FilterMode::Linear, _ => unreachable!(), }, - None => wgt::FilterMode::Nearest, + None => wgpu_types::FilterMode::Nearest, } } -pub fn serialize_compare_function(compare: &str) -> wgt::CompareFunction { +pub fn serialize_compare_function(compare: &str) -> wgpu_types::CompareFunction { match compare { - "never" => wgt::CompareFunction::Never, - "less" => wgt::CompareFunction::Less, - "equal" => wgt::CompareFunction::Equal, - "less-equal" => wgt::CompareFunction::LessEqual, - "greater" => wgt::CompareFunction::Greater, - "not-equal" => wgt::CompareFunction::NotEqual, - "greater-equal" => wgt::CompareFunction::GreaterEqual, - "always" => wgt::CompareFunction::Always, + "never" => wgpu_types::CompareFunction::Never, + "less" => wgpu_types::CompareFunction::Less, + "equal" => wgpu_types::CompareFunction::Equal, + "less-equal" => wgpu_types::CompareFunction::LessEqual, + "greater" => wgpu_types::CompareFunction::Greater, + "not-equal" => wgpu_types::CompareFunction::NotEqual, + "greater-equal" => wgpu_types::CompareFunction::GreaterEqual, + "always" => wgpu_types::CompareFunction::Always, _ => unreachable!(), } } @@ -91,7 +91,7 @@ pub fn op_webgpu_create_sampler( .try_borrow() .unwrap(); - let descriptor = wgc::resource::SamplerDescriptor { + let descriptor = wgpu_core::resource::SamplerDescriptor { label: args.label.map(Cow::Owned), address_modes: [ serialize_address_mode(args.address_mode_u), @@ -104,7 +104,7 @@ pub fn op_webgpu_create_sampler( lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), lod_max_clamp: args .lod_max_clamp - .unwrap_or(wgc::resource::SamplerDescriptor::default().lod_max_clamp), + .unwrap_or(wgpu_core::resource::SamplerDescriptor::default().lod_max_clamp), compare: args .compare .as_ref() @@ -116,7 +116,7 @@ pub fn op_webgpu_create_sampler( }; // TODO - let (sampler, _) = wgc::gfx_select!(device => instance.device_create_sampler( + let (sampler, _) = gfx_select!(device => instance.device_create_sampler( device, &descriptor, std::marker::PhantomData diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 91a3e30c8f8dd5..6c17817b421934 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -9,7 +9,7 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -pub(crate) struct WebGPUShaderModule(pub(crate) wgc::id::ShaderModuleId); +pub(crate) struct WebGPUShaderModule(pub(crate) wgpu_core::id::ShaderModuleId); impl Resource for WebGPUShaderModule { fn name(&self) -> Cow { "webGPUShaderModule".into() @@ -47,8 +47,8 @@ pub fn op_webgpu_create_shader_module( .unwrap(); let source = match args.code { - Some(code) => wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), - None => wgc::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { + Some(code) => wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), + None => wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { let (prefix, data, suffix) = zero_copy[0].align_to::(); assert!(prefix.is_empty()); assert!(suffix.is_empty()); @@ -56,13 +56,13 @@ pub fn op_webgpu_create_shader_module( })), }; - let descriptor = wgc::pipeline::ShaderModuleDescriptor { + let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { label: args.label.map(Cow::Owned), flags: Default::default() }; // TODO - let (shader_module, _) = wgc::gfx_select!(device => instance.device_create_shader_module( + let (shader_module, _) = gfx_select!(device => instance.device_create_shader_module( device, &descriptor, source, diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 7b8112b4d323b4..92e726406c06f4 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -9,14 +9,14 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -pub(crate) struct WebGPUTexture(pub(crate) wgc::id::TextureId); +pub(crate) struct WebGPUTexture(pub(crate) wgpu_core::id::TextureId); impl Resource for WebGPUTexture { fn name(&self) -> Cow { "webGPUTexture".into() } } -pub(crate) struct WebGPUTextureView(pub(crate) wgc::id::TextureViewId); +pub(crate) struct WebGPUTextureView(pub(crate) wgpu_core::id::TextureViewId); impl Resource for WebGPUTextureView { fn name(&self) -> Cow { "webGPUTextureView".into() @@ -25,78 +25,78 @@ impl Resource for WebGPUTextureView { pub fn serialize_texture_format( format: &String, -) -> Result { +) -> Result { Ok(match format.as_str() { // 8-bit formats - "r8unorm" => wgt::TextureFormat::R8Unorm, - "r8snorm" => wgt::TextureFormat::R8Snorm, - "r8uint" => wgt::TextureFormat::R8Uint, - "r8sint" => wgt::TextureFormat::R8Sint, + "r8unorm" => wgpu_types::TextureFormat::R8Unorm, + "r8snorm" => wgpu_types::TextureFormat::R8Snorm, + "r8uint" => wgpu_types::TextureFormat::R8Uint, + "r8sint" => wgpu_types::TextureFormat::R8Sint, // 16-bit formats - "r16uint" => wgt::TextureFormat::R16Uint, - "r16sint" => wgt::TextureFormat::R16Sint, - "r16float" => wgt::TextureFormat::R16Float, - "rg8unorm" => wgt::TextureFormat::Rg8Unorm, - "rg8snorm" => wgt::TextureFormat::Rg8Snorm, - "rg8uint" => wgt::TextureFormat::Rg8Uint, - "rg8sint" => wgt::TextureFormat::Rg8Sint, + "r16uint" => wgpu_types::TextureFormat::R16Uint, + "r16sint" => wgpu_types::TextureFormat::R16Sint, + "r16float" => wgpu_types::TextureFormat::R16Float, + "rg8unorm" => wgpu_types::TextureFormat::Rg8Unorm, + "rg8snorm" => wgpu_types::TextureFormat::Rg8Snorm, + "rg8uint" => wgpu_types::TextureFormat::Rg8Uint, + "rg8sint" => wgpu_types::TextureFormat::Rg8Sint, // 32-bit formats - "r32uint" => wgt::TextureFormat::R32Uint, - "r32sint" => wgt::TextureFormat::R32Sint, - "r32float" => wgt::TextureFormat::R32Float, - "rg16uint" => wgt::TextureFormat::Rg16Uint, - "rg16sint" => wgt::TextureFormat::Rg16Sint, - "rg16float" => wgt::TextureFormat::Rg16Float, - "rgba8unorm" => wgt::TextureFormat::Rgba8Unorm, - "rgba8unorm-srgb" => wgt::TextureFormat::Rgba8UnormSrgb, - "rgba8snorm" => wgt::TextureFormat::Rgba8Snorm, - "rgba8uint" => wgt::TextureFormat::Rgba8Uint, - "rgba8sint" => wgt::TextureFormat::Rgba8Sint, - "bgra8unorm" => wgt::TextureFormat::Bgra8Unorm, - "bgra8unorm-srgb" => wgt::TextureFormat::Bgra8UnormSrgb, + "r32uint" => wgpu_types::TextureFormat::R32Uint, + "r32sint" => wgpu_types::TextureFormat::R32Sint, + "r32float" => wgpu_types::TextureFormat::R32Float, + "rg16uint" => wgpu_types::TextureFormat::Rg16Uint, + "rg16sint" => wgpu_types::TextureFormat::Rg16Sint, + "rg16float" => wgpu_types::TextureFormat::Rg16Float, + "rgba8unorm" => wgpu_types::TextureFormat::Rgba8Unorm, + "rgba8unorm-srgb" => wgpu_types::TextureFormat::Rgba8UnormSrgb, + "rgba8snorm" => wgpu_types::TextureFormat::Rgba8Snorm, + "rgba8uint" => wgpu_types::TextureFormat::Rgba8Uint, + "rgba8sint" => wgpu_types::TextureFormat::Rgba8Sint, + "bgra8unorm" => wgpu_types::TextureFormat::Bgra8Unorm, + "bgra8unorm-srgb" => wgpu_types::TextureFormat::Bgra8UnormSrgb, // Packed 32-bit formats "rgb9e5ufloat" => return Err(not_supported()), // wgpu#967 - "rgb10a2unorm" => wgt::TextureFormat::Rgb10a2Unorm, - "rg11b10ufloat" => wgt::TextureFormat::Rg11b10Float, + "rgb10a2unorm" => wgpu_types::TextureFormat::Rgb10a2Unorm, + "rg11b10ufloat" => wgpu_types::TextureFormat::Rg11b10Float, // 64-bit formats - "rg32uint" => wgt::TextureFormat::Rg32Uint, - "rg32sint" => wgt::TextureFormat::Rg32Sint, - "rg32float" => wgt::TextureFormat::Rg32Float, - "rgba16uint" => wgt::TextureFormat::Rgba16Uint, - "rgba16sint" => wgt::TextureFormat::Rgba16Sint, - "rgba16float" => wgt::TextureFormat::Rgba16Float, + "rg32uint" => wgpu_types::TextureFormat::Rg32Uint, + "rg32sint" => wgpu_types::TextureFormat::Rg32Sint, + "rg32float" => wgpu_types::TextureFormat::Rg32Float, + "rgba16uint" => wgpu_types::TextureFormat::Rgba16Uint, + "rgba16sint" => wgpu_types::TextureFormat::Rgba16Sint, + "rgba16float" => wgpu_types::TextureFormat::Rgba16Float, // 128-bit formats - "rgba32uint" => wgt::TextureFormat::Rgba32Uint, - "rgba32sint" => wgt::TextureFormat::Rgba32Sint, - "rgba32float" => wgt::TextureFormat::Rgba32Float, + "rgba32uint" => wgpu_types::TextureFormat::Rgba32Uint, + "rgba32sint" => wgpu_types::TextureFormat::Rgba32Sint, + "rgba32float" => wgpu_types::TextureFormat::Rgba32Float, // Depth and stencil formats "stencil8" => return Err(not_supported()), // wgpu#967 "depth16unorm" => return Err(not_supported()), // wgpu#967 - "depth24plus" => wgt::TextureFormat::Depth24Plus, - "depth24plus-stencil8" => wgt::TextureFormat::Depth24PlusStencil8, - "depth32float" => wgt::TextureFormat::Depth32Float, + "depth24plus" => wgpu_types::TextureFormat::Depth24Plus, + "depth24plus-stencil8" => wgpu_types::TextureFormat::Depth24PlusStencil8, + "depth32float" => wgpu_types::TextureFormat::Depth32Float, // BC compressed formats usable if "texture-compression-bc" is both // supported by the device/user agent and enabled in requestDevice. - "bc1-rgba-unorm" => wgt::TextureFormat::Bc1RgbaUnorm, - "bc1-rgba-unorm-srgb" => wgt::TextureFormat::Bc1RgbaUnormSrgb, - "bc2-rgba-unorm" => wgt::TextureFormat::Bc2RgbaUnorm, - "bc2-rgba-unorm-srgb" => wgt::TextureFormat::Bc2RgbaUnormSrgb, - "bc3-rgba-unorm" => wgt::TextureFormat::Bc3RgbaUnorm, - "bc3-rgba-unorm-srgb" => wgt::TextureFormat::Bc3RgbaUnormSrgb, - "bc4-r-unorm" => wgt::TextureFormat::Bc4RUnorm, - "bc4-r-snorm" => wgt::TextureFormat::Bc4RSnorm, - "bc5-rg-unorm" => wgt::TextureFormat::Bc5RgUnorm, - "bc5-rg-snorm" => wgt::TextureFormat::Bc5RgSnorm, - "bc6h-rgb-ufloat" => wgt::TextureFormat::Bc6hRgbUfloat, - "bc6h-rgb-float" => wgt::TextureFormat::Bc6hRgbSfloat, // wgpu#967 - "bc7-rgba-unorm" => wgt::TextureFormat::Bc7RgbaUnorm, - "bc7-rgba-unorm-srgb" => wgt::TextureFormat::Bc7RgbaUnormSrgb, + "bc1-rgba-unorm" => wgpu_types::TextureFormat::Bc1RgbaUnorm, + "bc1-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc1RgbaUnormSrgb, + "bc2-rgba-unorm" => wgpu_types::TextureFormat::Bc2RgbaUnorm, + "bc2-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc2RgbaUnormSrgb, + "bc3-rgba-unorm" => wgpu_types::TextureFormat::Bc3RgbaUnorm, + "bc3-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc3RgbaUnormSrgb, + "bc4-r-unorm" => wgpu_types::TextureFormat::Bc4RUnorm, + "bc4-r-snorm" => wgpu_types::TextureFormat::Bc4RSnorm, + "bc5-rg-unorm" => wgpu_types::TextureFormat::Bc5RgUnorm, + "bc5-rg-snorm" => wgpu_types::TextureFormat::Bc5RgSnorm, + "bc6h-rgb-ufloat" => wgpu_types::TextureFormat::Bc6hRgbUfloat, + "bc6h-rgb-float" => wgpu_types::TextureFormat::Bc6hRgbSfloat, // wgpu#967 + "bc7-rgba-unorm" => wgpu_types::TextureFormat::Bc7RgbaUnorm, + "bc7-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc7RgbaUnormSrgb, // "depth24unorm-stencil8" extension "depth24unorm-stencil8" => return Err(not_supported()), // wgpu#967 @@ -107,14 +107,14 @@ pub fn serialize_texture_format( }) } -pub fn serialize_dimension(dimension: &String) -> wgt::TextureViewDimension { +pub fn serialize_dimension(dimension: &String) -> wgpu_types::TextureViewDimension { match dimension.as_str() { - "1d" => wgt::TextureViewDimension::D1, - "2d" => wgt::TextureViewDimension::D2, - "2d-array" => wgt::TextureViewDimension::D2Array, - "cube" => wgt::TextureViewDimension::Cube, - "cube-array" => wgt::TextureViewDimension::CubeArray, - "3d" => wgt::TextureViewDimension::D3, + "1d" => wgpu_types::TextureViewDimension::D1, + "2d" => wgpu_types::TextureViewDimension::D2, + "2d-array" => wgpu_types::TextureViewDimension::D2Array, + "cube" => wgpu_types::TextureViewDimension::Cube, + "cube-array" => wgpu_types::TextureViewDimension::CubeArray, + "3d" => wgpu_types::TextureViewDimension::D3, _ => unreachable!(), } } @@ -161,9 +161,9 @@ pub fn op_webgpu_create_texture( .try_borrow() .unwrap(); - let descriptor = wgc::resource::TextureDescriptor { + let descriptor = wgpu_core::resource::TextureDescriptor { label: args.label.map(Cow::Owned), - size: wgt::Extent3d { + size: wgpu_types::Extent3d { width: args.size.width.unwrap_or(1), height: args.size.height.unwrap_or(1), depth: args.size.depth.unwrap_or(1), @@ -172,19 +172,19 @@ pub fn op_webgpu_create_texture( sample_count: args.sample_count.unwrap_or(1), dimension: match args.dimension { Some(dimension) => match dimension.as_str() { - "1d" => wgt::TextureDimension::D1, - "2d" => wgt::TextureDimension::D2, - "3d" => wgt::TextureDimension::D3, + "1d" => wgpu_types::TextureDimension::D1, + "2d" => wgpu_types::TextureDimension::D2, + "3d" => wgpu_types::TextureDimension::D3, _ => unreachable!(), }, - None => wgt::TextureDimension::D2, + None => wgpu_types::TextureDimension::D2, }, format: serialize_texture_format(&args.format)?, - usage: wgt::TextureUsage::from_bits(args.usage).unwrap(), + usage: wgpu_types::TextureUsage::from_bits(args.usage).unwrap(), }; // TODO - let (texture, _) = wgc::gfx_select!(device => instance.device_create_texture( + let (texture, _) = gfx_select!(device => instance.device_create_texture( device, &descriptor, std::marker::PhantomData @@ -232,18 +232,18 @@ pub fn op_webgpu_create_texture_view( .try_borrow() .unwrap(); - let descriptor = wgc::resource::TextureViewDescriptor { + let descriptor = wgpu_core::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), format: args.format.map(|s| serialize_texture_format(&s)).transpose()?, dimension: args.dimension.map(|s| serialize_dimension(&s)), aspect: match args.aspect { Some(aspect) => match aspect.as_str() { - "all" => wgt::TextureAspect::All, - "stencil-only" => wgt::TextureAspect::StencilOnly, - "depth-only" => wgt::TextureAspect::DepthOnly, + "all" => wgpu_types::TextureAspect::All, + "stencil-only" => wgpu_types::TextureAspect::StencilOnly, + "depth-only" => wgpu_types::TextureAspect::DepthOnly, _ => unreachable!(), }, - None => wgt::TextureAspect::All, + None => wgpu_types::TextureAspect::All, }, base_mip_level: args.base_mip_level.unwrap_or(0), level_count: std::num::NonZeroU32::new(args.mip_level_count.unwrap_or(0)), @@ -254,7 +254,7 @@ pub fn op_webgpu_create_texture_view( }; // TODO - let (texture_view, _) = wgc::gfx_select!(texture => instance.texture_create_view( + let (texture_view, _) = gfx_select!(texture => instance.texture_create_view( texture, &descriptor, std::marker::PhantomData From 2c37fd88ac7dac7d0129a14d700f1f835e9fff4b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 03:16:08 +0100 Subject: [PATCH 052/144] clean up --- op_crates/webgpu/14_webgpu.js | 2 +- op_crates/webgpu/binding.rs | 33 ++++++++++++--------- op_crates/webgpu/buffer.rs | 10 +++---- op_crates/webgpu/bundle.rs | 26 ++++++++++------- op_crates/webgpu/command_encoder.rs | 38 ++++++++++++++---------- op_crates/webgpu/compute_pass.rs | 2 +- op_crates/webgpu/lib.rs | 31 ++++++++++++++------ op_crates/webgpu/pipeline.rs | 45 ++++++++++++++++++----------- op_crates/webgpu/queue.rs | 2 +- op_crates/webgpu/render_pass.rs | 2 +- op_crates/webgpu/sampler.rs | 25 +++++++++------- op_crates/webgpu/shader.rs | 27 +++++++++-------- op_crates/webgpu/texture.rs | 25 +++++++++------- 13 files changed, 159 insertions(+), 109 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 95417a8f0d29c0..d0121fc0bd3378 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. ((window) => { const core = window.Deno.core; diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index 836d1cf6d3bbf9..a3139071865bec 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -1,7 +1,7 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::{serde_json, RcRef, ZeroCopyBuf}; @@ -9,7 +9,9 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -pub(crate) struct WebGPUBindGroupLayout(pub(crate) wgpu_core::id::BindGroupLayoutId); +pub(crate) struct WebGPUBindGroupLayout( + pub(crate) wgpu_core::id::BindGroupLayoutId, +); impl Resource for WebGPUBindGroupLayout { fn name(&self) -> Cow { "webGPUBindGroupLayout".into() @@ -106,7 +108,9 @@ pub fn op_webgpu_create_bind_group_layout( ty: match &buffer.kind { Some(kind) => match kind.as_str() { "uniform" => wgpu_types::BufferBindingType::Uniform, - "storage" => wgpu_types::BufferBindingType::Storage { read_only: false }, + "storage" => { + wgpu_types::BufferBindingType::Storage { read_only: false } + } "read-only-storage" => { wgpu_types::BufferBindingType::Storage { read_only: true } } @@ -149,7 +153,9 @@ pub fn op_webgpu_create_bind_group_layout( wgpu_types::BindingType::Texture { sample_type: match &texture.sample_type { Some(sample_type) => match sample_type.as_str() { - "float" => wgpu_types::TextureSampleType::Float { filterable: true }, + "float" => { + wgpu_types::TextureSampleType::Float { filterable: true } + } "unfilterable-float" => { wgpu_types::TextureSampleType::Float { filterable: false } } @@ -196,12 +202,12 @@ pub fn op_webgpu_create_bind_group_layout( label: args.label.map(Cow::Owned), entries: Cow::Owned(entries), }; - // TODO - let (bind_group_layout, _) = gfx_select!(device => instance.device_create_bind_group_layout( + + let bind_group_layout = gfx_select_err!(device => instance.device_create_bind_group_layout( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state .resource_table @@ -257,12 +263,12 @@ pub fn op_webgpu_create_pipeline_layout( bind_group_layouts: Cow::Owned(bind_group_layouts), push_constant_ranges: Default::default(), }; - // TODO - let (pipeline_layout, _) = gfx_select!(device => instance.device_create_pipeline_layout( + + let pipeline_layout = gfx_select_err!(device => instance.device_create_pipeline_layout( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state .resource_table @@ -366,12 +372,11 @@ pub fn op_webgpu_create_bind_group( .try_borrow() .unwrap(); - // TODO - let (bind_group, _) = gfx_select!(device => instance.device_create_bind_group( + let bind_group = gfx_select_err!(device => instance.device_create_bind_group( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUBindGroup(bind_group)); diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 922060eac47b14..ec1b9540269838 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use std::borrow::Cow; use std::cell::RefCell; @@ -68,12 +68,11 @@ pub fn op_webgpu_create_buffer( mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }; - // TODO - let (buffer, _) = gfx_select!(device => instance.device_create_buffer( + let buffer = gfx_select_err!(device => instance.device_create_buffer( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUBuffer(buffer)); @@ -169,7 +168,8 @@ pub async fn op_webgpu_buffer_get_map_async( if let Some(instance_resource) = instance_resource { let instance = RcRef::map(&instance_resource, |r| &r.0).borrow().await; - gfx_select!(device.clone() => instance.device_poll(device, false)).unwrap() + gfx_select!(device.clone() => instance.device_poll(device, false)) + .unwrap() } else { break; } diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index e8ed066f200ec2..34b964b2678cfc 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -13,7 +13,9 @@ use std::rc::Rc; use super::texture::serialize_texture_format; -struct WebGPURenderBundleEncoder(RefCell); +struct WebGPURenderBundleEncoder( + RefCell, +); impl Resource for WebGPURenderBundleEncoder { fn name(&self) -> Cow { "webGPURenderBundleEncoder".into() @@ -111,14 +113,13 @@ pub fn op_webgpu_render_bundle_encoder_finish( .try_borrow() .unwrap(); - // TODO - let (render_bundle, _) = gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + let render_bundle = gfx_select_err!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgpu_core::command::RenderBundleDescriptor { label: args.label.map(Cow::Owned), }, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPURenderBundle(render_bundle)); @@ -323,12 +324,15 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - render_bundle_encoder_resource.0.borrow_mut().set_index_buffer( - buffer_resource.0, - super::pipeline::serialize_index_format(args.index_format), - args.offset, - std::num::NonZeroU64::new(args.size), - ); + render_bundle_encoder_resource + .0 + .borrow_mut() + .set_index_buffer( + buffer_resource.0, + super::pipeline::serialize_index_format(args.index_format), + args.offset, + std::num::NonZeroU64::new(args.size), + ); Ok(json!({})) } diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index cc863d782c9af7..8cd680206fb486 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -10,14 +10,18 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; -pub(crate) struct WebGPUCommandEncoder(pub(crate) wgpu_core::id::CommandEncoderId); +pub(crate) struct WebGPUCommandEncoder( + pub(crate) wgpu_core::id::CommandEncoderId, +); impl Resource for WebGPUCommandEncoder { fn name(&self) -> Cow { "webGPUCommandEncoder".into() } } -pub(crate) struct WebGPUCommandBuffer(pub(crate) wgpu_core::id::CommandBufferId); +pub(crate) struct WebGPUCommandBuffer( + pub(crate) wgpu_core::id::CommandBufferId, +); impl Resource for WebGPUCommandBuffer { fn name(&self) -> Cow { "webGPUCommandBuffer".into() @@ -38,7 +42,7 @@ struct CreateCommandEncoderArgs { instance_rid: u32, device_rid: u32, label: Option, - _measure_execution_time: Option, // waiting for wgpu to add measure_execution_time + _measure_execution_time: Option, // not yet implemented } pub fn op_webgpu_create_command_encoder( @@ -65,12 +69,11 @@ pub fn op_webgpu_create_command_encoder( label: args.label.map(Cow::Owned), }; - // TODO - let (command_encoder, _) = gfx_select!(device => instance.device_create_command_encoder( + let command_encoder = gfx_select_err!(device => instance.device_create_command_encoder( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state .resource_table @@ -112,7 +115,7 @@ struct CommandEncoderBeginRenderPassArgs { label: Option, color_attachments: Vec, depth_stencil_attachment: Option, - _occlusion_query_set: u32, // TODO wgpu#721 + _occlusion_query_set: u32, // not yet implemented } pub fn op_webgpu_command_encoder_begin_render_pass( @@ -229,8 +232,10 @@ pub fn op_webgpu_command_encoder_begin_render_pass( depth_stencil_attachment: depth_stencil_attachment.as_ref(), }; - let render_pass = - wgpu_core::command::RenderPass::new(command_encoder_resource.0, &descriptor); + let render_pass = wgpu_core::command::RenderPass::new( + command_encoder_resource.0, + &descriptor, + ); let rid = state .resource_table @@ -266,8 +271,10 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( label: args.label.map(Cow::Owned), }; - let compute_pass = - wgpu_core::command::ComputePass::new(command_encoder_resource.0, &descriptor); + let compute_pass = wgpu_core::command::ComputePass::new( + command_encoder_resource.0, + &descriptor, + ); let rid = state .resource_table @@ -358,7 +365,7 @@ pub struct GPUImageCopyTexture { pub texture: u32, pub mip_level: Option, pub origin: Option, - pub aspect: Option, // TODO + pub aspect: Option, // not yet implemented } #[derive(Deserialize)] @@ -716,11 +723,10 @@ pub fn op_webgpu_command_encoder_finish( label: args.label.map(Cow::Owned), }; - // TODO - let (command_buffer, _) = gfx_select!(command_encoder => instance.command_encoder_finish( + let command_buffer = gfx_select_err!(command_encoder => instance.command_encoder_finish( command_encoder, &descriptor - )); + ))?; let rid = state .resource_table diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index b016141df6e4d2..e8b6d8194f7ecc 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 0e78a90afde68e..7cdd660c35d146 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. #![deny(warnings)] @@ -33,6 +33,19 @@ mod macros { } }; } + + macro_rules! gfx_select_err { + ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { + { + let (data, err) = gfx_select!($id => $global.$method( $($param),* )); + if let Some(err) = err { + Err(err) + } else { + Ok(data) + } + } + }; + } } pub mod binding; @@ -148,13 +161,13 @@ pub async fn op_webgpu_request_adapter( }; let adapter = instance.request_adapter( &descriptor, - wgpu_core::instance::AdapterInputs::Mask(wgpu_types::BackendBit::PRIMARY, |_| { - std::marker::PhantomData - }), + wgpu_core::instance::AdapterInputs::Mask( + wgpu_types::BackendBit::PRIMARY, + |_| std::marker::PhantomData, + ), )?; - let name = - gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; + let name = gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; let adapter_features = gfx_select!(adapter => instance.adapter_features(adapter))?; let features = deserialize_features(&adapter_features); @@ -274,13 +287,13 @@ pub async fn op_webgpu_request_device( max_push_constant_size: 0, }), }; - // TODO - let (device, _) = gfx_select!(adapter => instance.adapter_request_device( + + let device = gfx_select_err!(adapter => instance.adapter_request_device( adapter, &descriptor, None, std::marker::PhantomData - )); + ))?; let device_features = gfx_select!(device => instance.device_features(device))?; diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 9da2040fbae1a0..796e1f9b5bc909 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -13,21 +13,27 @@ use super::sampler::serialize_compare_function; use super::texture::serialize_texture_format; use crate::shader::WebGPUShaderModule; -pub(crate) struct WebGPUPipelineLayout(pub(crate) wgpu_core::id::PipelineLayoutId); +pub(crate) struct WebGPUPipelineLayout( + pub(crate) wgpu_core::id::PipelineLayoutId, +); impl Resource for WebGPUPipelineLayout { fn name(&self) -> Cow { "webGPUPipelineLayout".into() } } -pub(crate) struct WebGPUComputePipeline(pub(crate) wgpu_core::id::ComputePipelineId); +pub(crate) struct WebGPUComputePipeline( + pub(crate) wgpu_core::id::ComputePipelineId, +); impl Resource for WebGPUComputePipeline { fn name(&self) -> Cow { "webGPUComputePipeline".into() } } -pub(crate) struct WebGPURenderPipeline(pub(crate) wgpu_core::id::RenderPipelineId); +pub(crate) struct WebGPURenderPipeline( + pub(crate) wgpu_core::id::RenderPipelineId, +); impl Resource for WebGPURenderPipeline { fn name(&self) -> Cow { "webGPURenderPipeline".into() @@ -42,7 +48,9 @@ pub fn serialize_index_format(format: String) -> wgpu_types::IndexFormat { } } -fn serialize_stencil_operation(operation: &str) -> wgpu_types::StencilOperation { +fn serialize_stencil_operation( + operation: &str, +) -> wgpu_types::StencilOperation { match operation { "keep" => wgpu_types::StencilOperation::Keep, "zero" => wgpu_types::StencilOperation::Zero, @@ -56,7 +64,9 @@ fn serialize_stencil_operation(operation: &str) -> wgpu_types::StencilOperation } } -fn serialize_stencil_face_state(state: GPUStencilFaceState) -> wgpu_types::StencilFaceState { +fn serialize_stencil_face_state( + state: GPUStencilFaceState, +) -> wgpu_types::StencilFaceState { wgpu_types::StencilFaceState { compare: state .compare @@ -104,7 +114,9 @@ fn serialize_blend_factor(blend_factor: &str) -> wgpu_types::BlendFactor { } } -fn serialize_blend_component(blend: GPUBlendComponent) -> wgpu_types::BlendState { +fn serialize_blend_component( + blend: GPUBlendComponent, +) -> wgpu_types::BlendState { wgpu_types::BlendState { src_factor: blend .src_factor @@ -189,7 +201,7 @@ pub fn op_webgpu_create_compute_pipeline( layout: pipeline_layout, stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: compute_shader_module_resource.0, - entry_point: Cow::Owned(args.compute.entry_point) + entry_point: Cow::Owned(args.compute.entry_point), }, }; let implicit_pipelines = match args.layout { @@ -246,8 +258,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .try_borrow() .unwrap(); - // TODO - let (bind_group_layout, _) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); + let bind_group_layout = gfx_select_err!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData))?; let rid = state .resource_table @@ -478,7 +489,6 @@ pub fn op_webgpu_create_render_pipeline( }), }, primitive: args.primitive.map_or(Default::default(), |primitive| { - // TODO wgpu_types::PrimitiveState { topology: match primitive.topology { Some(topology) => match topology.as_str() { @@ -491,7 +501,9 @@ pub fn op_webgpu_create_render_pipeline( }, None => wgpu_types::PrimitiveTopology::TriangleList, }, - strip_index_format: primitive.strip_index_format.map(serialize_index_format), + strip_index_format: primitive + .strip_index_format + .map(serialize_index_format), front_face: match primitive.front_face { Some(front_face) => match front_face.as_str() { "ccw" => wgpu_types::FrontFace::Ccw, @@ -543,7 +555,6 @@ pub fn op_webgpu_create_render_pipeline( }), multisample: args.multisample.map_or(Default::default(), |multisample| { wgpu_types::MultisampleState { - // TODO count: multisample.count.unwrap_or(1), mask: multisample.mask.unwrap_or(0xFFFFFFFF), alpha_to_coverage_enabled: multisample @@ -556,7 +567,7 @@ pub fn op_webgpu_create_render_pipeline( .resource_table .get::(fragment.module) .ok_or_else(bad_resource_id) - .unwrap(); // TODO + .unwrap(); wgpu_core::pipeline::FragmentState { stage: wgpu_core::pipeline::ProgrammableStageDescriptor { @@ -577,7 +588,8 @@ pub fn op_webgpu_create_render_pipeline( wgpu_types::ColorTargetState { format: serialize_texture_format(&target.format).unwrap(), - alpha_blend: blends.clone() + alpha_blend: blends + .clone() .map_or(Default::default(), |states| states.0), color_blend: blends .map_or(Default::default(), |states| states.1), @@ -648,8 +660,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .try_borrow() .unwrap(); - // TODO - let (bind_group_layout, _) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); + let bind_group_layout = gfx_select_err!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData))?; let rid = state .resource_table diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index e6fef642530da5..8de70386d2d735 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index b9f22127f1e2aa..ec87c075bd2974 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 8088c208716629..e13c1e993e5f8f 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -16,7 +16,9 @@ impl Resource for WebGPUSampler { } } -fn serialize_address_mode(address_mode: Option) -> wgpu_types::AddressMode { +fn serialize_address_mode( + address_mode: Option, +) -> wgpu_types::AddressMode { match address_mode { Some(address_mode) => match address_mode.as_str() { "clamp-to-edge" => wgpu_types::AddressMode::ClampToEdge, @@ -28,7 +30,9 @@ fn serialize_address_mode(address_mode: Option) -> wgpu_types::AddressMo } } -fn serialize_filter_mode(filter_mode: Option) -> wgpu_types::FilterMode { +fn serialize_filter_mode( + filter_mode: Option, +) -> wgpu_types::FilterMode { match filter_mode { Some(filter_mode) => match filter_mode.as_str() { "nearest" => wgpu_types::FilterMode::Nearest, @@ -39,7 +43,9 @@ fn serialize_filter_mode(filter_mode: Option) -> wgpu_types::FilterMode } } -pub fn serialize_compare_function(compare: &str) -> wgpu_types::CompareFunction { +pub fn serialize_compare_function( + compare: &str, +) -> wgpu_types::CompareFunction { match compare { "never" => wgpu_types::CompareFunction::Never, "less" => wgpu_types::CompareFunction::Less, @@ -102,9 +108,9 @@ pub fn op_webgpu_create_sampler( min_filter: serialize_filter_mode(args.min_filter), mipmap_filter: serialize_filter_mode(args.mipmap_filter), lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args - .lod_max_clamp - .unwrap_or(wgpu_core::resource::SamplerDescriptor::default().lod_max_clamp), + lod_max_clamp: args.lod_max_clamp.unwrap_or( + wgpu_core::resource::SamplerDescriptor::default().lod_max_clamp, + ), compare: args .compare .as_ref() @@ -115,12 +121,11 @@ pub fn op_webgpu_create_sampler( border_color: None, // native-only }; - // TODO - let (sampler, _) = gfx_select!(device => instance.device_create_sampler( + let sampler = gfx_select_err!(device => instance.device_create_sampler( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUSampler(sampler)); diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 6c17817b421934..c65924575e2d93 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; use deno_core::error::AnyError; @@ -47,27 +47,30 @@ pub fn op_webgpu_create_shader_module( .unwrap(); let source = match args.code { - Some(code) => wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)), - None => wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { - let (prefix, data, suffix) = zero_copy[0].align_to::(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data - })), + Some(code) => { + wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)) + } + None => { + wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data + })) + } }; let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { label: args.label.map(Cow::Owned), - flags: Default::default() + flags: Default::default(), }; - // TODO - let (shader_module, _) = gfx_select!(device => instance.device_create_shader_module( + let shader_module = gfx_select_err!(device => instance.device_create_shader_module( device, &descriptor, source, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUShaderModule(shader_module)); diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 92e726406c06f4..ced8b2ce0ad6b5 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; @@ -24,9 +24,9 @@ impl Resource for WebGPUTextureView { } pub fn serialize_texture_format( - format: &String, + format: &str, ) -> Result { - Ok(match format.as_str() { + Ok(match format { // 8-bit formats "r8unorm" => wgpu_types::TextureFormat::R8Unorm, "r8snorm" => wgpu_types::TextureFormat::R8Snorm, @@ -107,7 +107,9 @@ pub fn serialize_texture_format( }) } -pub fn serialize_dimension(dimension: &String) -> wgpu_types::TextureViewDimension { +pub fn serialize_dimension( + dimension: &String, +) -> wgpu_types::TextureViewDimension { match dimension.as_str() { "1d" => wgpu_types::TextureViewDimension::D1, "2d" => wgpu_types::TextureViewDimension::D2, @@ -183,12 +185,11 @@ pub fn op_webgpu_create_texture( usage: wgpu_types::TextureUsage::from_bits(args.usage).unwrap(), }; - // TODO - let (texture, _) = gfx_select!(device => instance.device_create_texture( + let texture = gfx_select_err!(device => instance.device_create_texture( device, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUTexture(texture)); @@ -234,7 +235,10 @@ pub fn op_webgpu_create_texture_view( let descriptor = wgpu_core::resource::TextureViewDescriptor { label: args.label.map(Cow::Owned), - format: args.format.map(|s| serialize_texture_format(&s)).transpose()?, + format: args + .format + .map(|s| serialize_texture_format(&s)) + .transpose()?, dimension: args.dimension.map(|s| serialize_dimension(&s)), aspect: match args.aspect { Some(aspect) => match aspect.as_str() { @@ -253,12 +257,11 @@ pub fn op_webgpu_create_texture_view( ), }; - // TODO - let (texture_view, _) = gfx_select!(texture => instance.texture_create_view( + let texture_view = gfx_select_err!(texture => instance.texture_create_view( texture, &descriptor, std::marker::PhantomData - )); + ))?; let rid = state.resource_table.add(WebGPUTextureView(texture_view)); From 00993bff7897850713d0b091f24538f2e9be86af Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 17:07:04 +0100 Subject: [PATCH 053/144] continue update --- op_crates/webgpu/14_webgpu.js | 109 ++++++++++++++++++++------- op_crates/webgpu/binding.rs | 12 +-- op_crates/webgpu/buffer.rs | 14 ++-- op_crates/webgpu/bundle.rs | 6 +- op_crates/webgpu/command_encoder.rs | 104 +++++++++++++++++++++++-- op_crates/webgpu/compute_pass.rs | 99 ++++++++++++++++++++++++ op_crates/webgpu/lib.rs | 113 +++++++++++++++++++++++++++- op_crates/webgpu/pipeline.rs | 33 ++++---- op_crates/webgpu/render_pass.rs | 99 ++++++++++++++++++++++++ op_crates/webgpu/sampler.rs | 2 +- op_crates/webgpu/shader.rs | 18 ++--- op_crates/webgpu/texture.rs | 8 +- runtime/ops/webgpu.rs | 30 ++++++++ 13 files changed, 564 insertions(+), 83 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index d0121fc0bd3378..e7dd3087330182 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -133,7 +133,9 @@ this.label = data.label; } - destroy() {} // TODO + destroy() { + throw new Error("Not yet implemented"); + } createBuffer(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { @@ -187,7 +189,7 @@ if (descriptor.storageTexture) i++; if (i !== 1) { - throw new Error(); // TODO + throw new Error(); // TODO(@crowlKats): correct error } } @@ -305,11 +307,11 @@ } createComputePipelineAsync(_descriptor) { - throw new Error("Not yet implemented"); // TODO easy polyfill + throw new Error("Not yet implemented"); // easy polyfill } createRenderPipelineAsync(_descriptor) { - throw new Error("Not yet implemented"); // TODO easy polyfill + throw new Error("Not yet implemented"); // easy polyfill } createCommandEncoder(descriptor = {}) { @@ -334,8 +336,16 @@ return new GPURenderBundleEncoder(rid, descriptor.label); } - createQuerySet(_descriptor) { - throw new Error("Not yet implemented"); // wgpu#721 + createQuerySet(descriptor) { + const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { + instanceRid, + deviceRid: this.#rid, + ...descriptor, + }); + + const querySet = new GPUQuerySet(descriptor.label); + GPUQuerySetMap.set(querySet, rid); + return querySet; } } @@ -533,7 +543,7 @@ } compilationInfo() { - throw new Error("Not yet implemented"); // wgpu#977 + throw new Error("Not yet implemented"); } } @@ -772,25 +782,38 @@ }); } insertDebugMarker(markerLabel) { - core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { + core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { instanceRid, commandEncoderRid: this.#rid, markerLabel, }); } - writeTimestamp(_querySet, _queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + writeTimestamp(querySet, queryIndex) { + core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { + instanceRid, + commandEncoderRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + queryIndex, + }); } resolveQuerySet( - _querySet, - _firstQuery, - _queryCount, - _destination, - _destinationOffset, + querySet, + firstQuery, + queryCount, + destination, + destinationOffset, ) { - throw new Error("Not yet implemented"); // wgpu#721 + core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { + instanceRid, + commandEncoderRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + firstQuery, + queryCount, + destination: GPUBufferMap.get(destination), + destinationOffset, + }); } finish(descriptor = {}) { @@ -858,15 +881,25 @@ throw new Error("Not yet implemented"); // wgpu#721 } - beginPipelineStatisticsQuery(_querySet, _queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + beginPipelineStatisticsQuery(querySet, queryIndex) { + core.jsonOpSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { + renderPassRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + queryIndex, + }); } endPipelineStatisticsQuery() { - throw new Error("Not yet implemented"); // wgpu#721 + core.jsonOpSync("op_webgpu_render_pass_end_pipeline_statistics_query", { + renderPassRid: this.#rid, + }); } - writeTimestamp(_querySet, _queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + writeTimestamp(querySet, queryIndex) { + core.jsonOpSync("op_webgpu_render_pass_write_timestamp", { + renderPassRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + queryIndex, + }); } executeBundles(bundles) { @@ -1034,15 +1067,28 @@ }); } - beginPipelineStatisticsQuery(_querySet, _queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + beginPipelineStatisticsQuery(querySet, queryIndex) { + core.jsonOpSync( + "op_webgpu_compute_pass_begin_pipeline_statistics_query", + { + computePassRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + queryIndex, + }, + ); } endPipelineStatisticsQuery() { - throw new Error("Not yet implemented"); // wgpu#721 + core.jsonOpSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { + computePassRid: this.#rid, + }); } - writeTimestamp(_querySet, _queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + writeTimestamp(querySet, queryIndex) { + core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { + computePassRid: this.#rid, + querySet: GPUQuerySetMap.get(querySet), + queryIndex, + }); } endPass() { @@ -1260,6 +1306,17 @@ } } + const GPUQuerySetMap = new WeakMap(); + class GPUQuerySet { + constructor(label) { + this.label = label ?? null; + } + + destroy() { + throw new Error("Not yet implemented"); + } + } + window.__bootstrap.webGPU = { gpu, }; diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index a3139071865bec..b1eb599e12d32d 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -199,8 +199,8 @@ pub fn op_webgpu_create_bind_group_layout( } let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { - label: args.label.map(Cow::Owned), - entries: Cow::Owned(entries), + label: args.label.map(Cow::from), + entries: Cow::from(entries), }; let bind_group_layout = gfx_select_err!(device => instance.device_create_bind_group_layout( @@ -259,8 +259,8 @@ pub fn op_webgpu_create_pipeline_layout( .unwrap(); let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { - label: args.label.map(Cow::Owned), - bind_group_layouts: Cow::Owned(bind_group_layouts), + label: args.label.map(Cow::from), + bind_group_layouts: Cow::from(bind_group_layouts), push_constant_ranges: Default::default(), }; @@ -359,9 +359,9 @@ pub fn op_webgpu_create_bind_group( .ok_or_else(bad_resource_id)?; let descriptor = wgpu_core::binding_model::BindGroupDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), layout: bind_group_layout.0, - entries: Cow::Owned(entries), + entries: Cow::from(entries), }; let instance_resource = state diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index ec1b9540269838..63be891df5ca91 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -1,12 +1,5 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; -use std::time::Duration; - -use serde::Deserialize; - use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::futures::channel::oneshot; @@ -15,6 +8,11 @@ use deno_core::serde_json::Value; use deno_core::OpState; use deno_core::{serde_json, RcRef, ZeroCopyBuf}; use deno_core::{BufVec, Resource}; +use serde::Deserialize; +use std::borrow::Cow; +use std::cell::RefCell; +use std::rc::Rc; +use std::time::Duration; pub(crate) struct WebGPUBuffer(pub(crate) wgpu_core::id::BufferId); impl Resource for WebGPUBuffer { @@ -62,7 +60,7 @@ pub fn op_webgpu_create_buffer( .unwrap(); let descriptor = wgpu_core::resource::BufferDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), size: args.size, usage: wgpu_types::BufferUsage::from_bits(args.usage).unwrap(), mapped_at_creation: args.mapped_at_creation.unwrap_or(false), diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 34b964b2678cfc..1cbb7cedbd2041 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -59,8 +59,8 @@ pub fn op_webgpu_create_render_bundle_encoder( } let descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { - label: args.label.map(Cow::Owned), - color_formats: Cow::Owned(color_formats), + label: args.label.map(Cow::from), + color_formats: Cow::from(color_formats), depth_stencil_format: args .depth_stencil_format .map(|s| serialize_texture_format(&s)) @@ -116,7 +116,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( let render_bundle = gfx_select_err!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgpu_core::command::RenderBundleDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), }, std::marker::PhantomData ))?; diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 8cd680206fb486..d34fc36947c69a 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -66,7 +66,7 @@ pub fn op_webgpu_create_command_encoder( .unwrap(); let descriptor = wgpu_types::CommandEncoderDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), }; let command_encoder = gfx_select_err!(device => instance.device_create_command_encoder( @@ -227,8 +227,8 @@ pub fn op_webgpu_command_encoder_begin_render_pass( } let descriptor = wgpu_core::command::RenderPassDescriptor { - label: args.label.map(Cow::Owned), - color_attachments: Cow::Owned(color_attachments), + label: args.label.map(Cow::from), + color_attachments: Cow::from(color_attachments), depth_stencil_attachment: depth_stencil_attachment.as_ref(), }; @@ -268,7 +268,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( .ok_or_else(bad_resource_id)?; let descriptor = wgpu_core::command::ComputePassDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), }; let compute_pass = wgpu_core::command::ComputePass::new( @@ -691,6 +691,100 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderWriteTimestampArgs { + instance_rid: u32, + command_encoder_rid: u32, + query_set: u32, + query_index: u32, +} + +pub fn op_webgpu_command_encoder_write_timestamp( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderWriteTimestampArgs = serde_json::from_value(args)?; + + let command_encoder_resource = state + .resource_table + .get::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = command_encoder_resource.0; + let instance_resource = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + + gfx_select!(command_encoder => instance.command_encoder_write_timestamp( + command_encoder, + query_set_resource.0, + args.query_index + ))?; + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CommandEncoderResolveQuerySetArgs { + instance_rid: u32, + command_encoder_rid: u32, + query_set: u32, + first_query: u32, + query_count: u32, + destination: u32, + destination_offset: u64, +} + +pub fn op_webgpu_command_encoder_resolve_query_set( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CommandEncoderResolveQuerySetArgs = serde_json::from_value(args)?; + + let command_encoder_resource = state + .resource_table + .get::(args.command_encoder_rid) + .ok_or_else(bad_resource_id)?; + let command_encoder = command_encoder_resource.0; + let instance_resource = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + let destination_resource = state + .resource_table + .get::(args.destination) + .ok_or_else(bad_resource_id)?; + + gfx_select!(command_encoder => instance.command_encoder_resolve_query_set( + command_encoder, + query_set_resource.0, + args.first_query, + args.query_count, + destination_resource.0, + args.destination_offset + ))?; + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderFinishArgs { @@ -720,7 +814,7 @@ pub fn op_webgpu_command_encoder_finish( .unwrap(); let descriptor = wgpu_types::CommandBufferDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), }; let command_buffer = gfx_select_err!(command_encoder => instance.command_encoder_finish( diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index e8b6d8194f7ecc..71d4043d07ba7b 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -114,6 +114,105 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassBeginPipelineStatisticsQueryArgs { + compute_pass_rid: u32, + query_set: u32, + query_index: u32, +} + +pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassBeginPipelineStatisticsQueryArgs = + serde_json::from_value(args)?; + + let compute_pass_resource = state + .resource_table + .get::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query( + &mut compute_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassEndPipelineStatisticsQueryArgs { + compute_pass_rid: u32, +} + +pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassEndPipelineStatisticsQueryArgs = + serde_json::from_value(args)?; + + let compute_pass_resource = state + .resource_table + .get::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query( + &mut compute_pass_resource.0.borrow_mut(), + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ComputePassWriteTimestampArgs { + compute_pass_rid: u32, + query_set: u32, + query_index: u32, +} + +pub fn op_webgpu_compute_pass_write_timestamp( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: ComputePassWriteTimestampArgs = serde_json::from_value(args)?; + + let compute_pass_resource = state + .resource_table + .get::(args.compute_pass_rid) + .ok_or_else(bad_resource_id)?; + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::compute_ffi::wgpu_compute_pass_write_timestamp( + &mut compute_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); + } + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassEndPassArgs { diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 7cdd660c35d146..c2422b0ebd8aa2 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -2,8 +2,8 @@ #![deny(warnings)] -use deno_core::error::bad_resource_id; use deno_core::error::AnyError; +use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; @@ -19,7 +19,7 @@ mod macros { macro_rules! gfx_select { ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { match $id.backend() { - #[cfg(all(not(target_arch = "wasm32"), any(not(any(target_os = "ios", target_os = "macos")), feature = "gfx-backend-vulkan")))] + #[cfg(all(not(target_arch = "wasm32"), not(any(target_os = "ios", target_os = "macos"))))] wgpu_types::Backend::Vulkan => $global.$method::( $($param),* ), #[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))] wgpu_types::Backend::Metal => $global.$method::( $($param),* ), @@ -83,6 +83,13 @@ impl Resource for WebGPUDevice { } } +struct WebGPUQuerySet(wgpu_core::id::QuerySetId); +impl Resource for WebGPUQuerySet { + fn name(&self) -> Cow { + "webGPUQuerySet".into() + } +} + /// Execute this crates' JS source files. pub fn init(isolate: &mut deno_core::JsRuntime) { let files = vec![( @@ -254,7 +261,7 @@ pub async fn op_webgpu_request_device( } let descriptor = wgpu_types::DeviceDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), features, limits: args .non_guaranteed_limits @@ -319,3 +326,103 @@ pub async fn op_webgpu_request_device( "limits": json_limits, })) } + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CreateQuerySetArgs { + instance_rid: u32, + device_rid: u32, + _label: Option, // not yet implemented + #[serde(rename = "type")] + kind: String, + count: u32, + pipeline_statistics: Option>, +} + +pub fn op_webgpu_create_query_set( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: CreateQuerySetArgs = serde_json::from_value(args)?; + + let device_resource = state + .resource_table + .get::(args.device_rid) + .ok_or_else(bad_resource_id)?; + let device = device_resource.0; + let instance_resource = state + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = RcRef::map(&instance_resource, |r| &r.0) + .try_borrow() + .unwrap(); + + let descriptor = wgpu_types::QuerySetDescriptor { + ty: match args.kind.as_str() { + "pipeline-statistics" => { + let mut pipeline_statistics_names = + wgpu_types::PipelineStatisticsTypes::empty(); + + if let Some(pipeline_statistics) = args.pipeline_statistics { + if pipeline_statistics + .contains(&"vertex-shader-invocations".to_string()) + { + pipeline_statistics_names.set( + wgpu_types::PipelineStatisticsTypes::VERTEX_SHADER_INVOCATIONS, + true, + ); + } + if pipeline_statistics.contains(&"clipper-invocations".to_string()) { + pipeline_statistics_names.set( + wgpu_types::PipelineStatisticsTypes::CLIPPER_INVOCATIONS, + true, + ); + } + if pipeline_statistics.contains(&"clipper-primitives-out".to_string()) + { + pipeline_statistics_names.set( + wgpu_types::PipelineStatisticsTypes::CLIPPER_PRIMITIVES_OUT, + true, + ); + } + if pipeline_statistics + .contains(&"fragment-shader-invocations".to_string()) + { + pipeline_statistics_names.set( + wgpu_types::PipelineStatisticsTypes::FRAGMENT_SHADER_INVOCATIONS, + true, + ); + } + if pipeline_statistics + .contains(&"compute-shader-invocations".to_string()) + { + pipeline_statistics_names.set( + wgpu_types::PipelineStatisticsTypes::COMPUTE_SHADER_INVOCATIONS, + true, + ); + } + }; + + wgpu_types::QueryType::PipelineStatistics(pipeline_statistics_names) + } + "occlusion" => return Err(not_supported()), + "timestamp" => wgpu_types::QueryType::Timestamp, + _ => unreachable!(), + }, + count: args.count, + }; + + let query_set = gfx_select_err!(device => instance.device_create_query_set( + device, + &descriptor, + std::marker::PhantomData + ))?; + + let rid = state.resource_table.add(WebGPUQuerySet(query_set)); + + Ok(json!({ + "rid": rid, + })) +} diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 796e1f9b5bc909..3edf5e2f83e2ab 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -9,10 +9,6 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; -use super::sampler::serialize_compare_function; -use super::texture::serialize_texture_format; -use crate::shader::WebGPUShaderModule; - pub(crate) struct WebGPUPipelineLayout( pub(crate) wgpu_core::id::PipelineLayoutId, ); @@ -72,7 +68,7 @@ fn serialize_stencil_face_state( .compare .as_ref() .map_or(wgpu_types::CompareFunction::Always, |op| { - serialize_compare_function(op) + super::sampler::serialize_compare_function(op) }), fail_op: state .fail_op @@ -193,15 +189,15 @@ pub fn op_webgpu_create_compute_pipeline( let compute_shader_module_resource = state .resource_table - .get::(args.compute.module) + .get::(args.compute.module) .ok_or_else(bad_resource_id)?; let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), layout: pipeline_layout, stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: compute_shader_module_resource.0, - entry_point: Cow::Owned(args.compute.entry_point), + entry_point: Cow::from(args.compute.entry_point), }, }; let implicit_pipelines = match args.layout { @@ -416,14 +412,14 @@ pub fn op_webgpu_create_render_pipeline( .ok_or_else(bad_resource_id)?; let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), layout, vertex: wgpu_core::pipeline::VertexState { stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: vertex_shader_module_resource.0, - entry_point: Cow::Owned(args.vertex.entry_point), + entry_point: Cow::from(args.vertex.entry_point), }, - buffers: Cow::Owned(if let Some(buffers) = args.vertex.vertex_buffers { + buffers: Cow::from(if let Some(buffers) = args.vertex.vertex_buffers { let mut return_buffers = vec![]; for buffer in buffers { if let Some(buffer) = buffer { @@ -437,7 +433,7 @@ pub fn op_webgpu_create_render_pipeline( }, None => wgpu_types::InputStepMode::Vertex, }, - attributes: Cow::Owned( + attributes: Cow::from( buffer .attributes .iter() @@ -478,7 +474,7 @@ pub fn op_webgpu_create_render_pipeline( offset: attribute.offset, shader_location: attribute.shader_location, }) - .collect(), + .collect::>(), ), }) } @@ -572,9 +568,9 @@ pub fn op_webgpu_create_render_pipeline( wgpu_core::pipeline::FragmentState { stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: fragment_shader_module_resource.0, - entry_point: Cow::Owned(fragment.entry_point), + entry_point: Cow::from(fragment.entry_point), }, - targets: Cow::Owned( + targets: Cow::from( fragment .targets .iter() @@ -587,7 +583,10 @@ pub fn op_webgpu_create_render_pipeline( }); wgpu_types::ColorTargetState { - format: serialize_texture_format(&target.format).unwrap(), + format: super::texture::serialize_texture_format( + &target.format, + ) + .unwrap(), alpha_blend: blends .clone() .map_or(Default::default(), |states| states.0), @@ -600,7 +599,7 @@ pub fn op_webgpu_create_render_pipeline( }), } }) - .collect(), + .collect::>(), ), } }), diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index ec87c075bd2974..a103539350e983 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -157,6 +157,105 @@ pub fn op_webgpu_render_pass_set_stencil_reference( Ok(json!({})) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassBeginPipelineStatisticsQueryArgs { + render_pass_rid: u32, + query_set: u32, + query_index: u32, +} + +pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassBeginPipelineStatisticsQueryArgs = + serde_json::from_value(args)?; + + let render_pass_resource = state + .resource_table + .get::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query( + &mut render_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassEndPipelineStatisticsQueryArgs { + render_pass_rid: u32, +} + +pub fn op_webgpu_render_pass_end_pipeline_statistics_query( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassEndPipelineStatisticsQueryArgs = + serde_json::from_value(args)?; + + let render_pass_resource = state + .resource_table + .get::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query( + &mut render_pass_resource.0.borrow_mut(), + ); + } + + Ok(json!({})) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenderPassWriteTimestampArgs { + render_pass_rid: u32, + query_set: u32, + query_index: u32, +} + +pub fn op_webgpu_render_pass_write_timestamp( + state: &mut OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + let args: RenderPassWriteTimestampArgs = serde_json::from_value(args)?; + + let render_pass_resource = state + .resource_table + .get::(args.render_pass_rid) + .ok_or_else(bad_resource_id)?; + let query_set_resource = state + .resource_table + .get::(args.query_set) + .ok_or_else(bad_resource_id)?; + + unsafe { + wgpu_core::command::render_ffi::wgpu_render_pass_write_timestamp( + &mut render_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); + } + + Ok(json!({})) +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassExecuteBundlesArgs { diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index e13c1e993e5f8f..fbc5e36149f90e 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -98,7 +98,7 @@ pub fn op_webgpu_create_sampler( .unwrap(); let descriptor = wgpu_core::resource::SamplerDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), address_modes: [ serialize_address_mode(args.address_mode_u), serialize_address_mode(args.address_mode_v), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index c65924575e2d93..c3d569dcbce382 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -48,20 +48,18 @@ pub fn op_webgpu_create_shader_module( let source = match args.code { Some(code) => { - wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code)) - } - None => { - wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Borrowed(unsafe { - let (prefix, data, suffix) = zero_copy[0].align_to::(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data - })) + wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::from(code)) } + None => wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::from(unsafe { + let (prefix, data, suffix) = zero_copy[0].align_to::(); + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + data + })), }; let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), flags: Default::default(), }; diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index ced8b2ce0ad6b5..ae208e20aa5fa2 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -108,9 +108,9 @@ pub fn serialize_texture_format( } pub fn serialize_dimension( - dimension: &String, + dimension: &str, ) -> wgpu_types::TextureViewDimension { - match dimension.as_str() { + match dimension { "1d" => wgpu_types::TextureViewDimension::D1, "2d" => wgpu_types::TextureViewDimension::D2, "2d-array" => wgpu_types::TextureViewDimension::D2Array, @@ -164,7 +164,7 @@ pub fn op_webgpu_create_texture( .unwrap(); let descriptor = wgpu_core::resource::TextureDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), size: wgpu_types::Extent3d { width: args.size.width.unwrap_or(1), height: args.size.height.unwrap_or(1), @@ -234,7 +234,7 @@ pub fn op_webgpu_create_texture_view( .unwrap(); let descriptor = wgpu_core::resource::TextureViewDescriptor { - label: args.label.map(Cow::Owned), + label: args.label.map(Cow::from), format: args .format .map(|s| serialize_texture_format(&s)) diff --git a/runtime/ops/webgpu.rs b/runtime/ops/webgpu.rs index 954eff61d18f03..0459f4d057c546 100644 --- a/runtime/ops/webgpu.rs +++ b/runtime/ops/webgpu.rs @@ -16,6 +16,11 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_request_device", op_webgpu_request_device, ); + super::reg_json_async( + rt, + "op_webgpu_create_query_set", + op_webgpu_create_query_set, + ); { // buffer @@ -154,6 +159,16 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_command_encoder_insert_debug_marker", command_encoder::op_webgpu_command_encoder_insert_debug_marker, ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_write_timestamp", + command_encoder::op_webgpu_command_encoder_write_timestamp, + ); + super::reg_json_sync( + rt, + "op_webgpu_command_encoder_resolve_query_set", + command_encoder::op_webgpu_command_encoder_resolve_query_set, + ); super::reg_json_sync( rt, "op_webgpu_command_encoder_finish", @@ -182,6 +197,21 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_render_pass_set_stencil_reference", render_pass::op_webgpu_render_pass_set_stencil_reference, ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_begin_pipeline_statistics_query", + render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_end_pipeline_statistics_query", + render_pass::op_webgpu_render_pass_end_pipeline_statistics_query, + ); + super::reg_json_sync( + rt, + "op_webgpu_render_pass_write_timestamp", + render_pass::op_webgpu_render_pass_write_timestamp, + ); super::reg_json_sync( rt, "op_webgpu_render_pass_execute_bundles", From 737e0b3030aa6cd19f1c50db5fa6f56bd3ba2d1f Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 17:58:48 +0100 Subject: [PATCH 054/144] use symbol instead of weakmaps --- op_crates/webgpu/14_webgpu.js | 220 ++++++++++++++-------------------- 1 file changed, 87 insertions(+), 133 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index e7dd3087330182..53476174ed01b8 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -3,6 +3,8 @@ ((window) => { const core = window.Deno.core; + const ridSymbol = Symbol("rid"); + function normalizeGPUExtent3D(data) { if (Array.isArray(data)) { return { @@ -144,15 +146,13 @@ ...descriptor, }); - const buffer = new GPUBuffer( + return new GPUBuffer( rid, this.#rid, descriptor.label, descriptor.size, descriptor.mappedAtCreation, ); - GPUBufferMap.set(buffer, rid); - return buffer; } createTexture(descriptor) { @@ -163,9 +163,7 @@ size: normalizeGPUExtent3D(descriptor.size), }); - const texture = new GPUTexture(rid, descriptor.label); - GPUTextureMap.set(texture, rid); - return texture; + return new GPUTexture(rid, descriptor.label); } createSampler(descriptor = {}) { @@ -175,9 +173,7 @@ ...descriptor, }); - const sampler = new GPUSampler(descriptor.label); - GPUSamplerMap.set(sampler, rid); - return sampler; + return new GPUSampler(rid, descriptor.label); } createBindGroupLayout(descriptor) { @@ -199,9 +195,7 @@ ...descriptor, }); - const bindGroupLayout = new GPUBindGroupLayout(descriptor.label); - GPUBindGroupLayoutMap.set(bindGroupLayout, rid); - return bindGroupLayout; + return new GPUBindGroupLayout(rid, descriptor.label); } createPipelineLayout(descriptor) { @@ -209,14 +203,10 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => { - return GPUBindGroupLayoutMap.get(bindGroupLayout); - }), + bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => bindGroupLayout[ridSymbol]), }); - const pipelineLayout = new GPUPipelineLayout(descriptor.label); - GPUPipelineLayoutMap.set(pipelineLayout, rid); - return pipelineLayout; + return new GPUPipelineLayout(rid, descriptor.label); } createBindGroup(descriptor) { @@ -224,25 +214,25 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - layout: GPUBindGroupLayoutMap.get(descriptor.layout), + layout: descriptor.layout[ridSymbol], entries: descriptor.entries.map((entry) => { if (entry instanceof GPUSampler) { return { binding: entry.binding, kind: "GPUSampler", - resource: GPUSamplerMap.get(entry.resource), + resource: entry.resource[ridSymbol], }; } else if (entry instanceof GPUTextureView) { return { binding: entry.binding, kind: "GPUTextureView", - resource: GPUTextureViewMap.get(entry.resource), + resource: entry.resource[ridSymbol], }; } else { return { binding: entry.binding, kind: "GPUBufferBinding", - resource: GPUBufferMap.get(entry.resource.buffer), + resource: entry.resource.buffer[ridSymbol], offset: entry.resource.offset, size: entry.resource.size, }; @@ -250,9 +240,7 @@ }), }); - const bindGroup = new GPUBindGroup(descriptor.label); - GPUBindGroupMap.set(bindGroup, rid); - return bindGroup; + return new GPUBindGroup(rid, descriptor.label); } createShaderModule(descriptor) { @@ -270,9 +258,7 @@ (descriptor.code instanceof Uint32Array) ? descriptor.code : undefined, ); - const shaderModule = new GPUShaderModule(rid, descriptor.label); - GPUShaderModuleMap.set(shaderModule, rid); - return shaderModule; + return new GPUShaderModule(rid, descriptor.label); } createComputePipeline(descriptor) { @@ -281,17 +267,15 @@ deviceRid: this.#rid, label: descriptor.label, layout: descriptor.layout - ? GPUPipelineLayoutMap.get(descriptor.layout) + ? descriptor.layout[ridSymbol] : undefined, computeStage: { - module: GPUShaderModuleMap.get(descriptor.computeStage.module), + module: descriptor.computeStage.module[ridSymbol], entryPoint: descriptor.computeStage.entryPoint, }, }); - const pipeline = new GPUComputePipeline(rid, descriptor.label); - GPUComputePipelineMap.set(pipeline, rid); - return pipeline; + return new GPUComputePipeline(rid, descriptor.label); } createRenderPipeline(descriptor) { @@ -301,9 +285,7 @@ ...descriptor, }); - const pipeline = new GPURenderPipeline(rid, descriptor.label); - GPURenderPipelineMap.set(pipeline, rid); - return pipeline; + return new GPURenderPipeline(rid, descriptor.label); } createComputePipelineAsync(_descriptor) { @@ -343,9 +325,7 @@ ...descriptor, }); - const querySet = new GPUQuerySet(descriptor.label); - GPUQuerySetMap.set(querySet, rid); - return querySet; + return new GPUQuerySet(rid, descriptor.label); } } @@ -360,9 +340,7 @@ core.jsonOpSync("op_webgpu_queue_submit", { instanceRid, queueRid: this.#rid, - commandBuffers: commandBuffers.map((buffer) => - GPUCommandBufferMap.get(buffer) - ), + commandBuffers: commandBuffers.map((buffer) => buffer[ridSymbol]), }); } @@ -375,7 +353,7 @@ { instanceRid, queueRid: this.#rid, - buffer: GPUBufferMap.get(buffer), + buffer: buffer[ridSymbol], bufferOffset, dataOffset, size, @@ -391,7 +369,7 @@ instanceRid, queueRid: this.#rid, destination: { - texture: GPUTextureMap.get(destination.texture), + texture: destination.texture[ridSymbol], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -408,9 +386,7 @@ } } - const GPUBufferMap = new WeakMap(); class GPUBuffer { - #rid; #deviceRid; #size; #mappedSize; @@ -419,7 +395,7 @@ #mappedBuffer; constructor(rid, deviceRid, label, size, mappedAtCreation) { - this.#rid = rid; + this[ridSymbol] = rid; this.#deviceRid = deviceRid; this.label = label ?? null; this.#size = size; @@ -435,7 +411,7 @@ this.#mappedSize = size ?? (this.#size - offset); await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { instanceRid, - bufferRid: this.#rid, + bufferRid: this[ridSymbol], deviceRid: this.#deviceRid, mode, offset, @@ -449,7 +425,7 @@ "op_webgpu_buffer_get_mapped_range", { instanceRid, - bufferRid: this.#rid, + bufferRid: this[ridSymbol], offset, size: size ?? this.#mappedSize, }, @@ -464,7 +440,7 @@ unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { instanceRid, - bufferRid: this.#rid, + bufferRid: this[ridSymbol], mappedRid: this.#mappedRid, }, this.#mappedBuffer); } @@ -474,24 +450,20 @@ } } - const GPUTextureMap = new WeakMap(); class GPUTexture { - #rid; constructor(rid, label) { - this.#rid = rid; + this[ridSymbol] = rid; this.label = label ?? null; } createView(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { instanceRid, - textureRid: this.#rid, + textureRid: this[ridSymbol], ...descriptor, }); - const view = new GPUTextureView(); - GPUTextureViewMap.set(view, rid); - return view; + return new GPUTextureView(rid); // TODO(@crowlKats): label? } destroy() { @@ -499,46 +471,44 @@ } } - const GPUTextureViewMap = new WeakMap(); class GPUTextureView { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUSamplerMap = new WeakMap(); class GPUSampler { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUBindGroupLayoutMap = new WeakMap(); class GPUBindGroupLayout { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUPipelineLayoutMap = new WeakMap(); class GPUPipelineLayout { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUBindGroupMap = new WeakMap(); class GPUBindGroup { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUShaderModuleMap = new WeakMap(); class GPUShaderModule { - #rid; constructor(rid, label) { - this.#rid = rid; + this[ridSymbol] = rid; this.label = label ?? null; } @@ -547,12 +517,9 @@ } } - const GPUComputePipelineMap = new WeakMap(); class GPUComputePipeline { - #rid; - constructor(rid, label) { - this.#rid = rid; + this[ridSymbol] = rid; this.label = label ?? null; } @@ -561,23 +528,18 @@ "op_webgpu_compute_pipeline_get_bind_group_layout", { instanceRid, - computePipelineRid: this.#rid, + computePipelineRid: this[ridSymbol], index, }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO(@crowlKats): label? - GPUBindGroupLayoutMap.set(bindGroupLayout, rid); - return bindGroupLayout; + return new GPUBindGroupLayout(rid); // TODO(@crowlKats): label? } } - const GPURenderPipelineMap = new WeakMap(); class GPURenderPipeline { - #rid; - constructor(rid, label) { - this.#rid = rid; + this[ridSymbol] = rid; this.label = label ?? null; } @@ -586,14 +548,12 @@ "op_webgpu_render_pipeline_get_bind_group_layout", { instanceRid, - renderPipelineRid: this.#rid, + renderPipelineRid: this[ridSymbol], index, }, ); - const bindGroupLayout = new GPUBindGroupLayout(); // TODO(@crowlKats): label? - GPUBindGroupLayoutMap.set(bindGroupLayout, rid); - return bindGroupLayout; + return new GPUBindGroupLayout(rid); // TODO(@crowlKats): label? } } @@ -610,9 +570,7 @@ if (descriptor.depthStencilAttachment) { depthStencilAttachment = { ...descriptor.depthStencilAttachment, - attachment: GPUTextureViewMap.get( - descriptor.depthStencilAttachment.attachment, - ), + view: descriptor.depthStencilAttachment.view[ridSymbol], }; if ( @@ -646,9 +604,9 @@ colorAttachments: descriptor.colorAttachments.map( (colorAttachment) => { const attachment = { - attachment: GPUTextureViewMap.get(colorAttachment.attachment), + view: colorAttachment.view[ridSymbol], resolveTarget: colorAttachment.resolveTarget - ? GPUTextureViewMap.get(colorAttachment.resolveTarget) + ? colorAttachment.resolveTarget[ridSymbol] : undefined, storeOp: colorAttachment.storeOp, }; @@ -696,9 +654,9 @@ { instanceRid, commandEncoderRid: this.#rid, - source: GPUBufferMap.get(source), + source: source[ridSymbol], sourceOffset, - destination: GPUBufferMap.get(destination), + destination: destination[ridSymbol], destinationOffset, size, }, @@ -713,10 +671,10 @@ commandEncoderRid: this.#rid, source: { ...source, - buffer: GPUBufferMap.get(source.buffer), + buffer: source.buffer[ridSymbol], }, destination: { - texture: GPUTextureMap.get(destination.texture), + texture: destination.texture[ridSymbol], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -733,13 +691,13 @@ instanceRid, commandEncoderRid: this.#rid, source: { - texture: GPUTextureMap.get(source.texture), + texture: source.texture[ridSymbol], mipLevel: source.mipLevel, origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { ...destination, - buffer: GPUBufferMap.get(destination.buffer), + buffer: destination.buffer[ridSymbol], }, copySize: normalizeGPUExtent3D(copySize), }, @@ -753,12 +711,12 @@ instanceRid, commandEncoderRid: this.#rid, source: { - texture: GPUTextureMap.get(source.texture), + texture: source.texture[ridSymbol], mipLevel: source.mipLevel, origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { - texture: GPUTextureMap.get(destination.texture), + texture: destination.texture[ridSymbol], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -793,7 +751,7 @@ core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { instanceRid, commandEncoderRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], queryIndex, }); } @@ -808,10 +766,10 @@ core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { instanceRid, commandEncoderRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], firstQuery, queryCount, - destination: GPUBufferMap.get(destination), + destination: destination[ridSymbol], destinationOffset, }); } @@ -823,9 +781,7 @@ ...descriptor, }); - const buffer = new GPUCommandBuffer(descriptor.label); - GPUCommandBufferMap.set(buffer, rid); - return buffer; + return new GPUCommandBuffer(rid, descriptor.label); } } @@ -884,7 +840,7 @@ beginPipelineStatisticsQuery(querySet, queryIndex) { core.jsonOpSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { renderPassRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], queryIndex, }); } @@ -897,7 +853,7 @@ writeTimestamp(querySet, queryIndex) { core.jsonOpSync("op_webgpu_render_pass_write_timestamp", { renderPassRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], queryIndex, }); } @@ -905,7 +861,7 @@ executeBundles(bundles) { core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { renderPassRid: this.#rid, - bundles: bundles.map((bundle) => GPURenderBundleMap.get(bundle)), + bundles: bundles.map((bundle) => bundle[ridSymbol]), }); } endPass() { @@ -923,7 +879,7 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = GPUBindGroupMap.get(bindGroup); + const bind = bindGroup[ridSymbol]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_pass_set_bind_group", @@ -970,14 +926,14 @@ setPipeline(pipeline) { core.jsonOpSync("op_webgpu_render_pass_set_pipeline", { renderPassRid: this.#rid, - pipeline: GPURenderPipelineMap.get(pipeline), + pipeline: pipeline[ridSymbol], }); } setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { core.jsonOpSync("op_webgpu_render_pass_set_index_buffer", { renderPassRid: this.#rid, - buffer: GPUBufferMap.get(buffer), + buffer: buffer[ridSymbol], indexFormat, offset, size, @@ -987,7 +943,7 @@ core.jsonOpSync("op_webgpu_render_pass_set_vertex_buffer", { renderPassRid: this.#rid, slot, - buffer: GPUBufferMap.get(buffer), + buffer: buffer[ridSymbol], offset, size, }); @@ -1022,14 +978,14 @@ drawIndirect(indirectBuffer, indirectOffset) { core.jsonOpSync("op_webgpu_render_pass_draw_indirect", { renderPassRid: this.#rid, - indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } drawIndexedIndirect(indirectBuffer, indirectOffset) { core.jsonOpSync("op_webgpu_render_pass_draw_indexed_indirect", { renderPassRid: this.#rid, - indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } @@ -1048,7 +1004,7 @@ setPipeline(pipeline) { core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { computePassRid: this.#rid, - pipeline: GPUComputePipelineMap.get(pipeline), + pipeline: pipeline[ridSymbol], }); } dispatch(x, y = 1, z = 1) { @@ -1062,7 +1018,7 @@ dispatchIndirect(indirectBuffer, indirectOffset) { core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { computePassRid: this.#rid, - indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } @@ -1072,7 +1028,7 @@ "op_webgpu_compute_pass_begin_pipeline_statistics_query", { computePassRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], queryIndex, }, ); @@ -1086,7 +1042,7 @@ writeTimestamp(querySet, queryIndex) { core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { computePassRid: this.#rid, - querySet: GPUQuerySetMap.get(querySet), + querySet: querySet[ridSymbol], queryIndex, }); } @@ -1106,7 +1062,7 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = GPUBindGroupMap.get(bindGroup); + const bind = bindGroup[ridSymbol]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_compute_pass_set_bind_group", @@ -1151,9 +1107,9 @@ } } - const GPUCommandBufferMap = new WeakMap(); class GPUCommandBuffer { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } @@ -1179,9 +1135,7 @@ }, ); - const bundle = new GPURenderBundle(descriptor.label); - GPURenderBundleMap.set(bundle, rid); - return bundle; + return new GPURenderBundle(rid, descriptor.label); } setBindGroup( @@ -1191,7 +1145,7 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = GPUBindGroupMap.get(bindGroup); + const bind = bindGroup[ridSymbol]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_bundle_encoder_set_bind_group", @@ -1238,14 +1192,14 @@ setPipeline(pipeline) { core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { renderBundleEncoderRid: this.#rid, - pipeline: GPURenderPipelineMap.get(pipeline), + pipeline: pipeline[ridSymbol], }); } setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { renderBundleEncoderRid: this.#rid, - buffer: GPUBufferMap.get(buffer), + buffer: buffer[ridSymbol], indexFormat, offset, size, @@ -1255,7 +1209,7 @@ core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { renderBundleEncoderRid: this.#rid, slot, - buffer: GPUBufferMap.get(buffer), + buffer: buffer[ridSymbol], offset, size, }); @@ -1290,7 +1244,7 @@ drawIndirect(indirectBuffer, indirectOffset) { core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { renderBundleEncoderRid: this.#rid, - indirectBuffer: GPUBufferMap.get(indirectBuffer), + indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } @@ -1299,16 +1253,16 @@ } } - const GPURenderBundleMap = new WeakMap(); class GPURenderBundle { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } } - const GPUQuerySetMap = new WeakMap(); class GPUQuerySet { - constructor(label) { + constructor(rid, label) { + this[ridSymbol] = rid; this.label = label ?? null; } From c77be719f39bd0e527e68f98609b23708e3d0990 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 18:12:20 +0100 Subject: [PATCH 055/144] add missing labels --- op_crates/webgpu/14_webgpu.js | 18 +++++++++--------- op_crates/webgpu/pipeline.rs | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 53476174ed01b8..bf17e857d8e2a4 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -203,7 +203,9 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => bindGroupLayout[ridSymbol]), + bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => + bindGroupLayout[ridSymbol] + ), }); return new GPUPipelineLayout(rid, descriptor.label); @@ -266,9 +268,7 @@ instanceRid, deviceRid: this.#rid, label: descriptor.label, - layout: descriptor.layout - ? descriptor.layout[ridSymbol] - : undefined, + layout: descriptor.layout ? descriptor.layout[ridSymbol] : undefined, computeStage: { module: descriptor.computeStage.module[ridSymbol], entryPoint: descriptor.computeStage.entryPoint, @@ -463,7 +463,7 @@ ...descriptor, }); - return new GPUTextureView(rid); // TODO(@crowlKats): label? + return new GPUTextureView(rid, descriptor.label); } destroy() { @@ -524,7 +524,7 @@ } getBindGroupLayout(index) { - const { rid } = core.jsonOpSync( + const { rid, label } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", { instanceRid, @@ -533,7 +533,7 @@ }, ); - return new GPUBindGroupLayout(rid); // TODO(@crowlKats): label? + return new GPUBindGroupLayout(rid, label); } } @@ -544,7 +544,7 @@ } getBindGroupLayout(index) { - const { rid } = core.jsonOpSync( + const { rid, label } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", { instanceRid, @@ -553,7 +553,7 @@ }, ); - return new GPUBindGroupLayout(rid); // TODO(@crowlKats): label? + return new GPUBindGroupLayout(rid, label); } } diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 3edf5e2f83e2ab..6bb4404c2b1bfb 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -256,12 +256,15 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( let bind_group_layout = gfx_select_err!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData))?; + let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); + let rid = state .resource_table .add(super::binding::WebGPUBindGroupLayout(bind_group_layout)); Ok(json!({ "rid": rid, + "label": label, })) } @@ -661,11 +664,14 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( let bind_group_layout = gfx_select_err!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData))?; + let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); + let rid = state .resource_table .add(super::binding::WebGPUBindGroupLayout(bind_group_layout)); Ok(json!({ "rid": rid, + "label": label, })) } From 75e60f2fd980b144a5ce902dc54d8a8496367f52 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 18:28:02 +0100 Subject: [PATCH 056/144] clean up comments --- op_crates/webgpu/14_webgpu.js | 4 ++-- op_crates/webgpu/command_encoder.rs | 2 +- op_crates/webgpu/shader.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index bf17e857d8e2a4..b4d842625c8525 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -831,10 +831,10 @@ } beginOcclusionQuery(_queryIndex) { - throw new Error("Not yet implemented"); // wgpu#721 + throw new Error("Not yet implemented"); } endOcclusionQuery() { - throw new Error("Not yet implemented"); // wgpu#721 + throw new Error("Not yet implemented"); } beginPipelineStatisticsQuery(querySet, queryIndex) { diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index d34fc36947c69a..ee3ab603d3e322 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -365,7 +365,7 @@ pub struct GPUImageCopyTexture { pub texture: u32, pub mip_level: Option, pub origin: Option, - pub aspect: Option, // not yet implemented + pub _aspect: Option, // not yet implemented } #[derive(Deserialize)] diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index c3d569dcbce382..9bc54787c08be4 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -23,7 +23,7 @@ struct CreateShaderModuleArgs { device_rid: u32, label: Option, code: Option, - _source_map: Option<()>, // not in wgpu + _source_map: Option<()>, // not yet implemented } pub fn op_webgpu_create_shader_module( From 4d064ffeb1f4c8114e293ca373c69d62db0c6792 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 22:12:42 +0100 Subject: [PATCH 057/144] clear some todos --- op_crates/webgpu/lib.rs | 43 ++++++++++++++++++++++++++---------- op_crates/webgpu/pipeline.rs | 14 ++++++++---- runtime/ops/webgpu.rs | 2 +- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index c2422b0ebd8aa2..5a19148b2b4a75 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -107,9 +107,15 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { if features.contains(wgpu_types::Features::DEPTH_CLAMPING) { return_features.push("depth-clamping"); } + if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { + return_features.push("pipeline-statistics-query"); + } if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { return_features.push("texture-compression-bc"); } + if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { + return_features.push("timestamp-query"); + } return_features } @@ -206,6 +212,10 @@ pub async fn op_webgpu_request_adapter( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GPULimits { + _max_texture_dimension1d: Option, + _max_texture_dimension2d: Option, + _max_texture_dimension3d: Option, + _max_texture_array_layers: Option, max_bind_groups: Option, max_dynamic_uniform_buffers_per_pipeline_layout: Option, max_dynamic_storage_buffers_per_pipeline_layout: Option, @@ -215,6 +225,10 @@ struct GPULimits { max_storage_textures_per_shader_stage: Option, max_uniform_buffers_per_shader_stage: Option, max_uniform_buffer_binding_size: Option, + _max_storage_buffer_binding_size: Option, + _max_vertex_buffers: Option, + _max_vertex_attributes: Option, + _max_vertex_buffer_array_stride: Option, } #[derive(Deserialize)] @@ -224,7 +238,7 @@ struct RequestDeviceArgs { adapter_rid: u32, label: Option, non_guaranteed_features: Option>, - non_guaranteed_limits: Option, // TODO + non_guaranteed_limits: Option, } pub async fn op_webgpu_request_device( @@ -248,16 +262,21 @@ pub async fn op_webgpu_request_device( .try_borrow() .unwrap(); - let mut features = wgpu_types::Features::default(); + let mut features: wgpu_types::Features = wgpu_types::Features::empty(); if let Some(passed_features) = args.non_guaranteed_features { if passed_features.contains(&"depth-clamping".to_string()) { features.set(wgpu_types::Features::DEPTH_CLAMPING, true); } + if passed_features.contains(&"pipeline-statistics-query".to_string()) { + features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true); + } if passed_features.contains(&"texture-compression-bc".to_string()) { features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true); } - // TODO + if passed_features.contains(&"timestamp-query".to_string()) { + features.set(wgpu_types::Features::TIMESTAMP_QUERY, true); + } } let descriptor = wgpu_types::DeviceDescriptor { @@ -307,15 +326,15 @@ pub async fn op_webgpu_request_device( let features = deserialize_features(&device_features); let limits = gfx_select!(device => instance.device_limits(device))?; let json_limits = json!({ - "max_bind_groups": limits.max_bind_groups, - "max_dynamic_uniform_buffers_per_pipeline_layout": limits.max_dynamic_uniform_buffers_per_pipeline_layout, - "max_dynamic_storage_buffers_per_pipeline_layout": limits.max_dynamic_storage_buffers_per_pipeline_layout, - "max_sampled_textures_per_shader_stage": limits.max_sampled_textures_per_shader_stage, - "max_samplers_per_shader_stage": limits.max_samplers_per_shader_stage, - "max_storage_buffers_per_shader_stage": limits.max_storage_buffers_per_shader_stage, - "max_storage_textures_per_shader_stage": limits.max_storage_textures_per_shader_stage, - "max_uniform_buffers_per_shader_stage": limits.max_uniform_buffers_per_shader_stage, - "max_uniform_buffer_binding_size": limits.max_uniform_buffer_binding_size, + "maxBindGroups": limits.max_bind_groups, + "maxDynamicUniformBuffersPerPipelineLayout": limits.max_dynamic_uniform_buffers_per_pipeline_layout, + "maxDynamicStorageBuffersPerPipelineLayout": limits.max_dynamic_storage_buffers_per_pipeline_layout, + "maxSampledTexturesPerShaderStage": limits.max_sampled_textures_per_shader_stage, + "maxSamplersPerShaderStage": limits.max_samplers_per_shader_stage, + "maxStorageBuffersPerShaderStage": limits.max_storage_buffers_per_shader_stage, + "maxStorageTexturesPerShaderStage": limits.max_storage_textures_per_shader_stage, + "maxUniformBuffersPerShaderStage": limits.max_uniform_buffers_per_shader_stage, + "maxUniformBufferBindingSize": limits.max_uniform_buffer_binding_size, }); let rid = state.resource_table.add(WebGPUDevice(device)); diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 6bb4404c2b1bfb..57d73cfebe8391 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -208,14 +208,17 @@ pub fn op_webgpu_create_compute_pipeline( }), }; - // TODO - let (compute_pipeline, _, _) = gfx_select!(device => instance.device_create_compute_pipeline( + let (compute_pipeline, _, err) = gfx_select!(device => instance.device_create_compute_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines )); + if let Some(err) = err { + return Err(err.into()); + } + let rid = state .resource_table .add(WebGPUComputePipeline(compute_pipeline)); @@ -616,14 +619,17 @@ pub fn op_webgpu_create_render_pipeline( }), }; - // TODO - let (render_pipeline, _, _) = gfx_select!(device => instance.device_create_render_pipeline( + let (render_pipeline, _, err) = gfx_select!(device => instance.device_create_render_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines )); + if let Some(err) = err { + return Err(err.into()); + } + let rid = state .resource_table .add(WebGPURenderPipeline(render_pipeline)); diff --git a/runtime/ops/webgpu.rs b/runtime/ops/webgpu.rs index 0459f4d057c546..aac77bee56a115 100644 --- a/runtime/ops/webgpu.rs +++ b/runtime/ops/webgpu.rs @@ -16,7 +16,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { "op_webgpu_request_device", op_webgpu_request_device, ); - super::reg_json_async( + super::reg_json_sync( rt, "op_webgpu_create_query_set", op_webgpu_create_query_set, From 463d2f7379c353364842439fd392d0dff4359a5d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 9 Feb 2021 23:17:36 +0100 Subject: [PATCH 058/144] fix bugs --- op_crates/webgpu/14_webgpu.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index b4d842625c8525..b150210b9f3a72 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -179,10 +179,10 @@ createBindGroupLayout(descriptor) { for (const entry of descriptor.entries) { let i = 0; - if (descriptor.buffer) i++; - if (descriptor.sampler) i++; - if (descriptor.texture) i++; - if (descriptor.storageTexture) i++; + if (entry.buffer) i++; + if (entry.sampler) i++; + if (entry.texture) i++; + if (entry.storageTexture) i++; if (i !== 1) { throw new Error(); // TODO(@crowlKats): correct error @@ -257,7 +257,7 @@ : undefined, sourceMap: descriptor.sourceMap, }, - (descriptor.code instanceof Uint32Array) ? descriptor.code : undefined, + ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []) ); return new GPUShaderModule(rid, descriptor.label); @@ -269,9 +269,9 @@ deviceRid: this.#rid, label: descriptor.label, layout: descriptor.layout ? descriptor.layout[ridSymbol] : undefined, - computeStage: { - module: descriptor.computeStage.module[ridSymbol], - entryPoint: descriptor.computeStage.entryPoint, + compute: { + module: descriptor.compute.module[ridSymbol], + entryPoint: descriptor.compute.entryPoint, }, }); From 2cc9d3c5c1c4cb8d4836dd791846bf1f2c3a3279 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 9 Feb 2021 23:24:54 +0100 Subject: [PATCH 059/144] fix build --- op_crates/webgpu/buffer.rs | 2 +- op_crates/webgpu/command_encoder.rs | 8 ++------ op_crates/webgpu/lib.rs | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index f761c5e2dc666c..2b7a34fc536b59 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -159,7 +159,7 @@ pub async fn op_webgpu_buffer_get_map_async( .get::(instance_rid) .ok_or_else(bad_resource_id)?; let instance = &instance_resource.0; - wgc::gfx_select!(device => instance.device_poll(device, false)).unwrap() + gfx_select!(device => instance.device_poll(device, false)).unwrap() } tokio::time::sleep(Duration::from_millis(10)).await; } diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 08e3e8966aa23f..b43bfccba1fa56 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -700,9 +700,7 @@ pub fn op_webgpu_command_encoder_write_timestamp( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let query_set_resource = state .resource_table .get::(args.query_set) @@ -745,9 +743,7 @@ pub fn op_webgpu_command_encoder_resolve_query_set( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let query_set_resource = state .resource_table .get::(args.query_set) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 63dcff7cabb30d..4c9a1e5088cfc8 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -60,7 +60,9 @@ pub mod sampler; pub mod shader; pub mod texture; -struct WebGPUInstance(wgc::hub::Global); +struct WebGPUInstance( + wgpu_core::hub::Global, +); impl Resource for WebGPUInstance { fn name(&self) -> Cow { "webGPUInstance".into() @@ -368,9 +370,7 @@ pub fn op_webgpu_create_query_set( .resource_table .get::(args.instance_rid) .ok_or_else(bad_resource_id)?; - let instance = RcRef::map(&instance_resource, |r| &r.0) - .try_borrow() - .unwrap(); + let instance = &instance_resource.0; let descriptor = wgpu_types::QuerySetDescriptor { ty: match args.kind.as_str() { From bb275ebc8b77304c87ed208c23f6ebf9c6f73b78 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:58:47 +0100 Subject: [PATCH 060/144] get rid of segfault via experimental means on macos x86 --- op_crates/webgpu/shader.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 7bfce44cf9d098..86f745bfd9324e 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -56,9 +56,14 @@ pub fn op_webgpu_create_shader_module( })), }; + let mut flags = wgpu_types::ShaderFlags::default(); + flags.set(wgpu_types::ShaderFlags::VALIDATION, true); + #[cfg(all(target_os = "macos", target_arch = "x86_64"))] + flags.set(wgpu_types::ShaderFlags::EXPERIMENTAL_TRANSLATION, true); + let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { label: args.label.map(Cow::from), - flags: Default::default(), + flags, }; let shader_module = gfx_select_err!(device => instance.device_create_shader_module( From 12bbab9d6a50846523ae84d6e66ff332fe8ae545 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 03:37:11 +0100 Subject: [PATCH 061/144] add tracing --- Cargo.lock | 19 +++++++++++++++++-- op_crates/webgpu/Cargo.toml | 2 +- op_crates/webgpu/lib.rs | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f0aa317f2cdd9..bd13fc35320f48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1366,9 +1366,9 @@ dependencies = [ [[package]] name = "gpu-descriptor" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d74668a6a6f0202e29f212a6d47ef8c7e092a76f4ab267b0065b6e0d175e45c6" +checksum = "e8a70f1e87a3840ed6a3e99e02c2b861e4dbdf26f0d07e38f42ea5aff46cfce2" dependencies = [ "bitflags", "gpu-descriptor-types", @@ -1890,6 +1890,7 @@ dependencies = [ "log", "num-traits", "petgraph", + "serde", "spirv_headers", "thiserror", ] @@ -2564,6 +2565,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ron" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064ea8613fb712a19faf920022ec8ddf134984f100090764a4e1d768f3827f1f" +dependencies = [ + "base64 0.13.0", + "bitflags", + "serde", +] + [[package]] name = "rustc_version" version = "0.2.3" @@ -3981,6 +3993,8 @@ dependencies = [ "gpu-descriptor", "naga", "parking_lot", + "ron", + "serde", "smallvec", "thiserror", "tracing", @@ -3994,6 +4008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72fa9ba80626278fd87351555c363378d08122d7601e58319be3d6fa85a87747" dependencies = [ "bitflags", + "serde", ] [[package]] diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index 0d4b96f5be4e07..5a834318415521 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -17,5 +17,5 @@ path = "lib.rs" deno_core = { version = "0.78.0", path = "../../core" } tokio = { version = "1.1.1", features = ["full"] } serde = { version = "1.0.121", features = ["derive"] } -wgpu-core = "0.7.0" +wgpu-core = { version = "0.7.0", features = ["trace"] } wgpu-types = "0.7.0" diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 4c9a1e5088cfc8..d1aa2b40caabf0 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -313,7 +313,7 @@ pub async fn op_webgpu_request_device( let device = gfx_select_err!(adapter => instance.adapter_request_device( adapter, &descriptor, - None, + Some(std::path::Path::new("./trace")), // TODO: remove std::marker::PhantomData ))?; From 4aa05db0c31539dd2fc4e0c5c6e19158d5eb86ce Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 11:25:56 +0100 Subject: [PATCH 062/144] don't copy mapped buffer --- op_crates/webgpu/buffer.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 2b7a34fc536b59..a55d6d89eb0414 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -21,7 +21,7 @@ impl Resource for WebGPUBuffer { } } -struct WebGPUBufferMapped(RefCell>); +struct WebGPUBufferMapped(*mut u8, usize); impl Resource for WebGPUBufferMapped { fn name(&self) -> Cow { "webGPUBufferMapped".into() @@ -218,7 +218,7 @@ pub fn op_webgpu_buffer_get_mapped_range( let rid = state .resource_table - .add(WebGPUBufferMapped(RefCell::new(slice.to_vec()))); + .add(WebGPUBufferMapped(slice_pointer, args.size as usize)); Ok(json!({ "rid": rid, @@ -255,10 +255,11 @@ pub fn op_webgpu_buffer_unmap( .ok_or_else(bad_resource_id)?; let instance = &instance_resource.0; - mapped_resource - .0 - .borrow_mut() - .copy_from_slice(&zero_copy[0]); + let slice_pointer = mapped_resource.0; + let size = mapped_resource.1; + + let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) }; + slice.copy_from_slice(&zero_copy[0]); gfx_select!(buffer => instance.buffer_unmap(buffer))?; From b5fc3181428b1626401f7cf146d6fa02319c28dd Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 12:57:12 +0100 Subject: [PATCH 063/144] add unit test --- cli/tests/shader.wgsl | 39 ++++++++++++++ cli/tests/unit/test_util.ts | 2 + cli/tests/unit/unit_tests.ts | 1 + cli/tests/unit/webgpu_test.js | 96 +++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 cli/tests/shader.wgsl create mode 100644 cli/tests/unit/webgpu_test.js diff --git a/cli/tests/shader.wgsl b/cli/tests/shader.wgsl new file mode 100644 index 00000000000000..2433f324335203 --- /dev/null +++ b/cli/tests/shader.wgsl @@ -0,0 +1,39 @@ +[[builtin(global_invocation_id)]] +var global_id: vec3; + +[[block]] +struct PrimeIndices { + data: [[stride(4)]] array; +}; // this is used as both input and output for convenience + +[[group(0), binding(0)]] +var v_indices: [[access(read_write)]] PrimeIndices; + +// The Collatz Conjecture states that for any integer n: +// If n is even, n = n/2 +// If n is odd, n = 3n+1 +// And repeat this process for each new n, you will always eventually reach 1. +// Though the conjecture has not been proven, no counterexample has ever been found. +// This function returns how many times this recurrence needs to be applied to reach 1. +fn collatz_iterations(n_base: u32) -> u32{ + var n: u32 = n_base; + var i: u32 = 0u; + loop { + if (n <= 1u) { + break; + } + if (n % 2u == 0u) { + n = n / 2u; + } + else { + n = 3u * n + 1u; + } + i = i + 1u; + } + return i; +} + +[[stage(compute), workgroup_size(1)]] +fn main() { + v_indices.data[global_id.x] = collatz_iterations(v_indices.data[global_id.x]); +} diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index 6c3c0c6a060643..d6d283cd1c31c7 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -136,6 +136,7 @@ interface UnitTestOptions { ignore?: boolean; only?: boolean; perms?: UnitTestPermissions; + sanitizeResources?: boolean; } interface UnitTestDefinition extends Deno.TestDefinition { @@ -186,6 +187,7 @@ export function unitTest( ignore: !!options.ignore, only: !!options.only, perms: normalizedPerms, + sanitizeResources: !!options.sanitizeResources, }; REGISTERED_UNIT_TESTS.push(unitTestDefinition); diff --git a/cli/tests/unit/unit_tests.ts b/cli/tests/unit/unit_tests.ts index 8af28c1bb76bfb..416e5979160a5f 100644 --- a/cli/tests/unit/unit_tests.ts +++ b/cli/tests/unit/unit_tests.ts @@ -76,3 +76,4 @@ import "./write_text_file_test.ts"; import "./performance_test.ts"; import "./version_test.ts"; import "./websocket_test.ts"; +import "./webgpu_test.js"; diff --git a/cli/tests/unit/webgpu_test.js b/cli/tests/unit/webgpu_test.js new file mode 100644 index 00000000000000..8d5421039dac11 --- /dev/null +++ b/cli/tests/unit/webgpu_test.js @@ -0,0 +1,96 @@ +import { assertEquals, unitTest } from "./test_util.ts"; + +// TODO(lucacasonato): remove sanitizeResources +unitTest({ perms: { read: true }, sanitizeResources: false }, async function webgpuComputePass() { + const numbers = [1, 4, 3, 295]; + + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); + + const shaderModule = device.createShaderModule({ + code: shaderCode, + }); + + const size = new Uint32Array(numbers).byteLength; + + const stagingBuffer = device.createBuffer({ + size: size, + usage: 1 | 8, + }); + + const storageBuffer = device.createBuffer({ + label: "Storage Buffer", + size: size, + usage: 0x80 | 8 | 4, + mappedAtCreation: true, + }); + + const buf = new Uint32Array(storageBuffer.getMappedRange()); + + buf.set(numbers); + + storageBuffer.unmap(); + + const bindGroupLayout = device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: 4, + buffer: { + type: "storage", + minBindingSize: 4, + }, + }, + ], + }); + + const bindGroup = device.createBindGroup({ + layout: bindGroupLayout, + entries: [ + { + binding: 0, + resource: { + buffer: storageBuffer, + }, + }, + ], + }); + + const pipelineLayout = device.createPipelineLayout({ + bindGroupLayouts: [bindGroupLayout], + }); + + const computePipeline = device.createComputePipeline({ + layout: pipelineLayout, + compute: { + module: shaderModule, + entryPoint: "main", + }, + }); + + const encoder = device.createCommandEncoder(); + + const computePass = encoder.beginComputePass(); + computePass.setPipeline(computePipeline); + computePass.setBindGroup(0, bindGroup); + computePass.insertDebugMarker("compute collatz iterations"); + computePass.dispatch(numbers.length); + computePass.endPass(); + + encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); + + device.queue.submit([encoder.finish()]); + + await stagingBuffer.mapAsync(1); + + const data = stagingBuffer.getMappedRange(); + + assertEquals( + new Uint32Array(0, 2, 7, 55).entries(), + new Uint32Array(data).entries(), + ); + + stagingBuffer.unmap(); +}); From e40dbb25226b359ca240ef525d4d1b6a64effbce Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 12:59:19 +0100 Subject: [PATCH 064/144] fmt lint --- cli/tests/unit/webgpu_test.js | 169 +++++++++++++++++----------------- op_crates/webgpu/14_webgpu.js | 2 +- 2 files changed, 88 insertions(+), 83 deletions(-) diff --git a/cli/tests/unit/webgpu_test.js b/cli/tests/unit/webgpu_test.js index 8d5421039dac11..707d0ed9365b31 100644 --- a/cli/tests/unit/webgpu_test.js +++ b/cli/tests/unit/webgpu_test.js @@ -1,96 +1,101 @@ import { assertEquals, unitTest } from "./test_util.ts"; // TODO(lucacasonato): remove sanitizeResources -unitTest({ perms: { read: true }, sanitizeResources: false }, async function webgpuComputePass() { - const numbers = [1, 4, 3, 295]; - - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); - - const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); - - const shaderModule = device.createShaderModule({ - code: shaderCode, - }); - - const size = new Uint32Array(numbers).byteLength; - - const stagingBuffer = device.createBuffer({ - size: size, - usage: 1 | 8, - }); - - const storageBuffer = device.createBuffer({ - label: "Storage Buffer", - size: size, - usage: 0x80 | 8 | 4, - mappedAtCreation: true, - }); - - const buf = new Uint32Array(storageBuffer.getMappedRange()); - - buf.set(numbers); - - storageBuffer.unmap(); - - const bindGroupLayout = device.createBindGroupLayout({ - entries: [ - { - binding: 0, - visibility: 4, - buffer: { - type: "storage", - minBindingSize: 4, +unitTest( + { perms: { read: true }, sanitizeResources: false }, + async function webgpuComputePass() { + const numbers = [1, 4, 3, 295]; + + // TODO(lucacasonato): remove when navigator is added to deno-lint + // deno-lint-ignore no-undef + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); + + const shaderModule = device.createShaderModule({ + code: shaderCode, + }); + + const size = new Uint32Array(numbers).byteLength; + + const stagingBuffer = device.createBuffer({ + size: size, + usage: 1 | 8, + }); + + const storageBuffer = device.createBuffer({ + label: "Storage Buffer", + size: size, + usage: 0x80 | 8 | 4, + mappedAtCreation: true, + }); + + const buf = new Uint32Array(storageBuffer.getMappedRange()); + + buf.set(numbers); + + storageBuffer.unmap(); + + const bindGroupLayout = device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: 4, + buffer: { + type: "storage", + minBindingSize: 4, + }, }, - }, - ], - }); - - const bindGroup = device.createBindGroup({ - layout: bindGroupLayout, - entries: [ - { - binding: 0, - resource: { - buffer: storageBuffer, + ], + }); + + const bindGroup = device.createBindGroup({ + layout: bindGroupLayout, + entries: [ + { + binding: 0, + resource: { + buffer: storageBuffer, + }, }, + ], + }); + + const pipelineLayout = device.createPipelineLayout({ + bindGroupLayouts: [bindGroupLayout], + }); + + const computePipeline = device.createComputePipeline({ + layout: pipelineLayout, + compute: { + module: shaderModule, + entryPoint: "main", }, - ], - }); - - const pipelineLayout = device.createPipelineLayout({ - bindGroupLayouts: [bindGroupLayout], - }); - - const computePipeline = device.createComputePipeline({ - layout: pipelineLayout, - compute: { - module: shaderModule, - entryPoint: "main", - }, - }); + }); - const encoder = device.createCommandEncoder(); + const encoder = device.createCommandEncoder(); - const computePass = encoder.beginComputePass(); - computePass.setPipeline(computePipeline); - computePass.setBindGroup(0, bindGroup); - computePass.insertDebugMarker("compute collatz iterations"); - computePass.dispatch(numbers.length); - computePass.endPass(); + const computePass = encoder.beginComputePass(); + computePass.setPipeline(computePipeline); + computePass.setBindGroup(0, bindGroup); + computePass.insertDebugMarker("compute collatz iterations"); + computePass.dispatch(numbers.length); + computePass.endPass(); - encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); + encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); - device.queue.submit([encoder.finish()]); + device.queue.submit([encoder.finish()]); - await stagingBuffer.mapAsync(1); + await stagingBuffer.mapAsync(1); - const data = stagingBuffer.getMappedRange(); + const data = stagingBuffer.getMappedRange(); - assertEquals( - new Uint32Array(0, 2, 7, 55).entries(), - new Uint32Array(data).entries(), - ); + assertEquals( + new Uint32Array(0, 2, 7, 55).entries(), + new Uint32Array(data).entries(), + ); - stagingBuffer.unmap(); -}); + stagingBuffer.unmap(); + }, +); diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index b150210b9f3a72..a01931ae04723b 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -257,7 +257,7 @@ : undefined, sourceMap: descriptor.sourceMap, }, - ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []) + ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []), ); return new GPUShaderModule(rid, descriptor.label); From 2d03404a5b4bc6132bd54f6a239995394b99aa6b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 13:16:11 +0100 Subject: [PATCH 065/144] remove resource sanitize --- cli/tests/unit/test_util.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index d6d283cd1c31c7..6c3c0c6a060643 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -136,7 +136,6 @@ interface UnitTestOptions { ignore?: boolean; only?: boolean; perms?: UnitTestPermissions; - sanitizeResources?: boolean; } interface UnitTestDefinition extends Deno.TestDefinition { @@ -187,7 +186,6 @@ export function unitTest( ignore: !!options.ignore, only: !!options.only, perms: normalizedPerms, - sanitizeResources: !!options.sanitizeResources, }; REGISTERED_UNIT_TESTS.push(unitTestDefinition); From 69bacfdea48c27468f65856f515801ca7df99631 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 13:33:39 +0100 Subject: [PATCH 066/144] lint --- cli/tests/unit/webgpu_test.js | 9 ++-- op_crates/webgpu/buffer.rs | 95 ++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/cli/tests/unit/webgpu_test.js b/cli/tests/unit/webgpu_test.js index 707d0ed9365b31..13a2734559af68 100644 --- a/cli/tests/unit/webgpu_test.js +++ b/cli/tests/unit/webgpu_test.js @@ -1,14 +1,15 @@ import { assertEquals, unitTest } from "./test_util.ts"; +// TODO(lucacasonato): remove when navigator is added to deno-lint +// deno-lint-ignore no-undef +const adapter = await navigator.gpu.requestAdapter(); + // TODO(lucacasonato): remove sanitizeResources unitTest( - { perms: { read: true }, sanitizeResources: false }, + { perms: { read: true } }, async function webgpuComputePass() { const numbers = [1, 4, 3, 295]; - // TODO(lucacasonato): remove when navigator is added to deno-lint - // deno-lint-ignore no-undef - const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index a55d6d89eb0414..b80f145ae9a47d 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -97,56 +97,57 @@ pub async fn op_webgpu_buffer_get_map_async( let (sender, receiver) = oneshot::channel::>(); - let state_ = state.borrow(); - let buffer_resource = state_ - .resource_table - .get::(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - let device_resource = state_ - .resource_table - .get::(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - let instance_resource = state_ - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let device; + { + let state_ = state.borrow(); + let buffer_resource = state_ + .resource_table + .get::(args.buffer_rid) + .ok_or_else(bad_resource_id)?; + let buffer = buffer_resource.0; + let device_resource = state_ + .resource_table + .get::(args.device_rid) + .ok_or_else(bad_resource_id)?; + device = device_resource.0; + let instance_resource = state_ + .resource_table + .get::(args.instance_rid) + .ok_or_else(bad_resource_id)?; + let instance = &instance_resource.0; + + let boxed_sender = Box::new(sender); + let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; + + extern "C" fn buffer_map_future_wrapper( + status: wgpu_core::resource::BufferMapAsyncStatus, + user_data: *mut u8, + ) { + let sender_ptr = user_data as *mut oneshot::Sender>; + let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; + boxed_sender + .send(match status { + wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()), + _ => unreachable!(), // TODO + }) + .unwrap(); + } - let boxed_sender = Box::new(sender); - let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; - - extern "C" fn buffer_map_future_wrapper( - status: wgpu_core::resource::BufferMapAsyncStatus, - user_data: *mut u8, - ) { - let sender_ptr = user_data as *mut oneshot::Sender>; - let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; - boxed_sender - .send(match status { - wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()), - _ => unreachable!(), // TODO - }) - .unwrap(); + gfx_select!(buffer => instance.buffer_map_async( + buffer, + args.offset..(args.offset + args.size), + wgpu_core::resource::BufferMapOperation { + host: match args.mode { + 1 => wgpu_core::device::HostMap::Read, + 2 => wgpu_core::device::HostMap::Write, + _ => unreachable!(), + }, + callback: buffer_map_future_wrapper, + user_data: sender_ptr, + } + ))?; } - gfx_select!(buffer => instance.buffer_map_async( - buffer, - args.offset..(args.offset + args.size), - wgpu_core::resource::BufferMapOperation { - host: match args.mode { - 1 => wgpu_core::device::HostMap::Read, - 2 => wgpu_core::device::HostMap::Write, - _ => unreachable!(), - }, - callback: buffer_map_future_wrapper, - user_data: sender_ptr, - } - ))?; - drop(instance); - drop(state_); - let done = Rc::new(RefCell::new(false)); let done_ = done.clone(); let instance_rid = args.instance_rid; From 675db5a584937725a2992793c3be7a6c384e9754 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 14:05:31 +0100 Subject: [PATCH 067/144] add typings --- cli/build.rs | 5 + cli/dts/lib.deno.window.d.ts | 6 + cli/dts/lib.deno.worker.d.ts | 6 + cli/main.rs | 3 +- cli/tsc.rs | 1 + op_crates/webgpu/lib.deno_webgpu.d.ts | 965 ++++++++++++++++++++++++++ op_crates/webgpu/lib.rs | 6 + 7 files changed, 991 insertions(+), 1 deletion(-) create mode 100644 op_crates/webgpu/lib.deno_webgpu.d.ts diff --git a/cli/build.rs b/cli/build.rs index b2303571715210..6b153f0b47e64c 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -57,6 +57,7 @@ fn create_compiler_snapshot( let mut op_crate_libs = HashMap::new(); op_crate_libs.insert("deno.web", deno_web::get_declaration()); op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration()); + op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration()); op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration()); // ensure we invalidate the build properly. @@ -254,6 +255,10 @@ fn main() { "cargo:rustc-env=DENO_FETCH_LIB_PATH={}", deno_fetch::get_declaration().display() ); + println!( + "cargo:rustc-env=DENO_WEBGPU_LIB_PATH={}", + deno_webgpu::get_declaration().display() + ); println!( "cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}", deno_websocket::get_declaration().display() diff --git a/cli/dts/lib.deno.window.d.ts b/cli/dts/lib.deno.window.d.ts index 721c89af229e30..b2dab70b1636a0 100644 --- a/cli/dts/lib.deno.window.d.ts +++ b/cli/dts/lib.deno.window.d.ts @@ -3,6 +3,7 @@ /// /// /// +/// /// declare class Window extends EventTarget { @@ -17,6 +18,7 @@ declare class Window extends EventTarget { confirm: (message?: string) => boolean; prompt: (message?: string, defaultValue?: string) => string | null; Deno: typeof Deno; + navigator: Navigator; } declare var window: Window & typeof globalThis; @@ -24,6 +26,10 @@ declare var self: Window & typeof globalThis; declare var onload: ((this: Window, ev: Event) => any) | null; declare var onunload: ((this: Window, ev: Event) => any) | null; +declare interface Navigator { + readonly gpu: GPU; +} + /** * Shows the given message and waits for the enter key pressed. * If the stdin is not interactive, it does nothing. diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index a8f42f3362e9bb..4a9c3c29bfc9b8 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -3,6 +3,7 @@ /// /// /// +/// /// declare class WorkerGlobalScope { @@ -29,6 +30,11 @@ declare class WorkerGlobalScope { close: () => void; postMessage: (message: any) => void; Deno: typeof Deno; + navigator: WorkerNavigator; +} + +declare interface WorkerNavigator { + readonly gpu: GPU; } declare class DedicatedWorkerGlobalScope extends WorkerGlobalScope { diff --git a/cli/main.rs b/cli/main.rs index 20e1ca8316771c..8743125d9b8c7c 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -278,10 +278,11 @@ fn print_cache_info( fn get_types(unstable: bool) -> String { let mut types = format!( - "{}\n{}\n{}\n{}\n{}\n{}", + "{}\n{}\n{}\n{}\n{}\n{}\n{}", crate::tsc::DENO_NS_LIB, crate::tsc::DENO_WEB_LIB, crate::tsc::DENO_FETCH_LIB, + crate::tsc::DENO_WEBGPU_LIB, crate::tsc::DENO_WEBSOCKET_LIB, crate::tsc::SHARED_GLOBALS_LIB, crate::tsc::WINDOW_LIB, diff --git a/cli/tsc.rs b/cli/tsc.rs index 9e32c19083d856..8ae81902515912 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -30,6 +30,7 @@ use std::sync::Mutex; pub static DENO_NS_LIB: &str = include_str!("dts/lib.deno.ns.d.ts"); pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH")); pub static DENO_FETCH_LIB: &str = include_str!(env!("DENO_FETCH_LIB_PATH")); +pub static DENO_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH")); pub static DENO_WEBSOCKET_LIB: &str = include_str!(env!("DENO_WEBSOCKET_LIB_PATH")); pub static SHARED_GLOBALS_LIB: &str = diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts new file mode 100644 index 00000000000000..eeecf9fa0649fa --- /dev/null +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -0,0 +1,965 @@ +declare interface GPUObjectBase { + label: string | null; +} + +declare interface GPUObjectDescriptorBase { + label?: string; +} + +declare interface GPUAdapterLimits { + maxTextureDimension1D?: number; + maxTextureDimension2D?: number; + maxTextureDimension3D?: number; + maxTextureArrayLayers?: number; + maxBindGroups?: number; + maxDynamicUniformBuffersPerPipelineLayout?: number; + maxDynamicStorageBuffersPerPipelineLayout?: number; + maxSampledTexturesPerShaderStage?: number; + maxSamplersPerShaderStage?: number; + maxStorageBuffersPerShaderStage?: number; + maxStorageTexturesPerShaderStage?: number; + maxUniformBuffersPerShaderStage?: number; + maxUniformBufferBindingSize?: number; + maxStorageBufferBindingSize?: number; + maxVertexBuffers?: number; + maxVertexAttributes?: number; + maxVertexBufferArrayStride?: number; +} + +declare type GPUAdapterFeatures = GPUFeatureName[]; + +declare interface GPU { + requestAdapter( + options?: GPURequestAdapterOptions, + ): Promise; +} + +declare interface GPURequestAdapterOptions { + powerPreference?: GPUPowerPreference; +} + +declare type GPUPowerPreference = "low-power" | "high-performance"; + +declare interface GPUAdapter { + readonly name: string; + readonly features: GPUAdapterFeatures; + readonly limits: GPUAdapterLimits; + + requestDevice(descriptor?: GPUDeviceDescriptor): Promise; +} + +declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase { + nonGuaranteedFeatures?: GPUFeatureName[]; + nonGuaranteedLimits?: Record; +} + +declare type GPUFeatureName = + | "depth-clamping" + | "depth24unorm-stencil8" + | "depth32float-stencil8" + | "pipeline-statistics-query" + | "texture-compression-bc" + | "timestamp-query"; + +declare interface GPUDevice extends EventTarget, GPUObjectBase { + readonly lost: Promise; + pushErrorScope(filter: GPUErrorFilter): undefined; + popErrorScope(): Promise; + onuncapturederror: ((this: GPUDevice, ev: Event) => any) | null; + + readonly adapter: GPUAdapter; + readonly features: ReadonlyArray; + readonly limits: Record; + readonly queue: GPUQueue; + + destroy(): undefined; + + createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer; + createTexture(descriptor: GPUTextureDescriptor): GPUTexture; + createSampler(descriptor?: GPUSamplerDescriptor): GPUSampler; + + createBindGroupLayout( + descriptor: GPUBindGroupLayoutDescriptor, + ): GPUBindGroupLayout; + createPipelineLayout( + descriptor: GPUPipelineLayoutDescriptor, + ): GPUPipelineLayout; + createBindGroup(descriptor: GPUBindGroupDescriptor): GPUBindGroup; + + createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule; + createComputePipeline( + descriptor: GPUComputePipelineDescriptor, + ): GPUComputePipeline; + createRenderPipeline( + descriptor: GPURenderPipelineDescriptor, + ): GPURenderPipeline; + createComputePipelineAsync( + descriptor: GPUComputePipelineDescriptor, + ): Promise; + createRenderPipelineAsync( + descriptor: GPURenderPipelineDescriptor, + ): Promise; + + createCommandEncoder( + descriptor?: GPUCommandEncoderDescriptor, + ): GPUCommandEncoder; + createRenderBundleEncoder( + descriptor: GPURenderBundleEncoderDescriptor, + ): GPURenderBundleEncoder; + + createQuerySet(descriptor: GPUQuerySetDescriptor): GPUQuerySet; +} + +declare interface GPUBuffer extends GPUObjectBase { + mapAsync( + mode: GPUMapModeFlags, + offset?: number, + size?: number, + ): Promise; + getMappedRange(offset?: number, size?: number): ArrayBuffer; + unmap(): undefined; + + destroy(): undefined; +} + +declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase { + size: number; + usage: GPUBufferUsageFlags; + mappedAtCreation?: boolean; +} + +declare type GPUBufferUsageFlags = number; +/* +declare interface GPUBufferUsage { + const GPUFlagsConstant MAP_READ = 0x0001; + const GPUFlagsConstant MAP_WRITE = 0x0002; + const GPUFlagsConstant COPY_SRC = 0x0004; + const GPUFlagsConstant COPY_DST = 0x0008; + const GPUFlagsConstant INDEX = 0x0010; + const GPUFlagsConstant VERTEX = 0x0020; + const GPUFlagsConstant UNIFORM = 0x0040; + const GPUFlagsConstant STORAGE = 0x0080; + const GPUFlagsConstant INDIRECT = 0x0100; + const GPUFlagsConstant QUERY_RESOLVE = 0x0200; +}; +*/ + +declare type GPUMapModeFlags = number; +/* +declare interface GPUMapMode { + const GPUFlagsConstant READ = 0x0001; + const GPUFlagsConstant WRITE = 0x0002; +}; +*/ + +declare interface GPUTexture extends GPUObjectBase { + createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView; + destroy(): undefined; +} + +declare interface GPUTextureDescriptor extends GPUObjectDescriptorBase { + size: GPUExtent3D; + mipLevelCount?: number; + sampleCount?: number; + dimension?: GPUTextureDimension; + format: GPUTextureFormat; + usage: GPUTextureUsageFlags; +} + +declare type GPUTextureDimension = "1d" | "2d" | "3d"; + +declare type GPUTextureUsageFlags = number; +/* +declare interface GPUTextureUsage { + const GPUFlagsConstant COPY_SRC = 0x01; + const GPUFlagsConstant COPY_DST = 0x02; + const GPUFlagsConstant SAMPLED = 0x04; + const GPUFlagsConstant STORAGE = 0x08; + const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; +}; +*/ + +declare interface GPUTextureView extends GPUObjectBase {} + +declare interface GPUTextureViewDescriptor extends GPUObjectDescriptorBase { + format?: GPUTextureFormat; + dimension?: GPUTextureViewDimension; + aspect?: GPUTextureAspect; + baseMipLevel?: number; + mipLevelCount?: number; + baseArrayLayer?: number; + arrayLayerCount?: number; +} + +declare type GPUTextureViewDimension = + | "1d" + | "2d" + | "2d-array" + | "cube" + | "cube-array" + | "3d"; + +declare type GPUTextureAspect = "all" | "stencil-only" | "depth-only"; + +declare type GPUTextureFormat = + | "r8unorm" + | "r8snorm" + | "r8uint" + | "r8sint" + | "r16uint" + | "r16sint" + | "r16float" + | "rg8unorm" + | "rg8snorm" + | "rg8uint" + | "rg8sint" + | "r32uint" + | "r32sint" + | "r32float" + | "rg16uint" + | "rg16sint" + | "rg16float" + | "rgba8unorm" + | "rgba8unorm-srgb" + | "rgba8snorm" + | "rgba8uint" + | "rgba8sint" + | "bgra8unorm" + | "bgra8unorm-srgb" + | "rgb9e5ufloat" + | "rgb10a2unorm" + | "rg11b10ufloat" + | "rg32uint" + | "rg32sint" + | "rg32float" + | "rgba16uint" + | "rgba16sint" + | "rgba16float" + | "rgba32uint" + | "rgba32sint" + | "rgba32float" + | "stencil8" + | "depth16unorm" + | "depth24plus" + | "depth24plus-stencil8" + | "depth32float" + | "bc1-rgba-unorm" + | "bc1-rgba-unorm-srgb" + | "bc2-rgba-unorm" + | "bc2-rgba-unorm-srgb" + | "bc3-rgba-unorm" + | "bc3-rgba-unorm-srgb" + | "bc4-r-unorm" + | "bc4-r-snorm" + | "bc5-rg-unorm" + | "bc5-rg-snorm" + | "bc6h-rgb-ufloat" + | "bc6h-rgb-float" + | "bc7-rgba-unorm" + | "bc7-rgba-unorm-srgb" + | "depth24unorm-stencil8" + | "depth32float-stencil8"; + +declare interface GPUSampler extends GPUObjectBase {} + +declare interface GPUSamplerDescriptor extends GPUObjectDescriptorBase { + addressModeU?: GPUAddressMode; + addressModeV?: GPUAddressMode; + addressModeW?: GPUAddressMode; + magFilter?: GPUFilterMode; + minFilter?: GPUFilterMode; + mipmapFilter?: GPUFilterMode; + lodMinClamp?: number; + lodMaxClamp?: number; + compare?: GPUCompareFunction; + maxAnisotropy?: number; +} + +declare type GPUAddressMode = "clamp-to-edge" | "repeat" | "mirror-repeat"; + +declare type GPUFilterMode = "nearest" | "linear"; + +declare type GPUCompareFunction = + | "never" + | "less" + | "equal" + | "less-equal" + | "greater" + | "not-equal" + | "greater-equal" + | "always"; + +declare interface GPUBindGroupLayout extends GPUObjectBase {} + +declare interface GPUBindGroupLayoutDescriptor extends GPUObjectDescriptorBase { + entries: GPUBindGroupLayoutEntry[]; +} + +declare interface GPUBindGroupLayoutEntry { + binding: number; + visibility: GPUShaderStageFlags; + + buffer?: GPUBufferBindingLayout; + sampler?: GPUSamplerBindingLayout; + texture?: GPUTextureBindingLayout; + storageTexture?: GPUStorageTextureBindingLayout; + +} + +declare type GPUShaderStageFlags = number; +/* +declare interface GPUShaderStage { + const GPUFlagsConstant VERTEX = 0x1; + const GPUFlagsConstant FRAGMENT = 0x2; + const GPUFlagsConstant COMPUTE = 0x4; +}; +*/ + +declare interface GPUBufferBindingLayout { + type?: GPUBufferBindingType; + hasDynamicOffset?: boolean; + minBindingSize?: number; +} + +declare type GPUBufferBindingType = "uniform" | "storage" | "read-only-storage"; + +declare interface GPUSamplerBindingLayout { + type?: GPUSamplerBindingType; +} + +declare type GPUSamplerBindingType = "filtering" | "non-filtering" | "comparison"; + +declare interface GPUTextureBindingLayout { + sampleType?: GPUTextureSampleType; + viewDimension?: GPUTextureViewDimension; + multisampled?: boolean; +} + +declare type GPUTextureSampleType = "float" | "unfilterable-float" | "depth" | "sint" | "uint"; + +declare interface GPUTextureBindingLayout { + sampleType?: GPUTextureSampleType; + viewDimension?: GPUTextureViewDimension; + multisampled?: boolean; +} + +declare type GPUStorageTextureAccess = "read-only" | "write-only"; + +declare interface GPUStorageTextureBindingLayout { + access: GPUStorageTextureAccess; + format: GPUTextureFormat; + viewDimension?: GPUTextureViewDimension; +} + +declare interface GPUBindGroup extends GPUObjectBase {} + +declare interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase { + layout: GPUBindGroupLayout; + entries: GPUBindGroupEntry[]; +} + +declare type GPUBindingResource = GPUSampler | GPUTextureView | GPUBufferBinding; + +declare interface GPUBindGroupEntry { + binding: number; + resource: GPUBindingResource; +} + +declare interface GPUBufferBinding { + buffer: GPUBuffer; + offset?: number; + size?: number; +} + +declare interface GPUPipelineLayout extends GPUObjectBase {} + +declare interface GPUPipelineLayoutDescriptor extends GPUObjectDescriptorBase { + bindGroupLayouts: GPUBindGroupLayout[]; +} + +declare type GPUCompilationMessageType = "error" | "warning" | "info"; + +declare interface GPUCompilationMessage { + readonly message: string; + readonly type: GPUCompilationMessageType; + readonly lineNum: number; + readonly linePos: number; +} + +declare interface GPUCompilationInfo { + readonly messages: ReadonlyArray; +} + +declare interface GPUShaderModule extends GPUObjectBase { + compilationInfo(): Promise; +} + +declare interface GPUShaderModuleDescriptor extends GPUObjectDescriptorBase { + code: string; + sourceMap?: any; +} + +declare interface GPUPipelineDescriptorBase extends GPUObjectDescriptorBase { + layout?: GPUPipelineLayout; +} + +declare interface GPUPipelineBase { + getBindGroupLayout(index: number): GPUBindGroupLayout; +} + +declare interface GPUProgrammableStage { + module: GPUShaderModule; + entryPoint: string; +} + +declare interface GPUComputePipeline extends GPUObjectBase, GPUPipelineBase {} + +declare interface GPUComputePipelineDescriptor extends GPUPipelineDescriptorBase { + compute: GPUProgrammableStage; +} + +declare interface GPURenderPipeline extends GPUObjectBase, GPUPipelineBase {} + +declare interface GPURenderPipelineDescriptor extends GPUPipelineDescriptorBase { + vertex: GPUVertexState; + primitive?: GPUPrimitiveState; + depthStencil?: GPUDepthStencilState; + multisample?: GPUMultisampleState; + fragment?: GPUFragmentState; +} + +declare type GPUPrimitiveTopology = + | "point-list" + | "line-list" + | "line-strip" + | "triangle-list" + | "triangle-strip"; + +declare interface GPUPrimitiveState { + topology?: GPUPrimitiveTopology; + stripIndexFormat?: GPUIndexFormat; + frontFace?: GPUFrontFace; + cullMode?: GPUCullMode; +} + +declare type GPUFrontFace = "ccw" | "cw"; + +declare type GPUCullMode = "none" | "front" | "back"; + +declare interface GPUMultisampleState { + count?: number; + mask?: number; + alphaToCoverageEnabled?: boolean; +} + +declare interface GPUFragmentState extends GPUProgrammableStage { + targets: GPUColorTargetState[]; +} + +declare interface GPUColorTargetState { + format: GPUTextureFormat; + + blend?: GPUBlendState; + writeMask?: GPUColorWriteFlags; +} + +declare interface GPUBlendState { + color: GPUBlendComponent; + alpha: GPUBlendComponent; +} + + +declare type GPUColorWriteFlags = number; +/* +declare interface GPUColorWrite { + const GPUFlagsConstant RED = 0x1; + const GPUFlagsConstant GREEN = 0x2; + const GPUFlagsConstant BLUE = 0x4; + const GPUFlagsConstant ALPHA = 0x8; + const GPUFlagsConstant ALL = 0xF; +}; +*/ + +declare interface GPUBlendComponent { + srcFactor: GPUBlendFactor; + dstFactor: GPUBlendFactor; + operation: GPUBlendOperation; +} + +declare type GPUBlendFactor = + | "zero" + | "one" + | "src-color" + | "one-minus-src-color" + | "src-alpha" + | "one-minus-src-alpha" + | "dst-color" + | "one-minus-dst-color" + | "dst-alpha" + | "one-minus-dst-alpha" + | "src-alpha-saturated" + | "blend-color" + | "one-minus-blend-color"; + +declare type GPUBlendOperation = + | "add" + | "subtract" + | "reverse-subtract" + | "min" + | "max"; + +declare interface GPUDepthStencilState { + format: GPUTextureFormat; + + depthWriteEnabled?: boolean; + depthCompare?: GPUCompareFunction; + + stencilFront?: GPUStencilFaceState; + stencilBack?: GPUStencilFaceState; + + stencilReadMask?: number; + stencilWriteMask?: number; + + depthBias?: number; + depthBiasSlopeScale?: number; + depthBiasClamp?: number; + + clampDepth?: boolean; +} + +declare interface GPUStencilFaceState { + compare?: GPUCompareFunction; + failOp?: GPUStencilOperation; + depthFailOp?: GPUStencilOperation; + passOp?: GPUStencilOperation; +} + +declare type GPUStencilOperation = + | "keep" + | "zero" + | "replace" + | "invert" + | "increment-clamp" + | "decrement-clamp" + | "increment-wrap" + | "decrement-wrap"; + +declare type GPUIndexFormat = "uint16" | "uint32"; + +declare type GPUVertexFormat = + | "uchar2" + | "uchar4" + | "char2" + | "char4" + | "uchar2norm" + | "uchar4norm" + | "char2norm" + | "char4norm" + | "ushort2" + | "ushort4" + | "short2" + | "short4" + | "ushort2norm" + | "ushort4norm" + | "short2norm" + | "short4norm" + | "half2" + | "half4" + | "float" + | "float2" + | "float3" + | "float4" + | "uint" + | "uint2" + | "uint3" + | "uint4" + | "int" + | "int2" + | "int3" + | "int4"; + +declare type GPUInputStepMode = "vertex" | "instance"; + +declare interface GPUVertexState extends GPUProgrammableStage { + buffer?: (GPUVertexBufferLayout | null)[]; +} + +declare interface GPUVertexBufferLayout { + arrayStride: number; + stepMode?: GPUInputStepMode; + attributes: GPUVertexAttribute[]; +} + +declare interface GPUVertexAttribute { + format: GPUVertexFormat; + offset: number; + + shaderLocation: number; +} + +declare interface GPUCommandBuffer extends GPUObjectBase { + readonly executionTime: Promise; +} + +declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {} + +declare interface GPUCommandEncoder extends GPUObjectBase { + beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder; + beginComputePass( + descriptor?: GPUComputePassDescriptor, + ): GPUComputePassEncoder; + + copyBufferToBuffer( + source: GPUBuffer, + sourceOffset: number, + destination: GPUBuffer, + destinationOffset: number, + size: number, + ): undefined; + + copyBufferToTexture( + source: GPUImageCopyBuffer, + destination: GPUImageCopyTexture, + copySize: GPUExtent3D, + ): undefined; + + copyTextureToBuffer( + source: GPUImageCopyTexture, + destination: GPUImageCopyBuffer, + copySize: GPUExtent3D, + ): undefined; + + copyTextureToTexture( + source: GPUImageCopyTexture, + destination: GPUImageCopyTexture, + copySize: GPUExtent3D, + ): undefined; + + pushDebugGroup(groupLabel: string): undefined; + popDebugGroup(): undefined; + insertDebugMarker(markerLabel: string): undefined; + + writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; + + resolveQuerySet( + querySet: GPUQuerySet, + firstQuery: number, + queryCount: number, + destination: GPUBuffer, + destinationOffset: number, + ): undefined; + + finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer; +} + +declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase { + measureExecutionTime?: boolean; +} + +declare interface GPUImageDataLayout { + offset?: number; + bytesPerRow?: number; + rowsPerImage?: number; +} + +declare interface GPUImageCopyBuffer extends GPUImageDataLayout { + buffer: GPUBuffer; +} + +declare interface GPUImageCopyTexture { + texture: GPUTexture; + mipLevel?: number; + origin?: GPUOrigin3D; + aspect?: GPUTextureAspect; +} + +declare interface GPUImageCopyImageBitmap { + imageBitmap: ImageBitmap; // TODO + origin?: GPUOrigin2D; +} + +declare interface GPUProgrammablePassEncoder { + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsets?: number[], + ): undefined; + + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsetsData: Uint32Array, + dynamicOffsetsDataStart: number, + dynamicOffsetsDataLength: number, + ): undefined; + + pushDebugGroup(groupLabel: string): undefined; + popDebugGroup(): undefined; + insertDebugMarker(markerLabel: string): undefined; +} + +declare interface GPUComputePassEncoder + extends GPUObjectBase, GPUProgrammablePassEncoder { + setPipeline(pipeline: GPUComputePipeline): undefined; + dispatch(x: number, y?: number, z?: number): undefined; + dispatchIndirect( + indirectBuffer: GPUBuffer, + indirectOffset: number, + ): undefined; + + beginPipelineStatisticsQuery( + querySet: GPUQuerySet, + queryIndex: number, + ): undefined; + endPipelineStatisticsQuery(): undefined; + + writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; + + endPass(): undefined; +} + +declare interface GPUComputePassDescriptor extends GPUObjectDescriptorBase {} + +declare interface GPURenderEncoderBase { + setPipeline(pipeline: GPURenderPipeline): undefined; + + setIndexBuffer( + buffer: GPUBuffer, + indexFormat: GPUIndexFormat, + offset?: number, + size?: number, + ): undefined; + setVertexBuffer( + slot: number, + buffer: GPUBuffer, + offset?: number, + size?: number, + ): undefined; + + draw( + vertexCount: number, + instanceCount?: number, + firstVertex?: number, + firstInstance?: number, + ): undefined; + drawIndexed( + indexCount: number, + instanceCount?: number, + firstIndex?: number, + baseVertex?: number, + firstInstance?: number, + ): undefined; + + drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; + drawIndexedIndirect( + indirectBuffer: GPUBuffer, + indirectOffset: number, + ): undefined; +} + +declare interface GPURenderPassEncoder + extends GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { + setViewport( + x: number, + y: number, + width: number, + height: number, + minDepth: number, + maxDepth: number, + ): undefined; + + setScissorRect( + x: number, + y: number, + width: number, + height: number, + ): undefined; + + setBlendColor(color: GPUColor): undefined; + setStencilReference(reference: number): undefined; + + beginOcclusionQuery(queryIndex: number): undefined; + endOcclusionQuery(): undefined; + + beginPipelineStatisticsQuery( + querySet: GPUQuerySet, + queryIndex: number, + ): undefined; + endPipelineStatisticsQuery(): undefined; + + writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; + + executeBundles(bundles: GPURenderBundle[]): undefined; + endPass(): undefined; +} + +declare interface GPURenderPassDescriptor extends GPUObjectDescriptorBase { + colorAttachments: GPURenderPassColorAttachment[]; + depthStencilAttachment?: GPURenderPassDepthStencilAttachment; + occlusionQuerySet?: GPUQuerySet; +} + +declare interface GPURenderPassColorAttachment { + view: GPUTextureView; + resolveTarget?: GPUTextureView; + + loadValue: GPULoadOp | GPUColor; + storeOp?: GPUStoreOp; +} + +declare interface GPURenderPassDepthStencilAttachment { + view: GPUTextureView; + + depthLoadValue: GPULoadOp | number; + depthStoreOp: GPUStoreOp; + depthReadOnly?: boolean; + + stencilLoadValue: GPULoadOp | number; + stencilStoreOp: GPUStoreOp; + stencilReadOnly?: boolean; +} + +declare type GPULoadOp = "load"; + +declare type GPUStoreOp = "store" | "clear"; + +declare interface GPURenderBundle extends GPUObjectBase {} + +declare interface GPURenderBundleDescriptor extends GPUObjectDescriptorBase {} + +declare interface GPURenderBundleEncoder + extends GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { + finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle; +} + +declare interface GPURenderBundleEncoderDescriptor extends GPUObjectDescriptorBase { + colorFormats: GPUTextureFormat[]; + depthStencilFormat?: GPUTextureFormat; + sampleCount?: number; +} + +declare interface GPUQueue extends GPUObjectBase { + submit(commandBuffers: GPUCommandBuffer[]): undefined; + + onSubmittedWorkDone(): Promise; + + writeBuffer( + buffer: GPUBuffer, + bufferOffset: number, + data: BufferSource, + dataOffset?: number, + size?: number, + ): undefined; + + writeTexture( + destination: GPUImageCopyTexture, + data: BufferSource, + dataLayout: GPUImageDataLayout, + size: GPUExtent3D, + ): undefined; + + copyImageBitmapToTexture( + source: GPUImageCopyImageBitmap, + destination: GPUImageCopyTexture, + copySize: GPUExtent3D, + ): undefined; +} + +declare interface GPUQuerySet extends GPUObjectBase { + destroy(): undefined; +} + +declare interface GPUQuerySetDescriptor extends GPUObjectDescriptorBase { + type: GPUQueryType; + count: number; + pipelineStatistics?: GPUPipelineStatisticName[]; +} + +declare type GPUQueryType = "occlusion" | "pipeline-statistics" | "timestamp"; + +declare type GPUPipelineStatisticName = + | "vertex-shader-invocations" + | "clipper-invocations" + | "clipper-primitives-out" + | "fragment-shader-invocations" + | "compute-shader-invocations"; + +declare interface GPUCanvasContext { + configureSwapChain(descriptor: GPUSwapChainDescriptor): GPUSwapChain; + + getSwapChainPreferredFormat(adapter: GPUAdapter): GPUTextureFormat; +} + +declare interface GPUSwapChainDescriptor extends GPUObjectDescriptorBase { + device: GPUDevice; + format: GPUTextureFormat; + usage?: GPUTextureUsageFlags; +} + +declare interface GPUSwapChain extends GPUObjectBase { + getCurrentTexture(): GPUTexture; +} + +declare type GPUDeviceLostReason = "destroyed"; + +declare interface GPUDeviceLostInfo { + readonly reason: GPUDeviceLostReason | undefined; + readonly message: string; +} + +declare type GPUErrorFilter = "out-of-memory" | "validation"; + +declare interface GPUOutOfMemoryError { + constructor(): this; +} + +declare interface GPUValidationError { + constructor(message: string): this; + readonly message: string; +} + +declare type GPUError = GPUOutOfMemoryError | GPUValidationError; + +declare interface GPUUncapturedErrorEvent extends Event { + constructor( + type: string, + gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit, + ): this; + readonly error: GPUError; +} + +declare interface GPUUncapturedErrorEventInit extends EventInit { + error?: GPUError; +} + +declare interface GPUColorDict { + r: number; + g: number; + b: number; + a: number; +} + +declare type GPUColor = number[] | GPUColorDict; + +declare interface GPUOrigin2DDict { + x?: number; + y?: number; +} + +declare type GPUOrigin2D = number[] | GPUOrigin2DDict; + +declare interface GPUOrigin3DDict { + x?: number; + y?: number; + z?: number; +} + +declare type GPUOrigin3D = number[] | GPUOrigin3DDict; + +declare interface GPUExtent3DDict { + width?: number; + height?: number; + depth?: number; +} + +declare type GPUExtent3D = number[] | GPUExtent3DDict; diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index d1aa2b40caabf0..4d4ada857dfac9 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -13,6 +13,7 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +use std::path::PathBuf; #[macro_use] mod macros { @@ -101,6 +102,11 @@ pub fn init(isolate: &mut deno_core::JsRuntime) { } } +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webgpu.d.ts") +} + + fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { let mut return_features: Vec<&str> = vec![]; From 8b4b882c9c98e1f74b0524916f37318e36ba7bcf Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 14:55:58 +0100 Subject: [PATCH 068/144] fix typings --- op_crates/webgpu/lib.deno_webgpu.d.ts | 51 +++++++++++++++++++-------- op_crates/webgpu/lib.rs | 3 +- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index eeecf9fa0649fa..6b8017a203da5e 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -1,3 +1,12 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// deno-lint-ignore-file no-explicit-any no-empty-interface + +/// +/// + +// 8cc98b6f10b7f354473a08c3773bb1de839845b9 + declare interface GPUObjectBase { label: string | null; } @@ -303,7 +312,6 @@ declare interface GPUBindGroupLayoutEntry { sampler?: GPUSamplerBindingLayout; texture?: GPUTextureBindingLayout; storageTexture?: GPUStorageTextureBindingLayout; - } declare type GPUShaderStageFlags = number; @@ -327,7 +335,10 @@ declare interface GPUSamplerBindingLayout { type?: GPUSamplerBindingType; } -declare type GPUSamplerBindingType = "filtering" | "non-filtering" | "comparison"; +declare type GPUSamplerBindingType = + | "filtering" + | "non-filtering" + | "comparison"; declare interface GPUTextureBindingLayout { sampleType?: GPUTextureSampleType; @@ -335,7 +346,12 @@ declare interface GPUTextureBindingLayout { multisampled?: boolean; } -declare type GPUTextureSampleType = "float" | "unfilterable-float" | "depth" | "sint" | "uint"; +declare type GPUTextureSampleType = + | "float" + | "unfilterable-float" + | "depth" + | "sint" + | "uint"; declare interface GPUTextureBindingLayout { sampleType?: GPUTextureSampleType; @@ -358,7 +374,10 @@ declare interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase { entries: GPUBindGroupEntry[]; } -declare type GPUBindingResource = GPUSampler | GPUTextureView | GPUBufferBinding; +declare type GPUBindingResource = + | GPUSampler + | GPUTextureView + | GPUBufferBinding; declare interface GPUBindGroupEntry { binding: number; @@ -414,13 +433,15 @@ declare interface GPUProgrammableStage { declare interface GPUComputePipeline extends GPUObjectBase, GPUPipelineBase {} -declare interface GPUComputePipelineDescriptor extends GPUPipelineDescriptorBase { +declare interface GPUComputePipelineDescriptor + extends GPUPipelineDescriptorBase { compute: GPUProgrammableStage; } declare interface GPURenderPipeline extends GPUObjectBase, GPUPipelineBase {} -declare interface GPURenderPipelineDescriptor extends GPUPipelineDescriptorBase { +declare interface GPURenderPipelineDescriptor + extends GPUPipelineDescriptorBase { vertex: GPUVertexState; primitive?: GPUPrimitiveState; depthStencil?: GPUDepthStencilState; @@ -468,7 +489,6 @@ declare interface GPUBlendState { alpha: GPUBlendComponent; } - declare type GPUColorWriteFlags = number; /* declare interface GPUColorWrite { @@ -674,7 +694,7 @@ declare interface GPUImageCopyTexture { } declare interface GPUImageCopyImageBitmap { - imageBitmap: ImageBitmap; // TODO + imageBitmap: ImageBitmap; // TODO(@crowlKats) origin?: GPUOrigin2D; } @@ -832,7 +852,8 @@ declare interface GPURenderBundleEncoder finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle; } -declare interface GPURenderBundleEncoderDescriptor extends GPUObjectDescriptorBase { +declare interface GPURenderBundleEncoderDescriptor + extends GPUObjectDescriptorBase { colorFormats: GPUTextureFormat[]; depthStencilFormat?: GPUTextureFormat; sampleCount?: number; @@ -909,22 +930,22 @@ declare interface GPUDeviceLostInfo { declare type GPUErrorFilter = "out-of-memory" | "validation"; -declare interface GPUOutOfMemoryError { - constructor(): this; +declare class GPUOutOfMemoryError { + constructor(); } -declare interface GPUValidationError { - constructor(message: string): this; +declare class GPUValidationError { + constructor(message: string); readonly message: string; } declare type GPUError = GPUOutOfMemoryError | GPUValidationError; -declare interface GPUUncapturedErrorEvent extends Event { +declare class GPUUncapturedErrorEvent extends Event { constructor( type: string, gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit, - ): this; + ); readonly error: GPUError; } diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 4d4ada857dfac9..098cb8e676a204 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -12,8 +12,8 @@ use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; -use std::rc::Rc; use std::path::PathBuf; +use std::rc::Rc; #[macro_use] mod macros { @@ -106,7 +106,6 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webgpu.d.ts") } - fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { let mut return_features: Vec<&str> = vec![]; From 61d214b2942dd3f8ed2d23c4a6303bc74f4ad231 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 15:12:29 +0100 Subject: [PATCH 069/144] Install mesa-vulkan --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe41c81632e0bd..c215fe94a4aac4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,12 @@ jobs: Select-Object -Skip 1 | ForEach-Object { Move-Item "$_" "$_.disabled" } + - name: Install mesa-vulkan (linux) + if: startsWith(matrix.os, 'ubuntu') + run: | + sudo apt-get update -y -qq + sudo apt-get install -y -qq mesa-vulkan-drivers + - name: Setup gcloud (unix) if: | runner.os != 'Windows' && From b3138d1a9548f9f763f1f8415b850f61b88ba3ad Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 15:19:50 +0100 Subject: [PATCH 070/144] delete unused structs --- op_crates/webgpu/lib.deno_webgpu.d.ts | 38 +++------------------------ 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index 6b8017a203da5e..ba67761eefaf8e 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -74,7 +74,9 @@ declare interface GPUDevice extends EventTarget, GPUObjectBase { readonly lost: Promise; pushErrorScope(filter: GPUErrorFilter): undefined; popErrorScope(): Promise; - onuncapturederror: ((this: GPUDevice, ev: Event) => any) | null; + onuncapturederror: + | ((this: GPUDevice, ev: GPUUncapturedErrorEvent) => any) + | null; readonly adapter: GPUAdapter; readonly features: ReadonlyArray; @@ -693,11 +695,6 @@ declare interface GPUImageCopyTexture { aspect?: GPUTextureAspect; } -declare interface GPUImageCopyImageBitmap { - imageBitmap: ImageBitmap; // TODO(@crowlKats) - origin?: GPUOrigin2D; -} - declare interface GPUProgrammablePassEncoder { setBindGroup( index: number, @@ -878,12 +875,6 @@ declare interface GPUQueue extends GPUObjectBase { dataLayout: GPUImageDataLayout, size: GPUExtent3D, ): undefined; - - copyImageBitmapToTexture( - source: GPUImageCopyImageBitmap, - destination: GPUImageCopyTexture, - copySize: GPUExtent3D, - ): undefined; } declare interface GPUQuerySet extends GPUObjectBase { @@ -905,22 +896,6 @@ declare type GPUPipelineStatisticName = | "fragment-shader-invocations" | "compute-shader-invocations"; -declare interface GPUCanvasContext { - configureSwapChain(descriptor: GPUSwapChainDescriptor): GPUSwapChain; - - getSwapChainPreferredFormat(adapter: GPUAdapter): GPUTextureFormat; -} - -declare interface GPUSwapChainDescriptor extends GPUObjectDescriptorBase { - device: GPUDevice; - format: GPUTextureFormat; - usage?: GPUTextureUsageFlags; -} - -declare interface GPUSwapChain extends GPUObjectBase { - getCurrentTexture(): GPUTexture; -} - declare type GPUDeviceLostReason = "destroyed"; declare interface GPUDeviceLostInfo { @@ -962,13 +937,6 @@ declare interface GPUColorDict { declare type GPUColor = number[] | GPUColorDict; -declare interface GPUOrigin2DDict { - x?: number; - y?: number; -} - -declare type GPUOrigin2D = number[] | GPUOrigin2DDict; - declare interface GPUOrigin3DDict { x?: number; y?: number; From 65510119e3d471c1bf68128f21b5ec8b1aa0a873 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 15:20:54 +0100 Subject: [PATCH 071/144] change dts --- cli/dts/lib.deno.window.d.ts | 1 + cli/dts/lib.deno.worker.d.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cli/dts/lib.deno.window.d.ts b/cli/dts/lib.deno.window.d.ts index b2dab70b1636a0..2d46e5fe05ed5f 100644 --- a/cli/dts/lib.deno.window.d.ts +++ b/cli/dts/lib.deno.window.d.ts @@ -25,6 +25,7 @@ declare var window: Window & typeof globalThis; declare var self: Window & typeof globalThis; declare var onload: ((this: Window, ev: Event) => any) | null; declare var onunload: ((this: Window, ev: Event) => any) | null; +declare var navigator: Navigator; declare interface Navigator { readonly gpu: GPU; diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index 4a9c3c29bfc9b8..302e2211d8dc6c 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -33,6 +33,8 @@ declare class WorkerGlobalScope { navigator: WorkerNavigator; } +declare var navigator: Navigator; + declare interface WorkerNavigator { readonly gpu: GPU; } From 03c4faa1437f628cb5b12f80560144b02a30ae93 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 15:55:25 +0100 Subject: [PATCH 072/144] webgpu_test.ts --- cli/tests/unit/unit_tests.ts | 2 +- cli/tests/unit/webgpu_test.js | 102 ---------------------------------- cli/tests/unit/webgpu_test.ts | 99 +++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 103 deletions(-) delete mode 100644 cli/tests/unit/webgpu_test.js create mode 100644 cli/tests/unit/webgpu_test.ts diff --git a/cli/tests/unit/unit_tests.ts b/cli/tests/unit/unit_tests.ts index 416e5979160a5f..2664a9ab0e3d03 100644 --- a/cli/tests/unit/unit_tests.ts +++ b/cli/tests/unit/unit_tests.ts @@ -76,4 +76,4 @@ import "./write_text_file_test.ts"; import "./performance_test.ts"; import "./version_test.ts"; import "./websocket_test.ts"; -import "./webgpu_test.js"; +import "./webgpu_test.ts"; diff --git a/cli/tests/unit/webgpu_test.js b/cli/tests/unit/webgpu_test.js deleted file mode 100644 index 13a2734559af68..00000000000000 --- a/cli/tests/unit/webgpu_test.js +++ /dev/null @@ -1,102 +0,0 @@ -import { assertEquals, unitTest } from "./test_util.ts"; - -// TODO(lucacasonato): remove when navigator is added to deno-lint -// deno-lint-ignore no-undef -const adapter = await navigator.gpu.requestAdapter(); - -// TODO(lucacasonato): remove sanitizeResources -unitTest( - { perms: { read: true } }, - async function webgpuComputePass() { - const numbers = [1, 4, 3, 295]; - - const device = await adapter.requestDevice(); - - const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); - - const shaderModule = device.createShaderModule({ - code: shaderCode, - }); - - const size = new Uint32Array(numbers).byteLength; - - const stagingBuffer = device.createBuffer({ - size: size, - usage: 1 | 8, - }); - - const storageBuffer = device.createBuffer({ - label: "Storage Buffer", - size: size, - usage: 0x80 | 8 | 4, - mappedAtCreation: true, - }); - - const buf = new Uint32Array(storageBuffer.getMappedRange()); - - buf.set(numbers); - - storageBuffer.unmap(); - - const bindGroupLayout = device.createBindGroupLayout({ - entries: [ - { - binding: 0, - visibility: 4, - buffer: { - type: "storage", - minBindingSize: 4, - }, - }, - ], - }); - - const bindGroup = device.createBindGroup({ - layout: bindGroupLayout, - entries: [ - { - binding: 0, - resource: { - buffer: storageBuffer, - }, - }, - ], - }); - - const pipelineLayout = device.createPipelineLayout({ - bindGroupLayouts: [bindGroupLayout], - }); - - const computePipeline = device.createComputePipeline({ - layout: pipelineLayout, - compute: { - module: shaderModule, - entryPoint: "main", - }, - }); - - const encoder = device.createCommandEncoder(); - - const computePass = encoder.beginComputePass(); - computePass.setPipeline(computePipeline); - computePass.setBindGroup(0, bindGroup); - computePass.insertDebugMarker("compute collatz iterations"); - computePass.dispatch(numbers.length); - computePass.endPass(); - - encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); - - device.queue.submit([encoder.finish()]); - - await stagingBuffer.mapAsync(1); - - const data = stagingBuffer.getMappedRange(); - - assertEquals( - new Uint32Array(0, 2, 7, 55).entries(), - new Uint32Array(data).entries(), - ); - - stagingBuffer.unmap(); - }, -); diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts new file mode 100644 index 00000000000000..a4d0458c28f626 --- /dev/null +++ b/cli/tests/unit/webgpu_test.ts @@ -0,0 +1,99 @@ +import { assert, assertEquals, unitTest } from "./test_util.ts"; + +// TODO(lucacasonato): remove when navigator is added to deno-lint +// deno-lint-ignore no-undef +const adapter = await navigator.gpu.requestAdapter(); +assert(adapter); + +unitTest({ perms: { read: true } }, async function webgpuComputePass() { + const numbers = [1, 4, 3, 295]; + + const device = await adapter.requestDevice(); + assert(device); + + const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); + + const shaderModule = device.createShaderModule({ + code: shaderCode, + }); + + const size = new Uint32Array(numbers).byteLength; + + const stagingBuffer = device.createBuffer({ + size: size, + usage: 1 | 8, + }); + + const storageBuffer = device.createBuffer({ + label: "Storage Buffer", + size: size, + usage: 0x80 | 8 | 4, + mappedAtCreation: true, + }); + + const buf = new Uint32Array(storageBuffer.getMappedRange()); + + buf.set(numbers); + + storageBuffer.unmap(); + + const bindGroupLayout = device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: 4, + buffer: { + type: "storage", + minBindingSize: 4, + }, + }, + ], + }); + + const bindGroup = device.createBindGroup({ + layout: bindGroupLayout, + entries: [ + { + binding: 0, + resource: { + buffer: storageBuffer, + }, + }, + ], + }); + + const pipelineLayout = device.createPipelineLayout({ + bindGroupLayouts: [bindGroupLayout], + }); + + const computePipeline = device.createComputePipeline({ + layout: pipelineLayout, + compute: { + module: shaderModule, + entryPoint: "main", + }, + }); + + const encoder = device.createCommandEncoder(); + + const computePass = encoder.beginComputePass(); + computePass.setPipeline(computePipeline); + computePass.setBindGroup(0, bindGroup); + computePass.insertDebugMarker("compute collatz iterations"); + computePass.dispatch(numbers.length); + computePass.endPass(); + + encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); + + device.queue.submit([encoder.finish()]); + + await stagingBuffer.mapAsync(1); + + const data = stagingBuffer.getMappedRange(); + + assertEquals(new Uint32Array(data), new Uint32Array([0, 2, 7, 55])); + + stagingBuffer.unmap(); + + device.destroy(); +}); From 68f0f5848701ca39c8670c17a7344a0c6d97d3aa Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 15:57:31 +0100 Subject: [PATCH 073/144] fix workerNavigator dts --- cli/dts/lib.deno.worker.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index 302e2211d8dc6c..93549ecd5cd36f 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -33,7 +33,7 @@ declare class WorkerGlobalScope { navigator: WorkerNavigator; } -declare var navigator: Navigator; +declare var navigator: WorkerNavigator; declare interface WorkerNavigator { readonly gpu: GPU; From 927d5dbd4e1841b5ed0a08bb2744050bdeb0e8b4 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 16:27:11 +0100 Subject: [PATCH 074/144] only run on windows --- cli/tests/unit/webgpu_test.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index a4d0458c28f626..5289eb8334eede 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -1,11 +1,23 @@ import { assert, assertEquals, unitTest } from "./test_util.ts"; +let isCI: boolean; +try { + isCI = (Deno.env.get("CI")?.length ?? 0) > 0; +} catch { + isCI = true; +} + // TODO(lucacasonato): remove when navigator is added to deno-lint // deno-lint-ignore no-undef const adapter = await navigator.gpu.requestAdapter(); assert(adapter); -unitTest({ perms: { read: true } }, async function webgpuComputePass() { +// Skip this test on linux CI, because the vulkan emulator is not good enough +// yet, and skip on macOS because these do not have virtual GPUs. +unitTest({ + perms: { read: true, env: true }, + ignore: (Deno.build.os === "linux" || Deno.build.os === "darwin") && isCI, +}, async function webgpuComputePass() { const numbers = [1, 4, 3, 295]; const device = await adapter.requestDevice(); From 24daeb6ec12f7c9cc16cac6d796a000d38b0245c Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 16:28:04 +0100 Subject: [PATCH 075/144] don't install mesa-vulkan --- .github/workflows/ci.yml | 6 ------ std/wasi/testdata | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) create mode 160000 std/wasi/testdata diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c215fe94a4aac4..fe41c81632e0bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,12 +106,6 @@ jobs: Select-Object -Skip 1 | ForEach-Object { Move-Item "$_" "$_.disabled" } - - name: Install mesa-vulkan (linux) - if: startsWith(matrix.os, 'ubuntu') - run: | - sudo apt-get update -y -qq - sudo apt-get install -y -qq mesa-vulkan-drivers - - name: Setup gcloud (unix) if: | runner.os != 'Windows' && diff --git a/std/wasi/testdata b/std/wasi/testdata new file mode 160000 index 00000000000000..7f8aa6ba628a2b --- /dev/null +++ b/std/wasi/testdata @@ -0,0 +1 @@ +Subproject commit 7f8aa6ba628a2bea3612e50638b8c9c9c4bb71a8 From 6bab6b914cde26788534cb909d901c32fe0a2624 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 10 Feb 2021 16:29:38 +0100 Subject: [PATCH 076/144] whoops --- std/wasi/testdata | 1 - 1 file changed, 1 deletion(-) delete mode 160000 std/wasi/testdata diff --git a/std/wasi/testdata b/std/wasi/testdata deleted file mode 160000 index 7f8aa6ba628a2b..00000000000000 --- a/std/wasi/testdata +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7f8aa6ba628a2bea3612e50638b8c9c9c4bb71a8 From 6f69ae56eea18c606ba8f3f3aa19dda475db432e Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 16:31:06 +0100 Subject: [PATCH 077/144] return null on no adapter --- op_crates/webgpu/14_webgpu.js | 13 +++++++++---- op_crates/webgpu/lib.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index a01931ae04723b..124eb7bbb5db1b 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -54,14 +54,19 @@ const gpu = { async requestAdapter(options = {}) { - const { rid, ...data } = await core.jsonOpAsync( + const { error, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", { instanceRid: getInstanceRid(), ...options, }, ); - return new GPUAdapter(rid, data); + + if (error) { + return null; + } else { + return new GPUAdapter(data); + } }, }; @@ -80,8 +85,8 @@ return this.#limits; } - constructor(rid, data) { - this.#rid = rid; + constructor(data) { + this.#rid = data.rid; this.#name = data.name; this.#features = Object.freeze(data.features); this.#limits = Object.freeze(data.limits); diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 098cb8e676a204..4b1420f8a4ed4d 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -181,8 +181,15 @@ pub async fn op_webgpu_request_adapter( wgpu_types::BackendBit::PRIMARY, |_| std::marker::PhantomData, ), - )?; + ); + + if adapter.is_err() { + return Ok(json!({ + "error": true + })); + } + let adapter = adapter.unwrap(); let name = gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; let adapter_features = gfx_select!(adapter => instance.adapter_features(adapter))?; From 52df4bb65ce3d2174b141c3b0979fa8ad3099068 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 17:37:23 +0100 Subject: [PATCH 078/144] move instance to OpState --- op_crates/webgpu/14_webgpu.js | 45 ----------------- op_crates/webgpu/binding.rs | 23 ++------- op_crates/webgpu/buffer.rs | 35 ++----------- op_crates/webgpu/bundle.rs | 7 +-- op_crates/webgpu/command_encoder.rs | 77 +++++------------------------ op_crates/webgpu/compute_pass.rs | 7 +-- op_crates/webgpu/lib.rs | 50 +++---------------- op_crates/webgpu/pipeline.rs | 28 ++--------- op_crates/webgpu/queue.rs | 21 ++------ op_crates/webgpu/render_pass.rs | 8 +-- op_crates/webgpu/sampler.rs | 7 +-- op_crates/webgpu/shader.rs | 7 +-- op_crates/webgpu/texture.rs | 14 +----- runtime/ops/webgpu.rs | 11 +++-- 14 files changed, 46 insertions(+), 294 deletions(-) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/14_webgpu.js index 124eb7bbb5db1b..b71f5f4dcae115 100644 --- a/op_crates/webgpu/14_webgpu.js +++ b/op_crates/webgpu/14_webgpu.js @@ -42,22 +42,11 @@ } } - let instanceRid; - - function getInstanceRid() { - if (!instanceRid) { - const { rid } = core.jsonOpSync("op_webgpu_create_instance"); - instanceRid = rid; - } - return instanceRid; - } - const gpu = { async requestAdapter(options = {}) { const { error, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", { - instanceRid: getInstanceRid(), ...options, }, ); @@ -96,7 +85,6 @@ const { rid, ...data } = await core.jsonOpAsync( "op_webgpu_request_device", { - instanceRid, adapterRid: this.#rid, ...descriptor, }, @@ -146,7 +134,6 @@ createBuffer(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -162,7 +149,6 @@ createTexture(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_texture", { - instanceRid, deviceRid: this.#rid, ...descriptor, size: normalizeGPUExtent3D(descriptor.size), @@ -173,7 +159,6 @@ createSampler(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -195,7 +180,6 @@ } const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -205,7 +189,6 @@ createPipelineLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { - instanceRid, deviceRid: this.#rid, label: descriptor.label, bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => @@ -218,7 +201,6 @@ createBindGroup(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { - instanceRid, deviceRid: this.#rid, label: descriptor.label, layout: descriptor.layout[ridSymbol], @@ -254,7 +236,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_create_shader_module", { - instanceRid, deviceRid: this.#rid, label: descriptor.label, code: (typeof descriptor.code === "string") @@ -270,7 +251,6 @@ createComputePipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { - instanceRid, deviceRid: this.#rid, label: descriptor.label, layout: descriptor.layout ? descriptor.layout[ridSymbol] : undefined, @@ -285,7 +265,6 @@ createRenderPipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -303,7 +282,6 @@ createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -325,7 +303,6 @@ createQuerySet(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { - instanceRid, deviceRid: this.#rid, ...descriptor, }); @@ -343,7 +320,6 @@ submit(commandBuffers) { core.jsonOpSync("op_webgpu_queue_submit", { - instanceRid, queueRid: this.#rid, commandBuffers: commandBuffers.map((buffer) => buffer[ridSymbol]), }); @@ -356,7 +332,6 @@ core.jsonOpSync( "op_webgpu_write_texture", { - instanceRid, queueRid: this.#rid, buffer: buffer[ridSymbol], bufferOffset, @@ -371,7 +346,6 @@ core.jsonOpSync( "op_webgpu_write_texture", { - instanceRid, queueRid: this.#rid, destination: { texture: destination.texture[ridSymbol], @@ -415,7 +389,6 @@ this.#mappedOffset = offset; this.#mappedSize = size ?? (this.#size - offset); await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { - instanceRid, bufferRid: this[ridSymbol], deviceRid: this.#deviceRid, mode, @@ -429,7 +402,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { - instanceRid, bufferRid: this[ridSymbol], offset, size: size ?? this.#mappedSize, @@ -444,7 +416,6 @@ unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { - instanceRid, bufferRid: this[ridSymbol], mappedRid: this.#mappedRid, }, this.#mappedBuffer); @@ -463,7 +434,6 @@ createView(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { - instanceRid, textureRid: this[ridSymbol], ...descriptor, }); @@ -532,7 +502,6 @@ const { rid, label } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", { - instanceRid, computePipelineRid: this[ridSymbol], index, }, @@ -552,7 +521,6 @@ const { rid, label } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", { - instanceRid, renderPipelineRid: this[ridSymbol], index, }, @@ -657,7 +625,6 @@ core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_buffer", { - instanceRid, commandEncoderRid: this.#rid, source: source[ridSymbol], sourceOffset, @@ -672,7 +639,6 @@ core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_texture", { - instanceRid, commandEncoderRid: this.#rid, source: { ...source, @@ -693,7 +659,6 @@ core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { - instanceRid, commandEncoderRid: this.#rid, source: { texture: source.texture[ridSymbol], @@ -713,7 +678,6 @@ core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { - instanceRid, commandEncoderRid: this.#rid, source: { texture: source.texture[ridSymbol], @@ -733,20 +697,17 @@ pushDebugGroup(groupLabel) { core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { - instanceRid, commandEncoderRid: this.#rid, groupLabel, }); } popDebugGroup() { core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { - instanceRid, commandEncoderRid: this.#rid, }); } insertDebugMarker(markerLabel) { core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { - instanceRid, commandEncoderRid: this.#rid, markerLabel, }); @@ -754,7 +715,6 @@ writeTimestamp(querySet, queryIndex) { core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { - instanceRid, commandEncoderRid: this.#rid, querySet: querySet[ridSymbol], queryIndex, @@ -769,7 +729,6 @@ destinationOffset, ) { core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { - instanceRid, commandEncoderRid: this.#rid, querySet: querySet[ridSymbol], firstQuery, @@ -781,7 +740,6 @@ finish(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { - instanceRid, commandEncoderRid: this.#rid, ...descriptor, }); @@ -871,7 +829,6 @@ } endPass() { core.jsonOpSync("op_webgpu_render_pass_end_pass", { - instanceRid, commandEncoderRid: this.#commandEncoderRid, renderPassRid: this.#rid, }); @@ -1054,7 +1011,6 @@ endPass() { core.jsonOpSync("op_webgpu_compute_pass_end_pass", { - instanceRid, commandEncoderRid: this.#commandEncoderRid, computePassRid: this.#rid, }); @@ -1134,7 +1090,6 @@ const { rid } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { - instanceRid, renderBundleEncoderRid: this.#rid, ...descriptor, }, diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index d372d0493e8783..994f193e7f3850 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -71,7 +71,6 @@ struct GPUBindGroupLayoutEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBindGroupLayoutArgs { - instance_rid: u32, device_rid: u32, label: Option, entries: Vec, @@ -84,16 +83,12 @@ pub fn op_webgpu_create_bind_group_layout( ) -> Result { let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let mut entries = vec![]; @@ -219,7 +214,6 @@ pub fn op_webgpu_create_bind_group_layout( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreatePipelineLayoutArgs { - instance_rid: u32, device_rid: u32, label: Option, bind_group_layouts: Vec, @@ -232,6 +226,7 @@ pub fn op_webgpu_create_pipeline_layout( ) -> Result { let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) @@ -248,12 +243,6 @@ pub fn op_webgpu_create_pipeline_layout( bind_group_layouts.push(bind_group_layout.0); } - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; - let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { label: args.label.map(Cow::from), bind_group_layouts: Cow::from(bind_group_layouts), @@ -288,7 +277,6 @@ struct GPUBindGroupEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBindGroupArgs { - instance_rid: u32, device_rid: u32, label: Option, layout: u32, @@ -302,6 +290,7 @@ pub fn op_webgpu_create_bind_group( ) -> Result { let args: CreateBindGroupArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) @@ -360,12 +349,6 @@ pub fn op_webgpu_create_bind_group( entries: Cow::from(entries), }; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; - let bind_group = gfx_select_err!(device => instance.device_create_bind_group( device, &descriptor, diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index b80f145ae9a47d..751b0fa823437a 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -31,7 +31,6 @@ impl Resource for WebGPUBufferMapped { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateBufferArgs { - instance_rid: u32, device_rid: u32, label: Option, size: u64, @@ -46,16 +45,12 @@ pub fn op_webgpu_create_buffer( ) -> Result { let args: CreateBufferArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_core::resource::BufferDescriptor { label: args.label.map(Cow::from), @@ -80,7 +75,6 @@ pub fn op_webgpu_create_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferGetMapAsyncArgs { - instance_rid: u32, buffer_rid: u32, device_rid: u32, mode: u32, @@ -100,6 +94,7 @@ pub async fn op_webgpu_buffer_get_map_async( let device; { let state_ = state.borrow(); + let instance = state_.borrow::(); let buffer_resource = state_ .resource_table .get::(args.buffer_rid) @@ -110,11 +105,6 @@ pub async fn op_webgpu_buffer_get_map_async( .get::(args.device_rid) .ok_or_else(bad_resource_id)?; device = device_resource.0; - let instance_resource = state_ - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let boxed_sender = Box::new(sender); let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; @@ -150,16 +140,11 @@ pub async fn op_webgpu_buffer_get_map_async( let done = Rc::new(RefCell::new(false)); let done_ = done.clone(); - let instance_rid = args.instance_rid; let device_poll_fut = async move { while !*done.borrow() { { let state = state.borrow(); - let instance_resource = state - .resource_table - .get::(instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = state.borrow::(); gfx_select!(device => instance.device_poll(device, false)).unwrap() } tokio::time::sleep(Duration::from_millis(10)).await; @@ -182,7 +167,6 @@ pub async fn op_webgpu_buffer_get_map_async( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferGetMappedRangeArgs { - instance_rid: u32, buffer_rid: u32, offset: u64, size: u64, @@ -195,16 +179,12 @@ pub fn op_webgpu_buffer_get_mapped_range( ) -> Result { let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let buffer_resource = state .resource_table .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; let buffer = buffer_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let slice_pointer = gfx_select!(buffer => instance.buffer_get_mapped_range( buffer, @@ -229,7 +209,6 @@ pub fn op_webgpu_buffer_get_mapped_range( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct BufferUnmapArgs { - instance_rid: u32, buffer_rid: u32, mapped_rid: u32, } @@ -241,6 +220,7 @@ pub fn op_webgpu_buffer_unmap( ) -> Result { let args: BufferUnmapArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let buffer_resource = state .resource_table .get::(args.buffer_rid) @@ -250,11 +230,6 @@ pub fn op_webgpu_buffer_unmap( .resource_table .get::(args.mapped_rid) .ok_or_else(bad_resource_id)?; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let slice_pointer = mapped_resource.0; let size = mapped_resource.1; diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 24b2eeec46e4fc..c974aa880810f4 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -84,7 +84,6 @@ pub fn op_webgpu_create_render_bundle_encoder( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderBundleEncoderFinishArgs { - instance_rid: u32, render_bundle_encoder_rid: u32, label: Option, } @@ -105,11 +104,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( .expect("unwrapping render_bundle_encoder_resource should succeed") .0 .into_inner(); - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = state.borrow::(); let render_bundle = gfx_select_err!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index b43bfccba1fa56..b3ab891ee15fa3 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -39,7 +39,6 @@ fn serialize_store_op(store_op: String) -> wgpu_core::command::StoreOp { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateCommandEncoderArgs { - instance_rid: u32, device_rid: u32, label: Option, _measure_execution_time: Option, // not yet implemented @@ -52,16 +51,12 @@ pub fn op_webgpu_create_command_encoder( ) -> Result { let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_types::CommandEncoderDescriptor { label: args.label.map(Cow::from), @@ -288,7 +283,6 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyBufferToBufferArgs { - instance_rid: u32, command_encoder_rid: u32, source: u32, source_offset: u64, @@ -305,6 +299,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( let args: CommandEncoderCopyBufferToBufferArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -320,11 +315,6 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .get::(args.destination) .ok_or_else(bad_resource_id)?; let destination_buffer = destination_buffer_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, @@ -367,7 +357,6 @@ pub struct GPUImageCopyTexture { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyBufferToTextureArgs { - instance_rid: u32, command_encoder_rid: u32, source: GPUImageCopyBuffer, destination: GPUImageCopyTexture, @@ -382,6 +371,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( let args: CommandEncoderCopyBufferToTextureArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -395,11 +385,6 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( .resource_table .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let source = wgpu_core::command::BufferCopyView { buffer: source_buffer_resource.0, @@ -438,7 +423,6 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyTextureToBufferArgs { - instance_rid: u32, command_encoder_rid: u32, source: GPUImageCopyTexture, destination: GPUImageCopyBuffer, @@ -453,6 +437,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( let args: CommandEncoderCopyTextureToBufferArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -466,11 +451,6 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( .resource_table .get::(args.destination.buffer) .ok_or_else(bad_resource_id)?; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let source = wgpu_core::command::TextureCopyView { texture: source_texture_resource.0, @@ -508,7 +488,6 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderCopyTextureToTextureArgs { - instance_rid: u32, command_encoder_rid: u32, source: GPUImageCopyTexture, destination: GPUImageCopyTexture, @@ -523,6 +502,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( let args: CommandEncoderCopyTextureToTextureArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -536,11 +516,6 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( .resource_table .get::(args.destination.texture) .ok_or_else(bad_resource_id)?; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let source = wgpu_core::command::TextureCopyView { texture: source_texture_resource.0, @@ -582,7 +557,6 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderPushDebugGroupArgs { - instance_rid: u32, command_encoder_rid: u32, group_label: String, } @@ -594,16 +568,12 @@ pub fn op_webgpu_command_encoder_push_debug_group( ) -> Result { let args: CommandEncoderPushDebugGroupArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; gfx_select!(command_encoder => instance .command_encoder_push_debug_group(command_encoder, &args.group_label))?; @@ -614,7 +584,6 @@ pub fn op_webgpu_command_encoder_push_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderPopDebugGroupArgs { - instance_rid: u32, command_encoder_rid: u32, } @@ -625,16 +594,12 @@ pub fn op_webgpu_command_encoder_pop_debug_group( ) -> Result { let args: CommandEncoderPopDebugGroupArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; @@ -644,7 +609,6 @@ pub fn op_webgpu_command_encoder_pop_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderInsertDebugMarkerArgs { - instance_rid: u32, command_encoder_rid: u32, marker_label: String, } @@ -656,16 +620,12 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( ) -> Result { let args: CommandEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, @@ -678,7 +638,6 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderWriteTimestampArgs { - instance_rid: u32, command_encoder_rid: u32, query_set: u32, query_index: u32, @@ -691,16 +650,12 @@ pub fn op_webgpu_command_encoder_write_timestamp( ) -> Result { let args: CommandEncoderWriteTimestampArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let query_set_resource = state .resource_table .get::(args.query_set) @@ -718,7 +673,6 @@ pub fn op_webgpu_command_encoder_write_timestamp( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderResolveQuerySetArgs { - instance_rid: u32, command_encoder_rid: u32, query_set: u32, first_query: u32, @@ -734,16 +688,12 @@ pub fn op_webgpu_command_encoder_resolve_query_set( ) -> Result { let args: CommandEncoderResolveQuerySetArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let query_set_resource = state .resource_table .get::(args.query_set) @@ -768,7 +718,6 @@ pub fn op_webgpu_command_encoder_resolve_query_set( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CommandEncoderFinishArgs { - instance_rid: u32, command_encoder_rid: u32, label: Option, } @@ -780,16 +729,12 @@ pub fn op_webgpu_command_encoder_finish( ) -> Result { let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_types::CommandBufferDescriptor { label: args.label.map(Cow::from), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 516a8de7c763e7..6c9235abd69e49 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -216,7 +216,6 @@ pub fn op_webgpu_compute_pass_write_timestamp( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePassEndPassArgs { - instance_rid: u32, command_encoder_rid: u32, compute_pass_rid: u32, } @@ -228,11 +227,7 @@ pub fn op_webgpu_compute_pass_end_pass( ) -> Result { let args: ComputePassEndPassArgs = serde_json::from_value(args)?; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::( diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 4b1420f8a4ed4d..ade092e3297c1c 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -14,6 +14,8 @@ use std::borrow::Cow; use std::cell::RefCell; use std::path::PathBuf; use std::rc::Rc; +pub use wgpu_core; +pub use wgpu_types; #[macro_use] mod macros { @@ -61,14 +63,7 @@ pub mod sampler; pub mod shader; pub mod texture; -struct WebGPUInstance( - wgpu_core::hub::Global, -); -impl Resource for WebGPUInstance { - fn name(&self) -> Cow { - "webGPUInstance".into() - } -} +type Instance = wgpu_core::hub::Global; struct WebGPUAdapter(wgpu_core::id::AdapterId); impl Resource for WebGPUAdapter { @@ -125,28 +120,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { return_features } -pub fn op_webgpu_create_instance( - state: &mut OpState, - _args: Value, - _zero_copy: &mut [ZeroCopyBuf], -) -> Result { - let instance = wgpu_core::hub::Global::new( - "webgpu", - wgpu_core::hub::IdentityManagerFactory, - wgpu_types::BackendBit::PRIMARY, - ); - - let rid = state.resource_table.add(WebGPUInstance(instance)); - - Ok(json!({ - "rid": rid, - })) -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestAdapterArgs { - instance_rid: u32, power_preference: Option, } @@ -158,11 +134,7 @@ pub async fn op_webgpu_request_adapter( let args: RequestAdapterArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = state.borrow::(); let descriptor = wgpu_core::instance::RequestAdapterOptions { power_preference: match args.power_preference { @@ -244,7 +216,6 @@ struct GPULimits { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RequestDeviceArgs { - instance_rid: u32, adapter_rid: u32, label: Option, non_guaranteed_features: Option>, @@ -264,11 +235,7 @@ pub async fn op_webgpu_request_device( .get::(args.adapter_rid) .ok_or_else(bad_resource_id)?; let adapter = adapter_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = state.borrow::(); let mut features: wgpu_types::Features = wgpu_types::Features::empty(); @@ -357,7 +324,6 @@ pub async fn op_webgpu_request_device( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateQuerySetArgs { - instance_rid: u32, device_rid: u32, _label: Option, // not yet implemented #[serde(rename = "type")] @@ -378,11 +344,7 @@ pub fn op_webgpu_create_query_set( .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; + let instance = &state.borrow::(); let descriptor = wgpu_types::QuerySetDescriptor { ty: match args.kind.as_str() { diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 0614060842584a..e0dc752babfef9 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -150,7 +150,6 @@ struct GPUProgrammableStage { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateComputePipelineArgs { - instance_rid: u32, device_rid: u32, label: Option, layout: Option, @@ -164,16 +163,12 @@ pub fn op_webgpu_create_compute_pipeline( ) -> Result { let args: CreateComputePipelineArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let pipeline_layout = if let Some(rid) = args.layout { let id = state @@ -229,7 +224,6 @@ pub fn op_webgpu_create_compute_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct ComputePipelineGetBindGroupLayoutArgs { - instance_rid: u32, compute_pipeline_rid: u32, index: u32, } @@ -242,16 +236,12 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( let args: ComputePipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let compute_pipeline_resource = state .resource_table .get::(args.compute_pipeline_rid) .ok_or_else(bad_resource_id)?; let compute_pipeline = compute_pipeline_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let bind_group_layout = gfx_select_err!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData))?; @@ -367,7 +357,6 @@ struct GPUFragmentState { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateRenderPipelineArgs { - instance_rid: u32, device_rid: u32, label: Option, layout: Option, @@ -385,16 +374,12 @@ pub fn op_webgpu_create_render_pipeline( ) -> Result { let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let layout = if let Some(rid) = args.layout { let pipeline_layout_resource = state @@ -636,7 +621,6 @@ pub fn op_webgpu_create_render_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPipelineGetBindGroupLayoutArgs { - instance_rid: u32, render_pipeline_rid: u32, index: u32, } @@ -649,16 +633,12 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( let args: RenderPipelineGetBindGroupLayoutArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let render_pipeline_resource = state .resource_table .get::(args.render_pipeline_rid) .ok_or_else(bad_resource_id)?; let render_pipeline = render_pipeline_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let bind_group_layout = gfx_select_err!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData))?; diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index 7446271577e841..e2509b1f4eaf31 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -13,7 +13,6 @@ type WebGPUQueue = super::WebGPUDevice; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueSubmitArgs { - instance_rid: u32, queue_rid: u32, command_buffers: Vec, } @@ -25,16 +24,12 @@ pub fn op_webgpu_queue_submit( ) -> Result { let args: QueueSubmitArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let queue_resource = state .resource_table .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; let queue = queue_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let mut ids = vec![]; @@ -62,7 +57,6 @@ struct GPUImageDataLayout { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueWriteBufferArgs { - instance_rid: u32, queue_rid: u32, buffer: u32, buffer_offset: u64, @@ -77,6 +71,7 @@ pub fn op_webgpu_write_buffer( ) -> Result { let args: QueueWriteBufferArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let buffer_resource = state .resource_table .get::(args.buffer) @@ -87,11 +82,6 @@ pub fn op_webgpu_write_buffer( .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; let queue = queue_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let data = match args.size { Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], @@ -110,7 +100,6 @@ pub fn op_webgpu_write_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct QueueWriteTextureArgs { - instance_rid: u32, queue_rid: u32, destination: super::command_encoder::GPUImageCopyTexture, data_layout: GPUImageDataLayout, @@ -124,6 +113,7 @@ pub fn op_webgpu_write_texture( ) -> Result { let args: QueueWriteTextureArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let texture_resource = state .resource_table .get::(args.destination.texture) @@ -133,11 +123,6 @@ pub fn op_webgpu_write_texture( .get::(args.queue_rid) .ok_or_else(bad_resource_id)?; let queue = queue_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let destination = wgpu_core::command::TextureCopyView { texture: texture_resource.0, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index d867185a7444db..67575cc65d96b1 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -299,7 +299,6 @@ pub fn op_webgpu_render_pass_execute_bundles( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct RenderPassEndPassArgs { - instance_rid: u32, command_encoder_rid: u32, render_pass_rid: u32, } @@ -311,6 +310,7 @@ pub fn op_webgpu_render_pass_end_pass( ) -> Result { let args: RenderPassEndPassArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::( @@ -318,16 +318,12 @@ pub fn op_webgpu_render_pass_end_pass( ) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let render_pass_resource = state .resource_table .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; let render_pass = &render_pass_resource.0.borrow(); + gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; Ok(json!({})) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 3f423b1abbe463..1400281eef265a 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -62,7 +62,6 @@ pub fn serialize_compare_function( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateSamplerArgs { - instance_rid: u32, device_rid: u32, label: Option, address_mode_u: Option, @@ -84,16 +83,12 @@ pub fn op_webgpu_create_sampler( ) -> Result { let args: CreateSamplerArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_core::resource::SamplerDescriptor { label: args.label.map(Cow::from), diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 86f745bfd9324e..36e99095c3e24d 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -19,7 +19,6 @@ impl Resource for WebGPUShaderModule { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateShaderModuleArgs { - instance_rid: u32, device_rid: u32, label: Option, code: Option, @@ -33,16 +32,12 @@ pub fn op_webgpu_create_shader_module( ) -> Result { let args: CreateShaderModuleArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let source = match args.code { Some(code) => { diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index 91082c21a4f18a..a8a1566fc93915 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -132,7 +132,6 @@ pub struct GPUExtent3D { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureArgs { - instance_rid: u32, device_rid: u32, label: Option, size: GPUExtent3D, @@ -150,16 +149,12 @@ pub fn op_webgpu_create_texture( ) -> Result { let args: CreateTextureArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let device_resource = state .resource_table .get::(args.device_rid) .ok_or_else(bad_resource_id)?; let device = device_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_core::resource::TextureDescriptor { label: args.label.map(Cow::from), @@ -199,7 +194,6 @@ pub fn op_webgpu_create_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct CreateTextureViewArgs { - instance_rid: u32, texture_rid: u32, label: Option, format: Option, @@ -218,16 +212,12 @@ pub fn op_webgpu_create_texture_view( ) -> Result { let args: CreateTextureViewArgs = serde_json::from_value(args)?; + let instance = state.borrow::(); let texture_resource = state .resource_table .get::(args.texture_rid) .ok_or_else(bad_resource_id)?; let texture = texture_resource.0; - let instance_resource = state - .resource_table - .get::(args.instance_rid) - .ok_or_else(bad_resource_id)?; - let instance = &instance_resource.0; let descriptor = wgpu_core::resource::TextureViewDescriptor { label: args.label.map(Cow::from), diff --git a/runtime/ops/webgpu.rs b/runtime/ops/webgpu.rs index aac77bee56a115..249532013e4cdb 100644 --- a/runtime/ops/webgpu.rs +++ b/runtime/ops/webgpu.rs @@ -1,11 +1,12 @@ use deno_webgpu::*; pub fn init(rt: &mut deno_core::JsRuntime) { - super::reg_json_sync( - rt, - "op_webgpu_create_instance", - op_webgpu_create_instance, - ); + rt.op_state().borrow_mut().put(wgpu_core::hub::Global::new( + "webgpu", + wgpu_core::hub::IdentityManagerFactory, + wgpu_types::BackendBit::PRIMARY, + )); + super::reg_json_async( rt, "op_webgpu_request_adapter", From 2d06ee676f7b1abc615c47c7c4633e556818c7c0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 10 Feb 2021 20:37:40 +0100 Subject: [PATCH 079/144] rename js file --- op_crates/webgpu/{14_webgpu.js => 01_webgpu.js} | 0 op_crates/webgpu/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename op_crates/webgpu/{14_webgpu.js => 01_webgpu.js} (100%) diff --git a/op_crates/webgpu/14_webgpu.js b/op_crates/webgpu/01_webgpu.js similarity index 100% rename from op_crates/webgpu/14_webgpu.js rename to op_crates/webgpu/01_webgpu.js diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index ade092e3297c1c..48f22ef013fe00 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -89,8 +89,8 @@ impl Resource for WebGPUQuerySet { /// Execute this crates' JS source files. pub fn init(isolate: &mut deno_core::JsRuntime) { let files = vec![( - "deno:op_crates/webgpu/14_webgpu.js", - include_str!("14_webgpu.js"), + "deno:op_crates/webgpu/01_webgpu.js", + include_str!("01_webgpu.js"), )]; for (url, source_code) in files { isolate.execute(url, source_code).unwrap(); From 8ba95490e8e88ff275c773ff27cf0d04e0944744 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 11 Feb 2021 00:30:10 +0100 Subject: [PATCH 080/144] add unstable check --- op_crates/webgpu/lib.rs | 15 +++++++++++++++ runtime/ops/webgpu.rs | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 48f22ef013fe00..65907954e39171 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -63,6 +63,20 @@ pub mod sampler; pub mod shader; pub mod texture; +pub struct Unstable(pub bool); + +fn check_unstable(state: &OpState, api_name: &str) { + let unstable = state.borrow::(); + + if !unstable.0 { + eprintln!( + "Unstable API '{}'. The --unstable flag must be provided.", + api_name + ); + std::process::exit(70); + } +} + type Instance = wgpu_core::hub::Global; struct WebGPUAdapter(wgpu_core::id::AdapterId); @@ -134,6 +148,7 @@ pub async fn op_webgpu_request_adapter( let args: RequestAdapterArgs = serde_json::from_value(args)?; let mut state = state.borrow_mut(); + check_unstable(&state, "navigator.gpu.requestAdapter"); let instance = state.borrow::(); let descriptor = wgpu_core::instance::RequestAdapterOptions { diff --git a/runtime/ops/webgpu.rs b/runtime/ops/webgpu.rs index 249532013e4cdb..d3b9cfa19c5800 100644 --- a/runtime/ops/webgpu.rs +++ b/runtime/ops/webgpu.rs @@ -1,11 +1,18 @@ use deno_webgpu::*; pub fn init(rt: &mut deno_core::JsRuntime) { - rt.op_state().borrow_mut().put(wgpu_core::hub::Global::new( - "webgpu", - wgpu_core::hub::IdentityManagerFactory, - wgpu_types::BackendBit::PRIMARY, - )); + { + let op_state = rt.op_state(); + let mut state = op_state.borrow_mut(); + state.put(wgpu_core::hub::Global::new( + "webgpu", + wgpu_core::hub::IdentityManagerFactory, + wgpu_types::BackendBit::PRIMARY, + )); + let unstable_checker = state.borrow::(); + let unstable = unstable_checker.unstable; + state.put(Unstable(unstable)); + } super::reg_json_async( rt, From e9236b9df9c5dbab313549cb49a3203ff39bec53 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 11 Feb 2021 13:14:43 +0100 Subject: [PATCH 081/144] fix stuff --- op_crates/webgpu/01_webgpu.js | 22 +++++++++++++++++++++- op_crates/webgpu/command_encoder.rs | 2 +- op_crates/webgpu/lib.deno_webgpu.d.ts | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index b71f5f4dcae115..94cec9c31d814f 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -264,9 +264,29 @@ } createRenderPipeline(descriptor) { + const d = { + label: descriptor.label, + layout: descriptor.layout?.[ridSymbol], + vertex: { + module: descriptor.vertex.module[ridSymbol], + entryPoint: descriptor.vertex.entryPoint, + buffers: descriptor.vertex.buffers, + }, + primitive: descriptor.primitive, + depthStencil: descriptor.depthStencil, + multisample: descriptor.multisample, + fragment: descriptor.fragment + ? { + module: descriptor.fragment.module[ridSymbol], + entryPoint: descriptor.fragment.entryPoint, + targets: descriptor.fragment.targets, + } + : undefined, + }; + const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { deviceRid: this.#rid, - ...descriptor, + ...d, }); return new GPURenderPipeline(rid, descriptor.label); diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index b3ab891ee15fa3..a23b44c4d8c107 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -108,7 +108,7 @@ struct CommandEncoderBeginRenderPassArgs { label: Option, color_attachments: Vec, depth_stencil_attachment: Option, - _occlusion_query_set: u32, // not yet implemented + _occlusion_query_set: Option, // not yet implemented } pub fn op_webgpu_command_encoder_begin_render_pass( diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index ba67761eefaf8e..5dd3204e14f6af 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -603,7 +603,7 @@ declare type GPUVertexFormat = declare type GPUInputStepMode = "vertex" | "instance"; declare interface GPUVertexState extends GPUProgrammableStage { - buffer?: (GPUVertexBufferLayout | null)[]; + buffers?: (GPUVertexBufferLayout | null)[]; } declare interface GPUVertexBufferLayout { From 7c5b8a0f7f60e2b22e03423743b63e238fd479d6 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 11 Feb 2021 22:51:35 +0100 Subject: [PATCH 082/144] fix stuff --- op_crates/webgpu/pipeline.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index e0dc752babfef9..811eb9097dc7b4 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -335,7 +335,7 @@ struct GPUVertexBufferLayout { struct GPUVertexState { module: u32, entry_point: String, - vertex_buffers: Option>>, + buffers: Option>>, } #[derive(Deserialize)] @@ -404,7 +404,7 @@ pub fn op_webgpu_create_render_pipeline( module: vertex_shader_module_resource.0, entry_point: Cow::from(args.vertex.entry_point), }, - buffers: Cow::from(if let Some(buffers) = args.vertex.vertex_buffers { + buffers: Cow::from(if let Some(buffers) = args.vertex.buffers { let mut return_buffers = vec![]; for buffer in buffers { if let Some(buffer) = buffer { From da2b53d80311fe47c58784752526b32b2876d0a0 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:03:10 +0100 Subject: [PATCH 083/144] expose classes and make constructors private --- op_crates/webgpu/01_webgpu.js | 160 +++++++++++++++++++++++++--------- runtime/js/99_main.js | 21 +++++ 2 files changed, 140 insertions(+), 41 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 94cec9c31d814f..8654bb9c917edb 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -5,6 +5,13 @@ const ridSymbol = Symbol("rid"); + const keySymbol = Symbol("key"); + function checkKey(key) { + if (key !== keySymbol) { + throw new TypeError("Illegal constructor"); + } + } + function normalizeGPUExtent3D(data) { if (Array.isArray(data)) { return { @@ -54,7 +61,7 @@ if (error) { return null; } else { - return new GPUAdapter(data); + return new GPUAdapter(keySymbol, data); } }, }; @@ -74,7 +81,9 @@ return this.#limits; } - constructor(data) { + constructor(key, data) { + checkKey(key); + this.#rid = data.rid; this.#name = data.name; this.#features = Object.freeze(data.features); @@ -90,7 +99,7 @@ }, ); - return new GPUDevice(this, rid, { + return new GPUDevice(keySymbol, this, rid, { label: descriptor.label, ...data, }); @@ -117,14 +126,16 @@ return this.#queue; } - constructor(adapter, rid, data) { + constructor(key, adapter, rid, data) { + checkKey(key); + super(); this.#adapter = adapter; this.#rid = rid; this.#features = Object.freeze(data.features); this.#limits = data.limits; - this.#queue = new GPUQueue(rid, data.label); + this.#queue = new GPUQueue(keySymbol, rid, data.label); this.label = data.label; } @@ -139,6 +150,7 @@ }); return new GPUBuffer( + keySymbol, rid, this.#rid, descriptor.label, @@ -154,7 +166,7 @@ size: normalizeGPUExtent3D(descriptor.size), }); - return new GPUTexture(rid, descriptor.label); + return new GPUTexture(keySymbol, rid, descriptor.label); } createSampler(descriptor = {}) { @@ -163,7 +175,7 @@ ...descriptor, }); - return new GPUSampler(rid, descriptor.label); + return new GPUSampler(keySymbol, rid, descriptor.label); } createBindGroupLayout(descriptor) { @@ -184,7 +196,7 @@ ...descriptor, }); - return new GPUBindGroupLayout(rid, descriptor.label); + return new GPUBindGroupLayout(keySymbol, rid, descriptor.label); } createPipelineLayout(descriptor) { @@ -196,7 +208,7 @@ ), }); - return new GPUPipelineLayout(rid, descriptor.label); + return new GPUPipelineLayout(keySymbol, rid, descriptor.label); } createBindGroup(descriptor) { @@ -229,7 +241,7 @@ }), }); - return new GPUBindGroup(rid, descriptor.label); + return new GPUBindGroup(keySymbol, rid, descriptor.label); } createShaderModule(descriptor) { @@ -246,7 +258,7 @@ ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []), ); - return new GPUShaderModule(rid, descriptor.label); + return new GPUShaderModule(keySymbol, rid, descriptor.label); } createComputePipeline(descriptor) { @@ -260,7 +272,7 @@ }, }); - return new GPUComputePipeline(rid, descriptor.label); + return new GPUComputePipeline(keySymbol, rid, descriptor.label); } createRenderPipeline(descriptor) { @@ -289,7 +301,7 @@ ...d, }); - return new GPURenderPipeline(rid, descriptor.label); + return new GPURenderPipeline(keySymbol, rid, descriptor.label); } createComputePipelineAsync(_descriptor) { @@ -306,7 +318,7 @@ ...descriptor, }); - return new GPUCommandEncoder(rid, descriptor.label); + return new GPUCommandEncoder(keySymbol, rid, descriptor.label); } createRenderBundleEncoder(descriptor) { @@ -318,7 +330,7 @@ }, ); - return new GPURenderBundleEncoder(rid, descriptor.label); + return new GPURenderBundleEncoder(keySymbol, rid, descriptor.label); } createQuerySet(descriptor) { @@ -327,13 +339,15 @@ ...descriptor, }); - return new GPUQuerySet(rid, descriptor.label); + return new GPUQuerySet(keySymbol, rid, descriptor.label); } } class GPUQueue { #rid; - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this.#rid = rid; this.label = label ?? null; } @@ -393,7 +407,9 @@ #mappedRid; #mappedBuffer; - constructor(rid, deviceRid, label, size, mappedAtCreation) { + constructor(key, rid, deviceRid, label, size, mappedAtCreation) { + checkKey(key); + this[ridSymbol] = rid; this.#deviceRid = deviceRid; this.label = label ?? null; @@ -447,7 +463,9 @@ } class GPUTexture { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -458,7 +476,7 @@ ...descriptor, }); - return new GPUTextureView(rid, descriptor.label); + return new GPUTextureView(keySymbol, rid, descriptor.label); } destroy() { @@ -467,42 +485,54 @@ } class GPUTextureView { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUSampler { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUBindGroupLayout { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUPipelineLayout { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUBindGroup { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUShaderModule { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -513,7 +543,9 @@ } class GPUComputePipeline { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -527,12 +559,14 @@ }, ); - return new GPUBindGroupLayout(rid, label); + return new GPUBindGroupLayout(keySymbol, rid, label); } } class GPURenderPipeline { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -546,14 +580,16 @@ }, ); - return new GPUBindGroupLayout(rid, label); + return new GPUBindGroupLayout(keySymbol, rid, label); } } class GPUCommandEncoder { #rid; - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this.#rid = rid; this.label = label ?? null; } @@ -620,7 +656,12 @@ }, ); - return new GPURenderPassEncoder(this.#rid, rid, descriptor.label); + return new GPURenderPassEncoder( + keySymbol, + this.#rid, + rid, + descriptor.label, + ); } beginComputePass(descriptor = {}) { @@ -632,7 +673,12 @@ }, ); - return new GPUComputePassEncoder(this.#rid, rid, descriptor.label); + return new GPUComputePassEncoder( + keySymbol, + this.#rid, + rid, + descriptor.label, + ); } copyBufferToBuffer( @@ -764,7 +810,7 @@ ...descriptor, }); - return new GPUCommandBuffer(rid, descriptor.label); + return new GPUCommandBuffer(keySymbol, rid, descriptor.label); } } @@ -772,7 +818,9 @@ #commandEncoderRid; #rid; - constructor(commandEncoderRid, rid, label) { + constructor(key, commandEncoderRid, rid, label) { + checkKey(key); + this.#commandEncoderRid = commandEncoderRid; this.#rid = rid; this.label = label ?? null; @@ -977,7 +1025,9 @@ #commandEncoderRid; #rid; - constructor(commandEncoderRid, rid, label) { + constructor(key, commandEncoderRid, rid, label) { + checkKey(key); + this.#commandEncoderRid = commandEncoderRid; this.#rid = rid; this.label = label ?? null; @@ -1089,7 +1139,9 @@ } class GPUCommandBuffer { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -1101,7 +1153,9 @@ class GPURenderBundleEncoder { #rid; - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this.#rid = rid; this.label = label ?? null; } @@ -1115,7 +1169,7 @@ }, ); - return new GPURenderBundle(rid, descriptor.label); + return new GPURenderBundle(keySymbol, rid, descriptor.label); } setBindGroup( @@ -1234,14 +1288,18 @@ } class GPURenderBundle { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } } class GPUQuerySet { - constructor(rid, label) { + constructor(key, rid, label) { + checkKey(key); + this[ridSymbol] = rid; this.label = label ?? null; } @@ -1253,5 +1311,25 @@ window.__bootstrap.webGPU = { gpu, + GPUAdapter, + GPUDevice, + GPUQueue, + GPUBuffer, + GPUTexture, + GPUTextureView, + GPUSampler, + GPUBindGroupLayout, + GPUPipelineLayout, + GPUBindGroup, + GPUShaderModule, + GPUComputePipeline, + GPURenderPipeline, + GPUCommandEncoder, + GPURenderPassEncoder, + GPUComputePassEncoder, + GPUCommandBuffer, + GPURenderBundleEncoder, + GPURenderBundle, + GPUQuerySet, }; })(this); diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 0601e8e27c2a09..707f783769510a 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -250,6 +250,27 @@ delete Object.prototype.__proto__; performance: util.writable(performance.performance), setInterval: util.writable(timers.setInterval), setTimeout: util.writable(timers.setTimeout), + + GPUAdapter: util.nonEnumerable(webGPU.GPUAdapter), + GPUDevice: util.nonEnumerable(webGPU.GPUDevice), + GPUQueue: util.nonEnumerable(webGPU.GPUQueue), + GPUBuffer: util.nonEnumerable(webGPU.GPUBuffer), + GPUTexture: util.nonEnumerable(webGPU.GPUTexture), + GPUTextureView: util.nonEnumerable(webGPU.GPUTextureView), + GPUSampler: util.nonEnumerable(webGPU.GPUSampler), + GPUBindGroupLayout: util.nonEnumerable(webGPU.GPUBindGroupLayout), + GPUPipelineLayout: util.nonEnumerable(webGPU.GPUPipelineLayout), + GPUBindGroup: util.nonEnumerable(webGPU.GPUBindGroup), + GPUShaderModule: util.nonEnumerable(webGPU.GPUShaderModule), + GPUComputePipeline: util.nonEnumerable(webGPU.GPUComputePipeline), + GPURenderPipeline: util.nonEnumerable(webGPU.GPURenderPipeline), + GPUCommandEncoder: util.nonEnumerable(webGPU.GPUCommandEncoder), + GPURenderPassEncoder: util.nonEnumerable(webGPU.GPURenderPassEncoder), + GPUComputePassEncoder: util.nonEnumerable(webGPU.GPUComputePassEncoder), + GPUCommandBuffer: util.nonEnumerable(webGPU.GPUCommandBuffer), + GPURenderBundleEncoder: util.nonEnumerable(webGPU.GPURenderBundleEncoder), + GPURenderBundle: util.nonEnumerable(webGPU.GPURenderBundle), + GPUQuerySet: util.nonEnumerable(webGPU.GPUQuerySet), }; // The console seems to be the only one that should be writable and non-enumerable From efb63bc690466d4671b8b6d46dfd586cdcb2d139 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sat, 13 Feb 2021 10:37:28 +0100 Subject: [PATCH 084/144] fix bindgroup entry --- op_crates/webgpu/01_webgpu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 8654bb9c917edb..7f6c3600c36137 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -217,13 +217,13 @@ label: descriptor.label, layout: descriptor.layout[ridSymbol], entries: descriptor.entries.map((entry) => { - if (entry instanceof GPUSampler) { + if (entry.resource instanceof GPUSampler) { return { binding: entry.binding, kind: "GPUSampler", resource: entry.resource[ridSymbol], }; - } else if (entry instanceof GPUTextureView) { + } else if (entry.resource instanceof GPUTextureView) { return { binding: entry.binding, kind: "GPUTextureView", From c7395290d59e59dac03878a014b462cd7bf2cf97 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:27:54 +0100 Subject: [PATCH 085/144] support more features --- op_crates/webgpu/lib.rs | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 65907954e39171..bc6596aee3acf7 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -131,6 +131,53 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { return_features.push("timestamp-query"); } + // extended from spec + if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { + return_features.push("mappable-primary-buffers"); + } + if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY) { + return_features.push("sampled-texture-binding-array"); + } + if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING) { + return_features.push("sampled-texture-array-dynamic-indexing"); + } + if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) { + return_features.push("sampled-texture-array-non-uniform-indexing"); + } + if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { + return_features.push("unsized-binding-array"); + } + if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT) { + return_features.push("multi-draw-indirect"); + } + if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT) { + return_features.push("multi-draw-indirect-count"); + } + if features.contains(wgpu_types::Features::PUSH_CONSTANTS) { + return_features.push("push-constants"); + } + if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { + return_features.push("address-mode-clamp-to-border"); + } + if features.contains(wgpu_types::Features::NON_FILL_POLYGON_MODE) { + return_features.push("non-fill-polygon-mode"); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { + return_features.push("texture-compression-etc2"); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { + return_features.push("texture-compression-astc-ldr"); + } + if features.contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) { + return_features.push("texture-adapter-specific-format-features"); + } + if features.contains(wgpu_types::Features::SHADER_FLOAT64) { + return_features.push("shader-float64"); + } + if features.contains(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT) { + return_features.push("vertex-attribute-64bit"); + } + return_features } @@ -267,6 +314,53 @@ pub async fn op_webgpu_request_device( if passed_features.contains(&"timestamp-query".to_string()) { features.set(wgpu_types::Features::TIMESTAMP_QUERY, true); } + + // extended from spec + if passed_features.contains(&"mappable-primary-buffers".to_string()) { + features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true); + } + if passed_features.contains(&"sampled-texture-binding-array".to_string()) { + features.set(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY, true); + } + if passed_features.contains(&"sampled-texture-array-dynamic-indexing".to_string()) { + features.set(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING, true); + } + if passed_features.contains(&"sampled-texture-array-non-uniform-indexing".to_string()) { + features.set(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, true); + } + if passed_features.contains(&"unsized-binding-array".to_string()) { + features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true); + } + if passed_features.contains(&"multi-draw-indirect".to_string()) { + features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, true); + } + if passed_features.contains(&"multi-draw-indirect-count".to_string()) { + features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, true); + } + if passed_features.contains(&"push-constants".to_string()) { + features.set(wgpu_types::Features::PUSH_CONSTANTS, true); + } + if passed_features.contains(&"address-mode-clamp-to-border".to_string()) { + features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); + } + if passed_features.contains(&"non-fill-polygon-mode".to_string()) { + features.set(wgpu_types::Features::NON_FILL_POLYGON_MODE, true); + } + if passed_features.contains(&"texture-compression-etc2".to_string()) { + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, true); + } + if passed_features.contains(&"texture-compression-astc-ldr".to_string()) { + features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true); + } + if passed_features.contains(&"texture-adapter-specific-format-features".to_string()) { + features.set(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, true); + } + if passed_features.contains(&"shader-float64".to_string()) { + features.set(wgpu_types::Features::SHADER_FLOAT64, true); + } + if passed_features.contains(&"vertex-attribute-64bit".to_string()) { + features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, true); + } } let descriptor = wgpu_types::DeviceDescriptor { From e6b7fac4d1a4f3808c0987407bf156c21572bb83 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:30:47 +0100 Subject: [PATCH 086/144] add setters --- op_crates/webgpu/01_webgpu.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7f6c3600c36137..625f44ba2ab42e 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -72,14 +72,17 @@ get name() { return this.#name; } + set name(_) {} #features; get features() { return this.#features; } + set features(_) {} #limits; get limits() { return this.#limits; } + set limits(_) {} constructor(key, data) { checkKey(key); @@ -113,18 +116,22 @@ get adapter() { return this.#adapter; } + set adapter(_) {} #features; get features() { return this.#features; } + set features(_) {} #limits; get limits() { return this.#limits; } + set limits(_) {} #queue; get queue() { return this.#queue; } + set queue(_) {} constructor(key, adapter, rid, data) { checkKey(key); @@ -1149,6 +1156,7 @@ get executionTime() { throw new Error("Not yet implemented"); } + set executionTime(_) {} } class GPURenderBundleEncoder { From 5fd635da35ec8a9bfe1a0d9dd492b6f433a1c0ee Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 15 Feb 2021 00:50:10 +0100 Subject: [PATCH 087/144] add typings for extended features --- op_crates/webgpu/lib.deno_webgpu.d.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index 5dd3204e14f6af..469849fce81246 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -68,7 +68,23 @@ declare type GPUFeatureName = | "depth32float-stencil8" | "pipeline-statistics-query" | "texture-compression-bc" - | "timestamp-query"; + | "timestamp-query" + // extended from spec + | "mappable-primary-buffers" + | "sampled-texture-binding-array" + | "sampled-texture-array-dynamic-indexing" + | "sampled-texture-array-non-uniform-indexing" + | "unsized-binding-array" + | "multi-draw-indirect" + | "multi-draw-indirect-count" + | "push-constants" + | "address-mode-clamp-to-border" + | "non-fill-polygon-mode" + | "texture-compression-etc2" + | "texture-compression-astc-ldr" + | "texture-adapter-specific-format-features" + | "shader-float64" + | "vertex-attribute-64bit"; declare interface GPUDevice extends EventTarget, GPUObjectBase { readonly lost: Promise; From 59d99d415f9a4409bcf1a4a13c0cd90c09e4b6e7 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 15 Feb 2021 05:17:36 +0100 Subject: [PATCH 088/144] Revert "add setters" This reverts commit e6b7fac4 --- op_crates/webgpu/01_webgpu.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 625f44ba2ab42e..7f6c3600c36137 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -72,17 +72,14 @@ get name() { return this.#name; } - set name(_) {} #features; get features() { return this.#features; } - set features(_) {} #limits; get limits() { return this.#limits; } - set limits(_) {} constructor(key, data) { checkKey(key); @@ -116,22 +113,18 @@ get adapter() { return this.#adapter; } - set adapter(_) {} #features; get features() { return this.#features; } - set features(_) {} #limits; get limits() { return this.#limits; } - set limits(_) {} #queue; get queue() { return this.#queue; } - set queue(_) {} constructor(key, adapter, rid, data) { checkKey(key); @@ -1156,7 +1149,6 @@ get executionTime() { throw new Error("Not yet implemented"); } - set executionTime(_) {} } class GPURenderBundleEncoder { From e5916a0d7bc57bf2356c0f73f346f8abb73443c1 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 15 Feb 2021 23:45:36 +0100 Subject: [PATCH 089/144] fix writeBuffer --- op_crates/webgpu/01_webgpu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7f6c3600c36137..7c02f0c59f08be 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -364,7 +364,7 @@ writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { core.jsonOpSync( - "op_webgpu_write_texture", + "op_webgpu_write_buffer", { queueRid: this.#rid, buffer: buffer[ridSymbol], From 401c7873e41d0273518620144041bffc16d8887d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Tue, 16 Feb 2021 00:06:43 +0100 Subject: [PATCH 090/144] fix depthStencilAttachment --- op_crates/webgpu/01_webgpu.js | 1 + 1 file changed, 1 insertion(+) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7c02f0c59f08be..1061461be61c54 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -618,6 +618,7 @@ ) { depthStencilAttachment.stencilLoadOp = descriptor.depthStencilAttachment.stencilLoadValue; + depthStencilAttachment.stencilLoadValue = undefined; } else { depthStencilAttachment.stencilLoadOp = "clear"; depthStencilAttachment.stencilLoadValue = From 821490abcca18b53d3f32ff1f4f81e19f8ff36e8 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 16 Feb 2021 02:06:05 +0100 Subject: [PATCH 091/144] start on webidl --- op_crates/web/00_webidl.js | 24 +++-- op_crates/web/internal.d.ts | 2 +- op_crates/webgpu/01_webgpu.js | 190 ++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 11 deletions(-) diff --git a/op_crates/web/00_webidl.js b/op_crates/web/00_webidl.js index 8831cb71e66f1d..94f51a07a875dd 100644 --- a/op_crates/web/00_webidl.js +++ b/op_crates/web/00_webidl.js @@ -14,7 +14,7 @@ return new ErrorType( `${opts.prefix ? opts.prefix + ": " : ""}${ opts.context ? opts.context : "Value" - } ${message}.`, + } ${message}`, ); } @@ -637,13 +637,15 @@ esMemberValue = esDict[key]; } + const context = `'${key}' of '${name}'${ + opts.context ? ` (${opts.context})` : "" + }`; + if (esMemberValue !== undefined) { const converter = member.converter; const idlMemberValue = converter(esMemberValue, { ...opts, - context: `${key} of '${name}'${ - opts.context ? `(${opts.context})` : "" - }`, + context, }); idlDict[key] = idlMemberValue; } else if ("defaultValue" in member) { @@ -651,8 +653,10 @@ const idlMemberValue = defaultValue; idlDict[key] = idlMemberValue; } else if (member.required) { - throw new TypeError( - `can not be converted to '${name}' because ${key} is required in '${name}'.`, + throw makeException( + TypeError, + `can not be converted to '${name}' because '${key}' is required in '${name}'.`, + { ...opts }, ); } } @@ -670,10 +674,10 @@ const S = String(V); if (!E.has(S)) { - throw makeException( - TypeError, - `The provided value '${V}' is not a valid enum value of type ${name}.`, - opts, + throw new TypeError( + `${ + opts.prefix ? opts.prefix + ": " : "" + }The provided value '${S}' is not a valid enum value of type ${name}.`, ); } diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 04fc061bbaf676..9014ff711f961e 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -205,7 +205,7 @@ declare namespace globalThis { declare interface DictionaryMember { key: string; converter: (v: any, opts: ValueConverterOpts) => any; - defaultValue?: boolean; + defaultValue?: any; required?: boolean; } diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 1061461be61c54..ab7ef01ce3d3d8 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1,7 +1,12 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +// @ts-check +/// +/// + ((window) => { const core = window.Deno.core; + const webidl = window.__bootstrap.webidl; const ridSymbol = Symbol("rid"); @@ -49,8 +54,185 @@ } } + const wgpuEnums = { + GPUPowerPreference: webidl.createEnumConverter("GPUPowerPreference", [ + "low-power", + "high-performance", + ]), + GPUTextureDimension: webidl.createEnumConverter("GPUTextureDimension", [ + "1d", + "2d", + "3d", + ]), + GPUTextureFormat: webidl.createEnumConverter("GPUTextureFormat", [ + // 8-bit formats + "r8unorm", + "r8snorm", + "r8uint", + "r8sint", + + // 16-bit formats + "r16uint", + "r16sint", + "r16float", + "rg8unorm", + "rg8snorm", + "rg8uint", + "rg8sint", + + // 32-bit formats + "r32uint", + "r32sint", + "r32float", + "rg16uint", + "rg16sint", + "rg16float", + "rgba8unorm", + "rgba8unorm-srgb", + "rgba8snorm", + "rgba8uint", + "rgba8sint", + "bgra8unorm", + "bgra8unorm-srgb", + // Packed 32-bit formats + "rgb9e5ufloat", + "rgb10a2unorm", + "rg11b10ufloat", + + // 64-bit formats + "rg32uint", + "rg32sint", + "rg32float", + "rgba16uint", + "rgba16sint", + "rgba16float", + + // 128-bit formats + "rgba32uint", + "rgba32sint", + "rgba32float", + + // Depth and stencil formats + "stencil8", + "depth16unorm", + "depth24plus", + "depth24plus-stencil8", + "depth32float", + + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + "bc1-rgba-unorm", + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm", + "bc3-rgba-unorm-srgb", + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm", + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb", + + // "depth24unorm-stencil8" feature + "depth24unorm-stencil8", + + // "depth32float-stencil8" feature + "depth32float-stencil8", + ]), + }; + const wgpuTypedefs = { + GPUSize64: (v, opts) => + webidl.converters["unsigned long long"](v, { + ...opts, + enforceRange: true, + }), + GPUSize32: (v, opts) => + webidl.converters["unsigned long"](v, { + ...opts, + enforceRange: true, + }), + GPUBufferUsageFlags: (v, opts) => + webidl.converters["unsigned long"](v, { + ...opts, + enforceRange: true, + }), + GPUIntegerCoordinate: (v, opts) => + webidl.converters["unsigned long"](v, { + ...opts, + enforceRange: true, + }), + GPUTextureUsageFlags: (v, opts) => + webidl.converters["unsigned long"](v, { + ...opts, + enforceRange: true, + }), + // TODO(lucacasonato): fixme when we implement WebIDL union and sequence + GPUExtent3D: webidl.converters.any, + }; + const wgpuDicts = { + GPURequestAdapterOptions: webidl.createDictionaryConverter( + "GPURequestAdapterOptions", + [{ converter: wgpuEnums.GPUPowerPreference, key: "powerPreference" }], + ), + GPUBufferDescriptor: webidl.createDictionaryConverter( + "GPUBufferDescriptor", + [ + { key: "size", converter: wgpuTypedefs.GPUSize64, required: true }, + { + key: "usage", + converter: wgpuTypedefs.GPUBufferUsageFlags, + required: true, + }, + { + key: "mappedAtCreation", + converter: webidl.converters.boolean, + defaultValue: false, + }, + ], + ), + GPUTextureDescriptor: webidl.createDictionaryConverter( + "GPUTextureDescriptor", + [ + { key: "size", converter: webidl.converters.any, required: true }, + { + key: "mipLevelCount", + converter: wgpuTypedefs.GPUIntegerCoordinate, + defaultValue: 1, + }, + { + key: "sampleCount", + converter: wgpuTypedefs.GPUSize64, + defaultValue: 1, + }, + { + key: "dimension", + converter: wgpuEnums.GPUTextureDimension, + defaultValue: "2d", + }, + { + key: "format", + converter: wgpuEnums.GPUTextureFormat, + required: true, + }, + { + key: "usage", + converter: wgpuTypedefs.GPUTextureUsageFlags, + required: true, + }, + ], + ), + }; + const gpu = { async requestAdapter(options = {}) { + options = wgpuDicts.GPURequestAdapterOptions(options, { + prefix: "Failed to execute 'requestAdapter' on 'GPU'", + context: "Argument 1", + }); + const { error, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", { @@ -144,6 +326,10 @@ } createBuffer(descriptor) { + descriptor = wgpuDicts.GPUBufferDescriptor(descriptor, { + prefix: "Failed to execute 'createBuffer' on 'GPUDevice'", + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { deviceRid: this.#rid, ...descriptor, @@ -160,6 +346,10 @@ } createTexture(descriptor) { + descriptor = wgpuDicts.GPUTextureDescriptor(descriptor, { + prefix: "Failed to execute 'createTexture' on 'GPUDevice'", + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_texture", { deviceRid: this.#rid, ...descriptor, From 2a3cf4951854ec61c7f0cfed40a9b7a003f29314 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 17 Feb 2021 01:35:58 +0100 Subject: [PATCH 092/144] add DENO_WEBGPU_TRACE env var --- cli/flags.rs | 1 + op_crates/webgpu/lib.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/flags.rs b/cli/flags.rs index f7c83294cd50fc..e4d6a8c7ed6623 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -224,6 +224,7 @@ static ENV_VARIABLES_HELP: &str = "ENVIRONMENT VARIABLES: DENO_INSTALL_ROOT Set deno install's output directory (defaults to $HOME/.deno/bin) DENO_CERT Load certificate authority from PEM encoded file + DENO_WEBGPU_TRACE Directory to use for wgpu traces NO_COLOR Set to disable color HTTP_PROXY Proxy address for HTTP requests (module downloads, fetch) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index bc6596aee3acf7..630e339331a281 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -401,7 +401,7 @@ pub async fn op_webgpu_request_device( let device = gfx_select_err!(adapter => instance.adapter_request_device( adapter, &descriptor, - Some(std::path::Path::new("./trace")), // TODO: remove + option_env!("DENO_WEBGPU_TRACE").map(std::path::Path::new), std::marker::PhantomData ))?; From ee1af0a49322ad9953587d3a42b4fc30b65d9fd2 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 01:59:08 +0100 Subject: [PATCH 093/144] fix free before use in dynamic_offsets_data --- op_crates/webgpu/render_pass.rs | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 67575cc65d96b1..1d21fba9f59e70 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -356,23 +356,36 @@ pub fn op_webgpu_render_pass_set_bind_group( .get::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( - &mut render_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - match args.dynamic_offsets_data { - Some(data) => data.as_ptr(), - None => { - let (prefix, data, suffix) = zero_copy[0].align_to::(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data[args.dynamic_offsets_data_start..].as_ptr() - } - }, - args.dynamic_offsets_data_length, - ); - } + // I know this might look like it can be easily deduplicated, but it can not + // be due to the lifetime of the args.dynamic_offsets_data slice. Because we + // need to use a raw pointer here the slice can be freed before the pointer + // is used in wgpu_render_pass_set_bind_group. See + // https://matrix.to/#/!XFRnMvAfptAHthwBCx:matrix.org/$HgrlhD-Me1DwsGb8UdMu2Hqubgks8s7ILwWRwigOUAg + match args.dynamic_offsets_data { + Some(data) => unsafe { + wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( + &mut render_pass_resource.0.borrow_mut(), + args.index, + bind_group_resource.0, + data.as_slice().as_ptr(), + args.dynamic_offsets_data_length, + ); + }, + None => { + let (prefix, data, suffix) = unsafe { zero_copy[0].align_to::() }; + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + unsafe { + wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( + &mut render_pass_resource.0.borrow_mut(), + args.index, + bind_group_resource.0, + data[args.dynamic_offsets_data_start..].as_ptr(), + args.dynamic_offsets_data_length, + ); + } + } + }; Ok(json!({})) } From 0c32f516c8bc269748b1cda3103b3750c8682405 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 01:59:53 +0100 Subject: [PATCH 094/144] start on webidl --- op_crates/web/00_webidl.js | 32 + op_crates/web/02_event.js | 1 + op_crates/web/internal.d.ts | 44 +- op_crates/webgpu/01_idl_types.js | 1249 +++++++++++++++++ .../webgpu/{01_webgpu.js => 02_webgpu.js} | 484 +++---- op_crates/webgpu/lib.rs | 53 +- op_crates/webgpu/webgpu.idl | 1023 ++++++++++++++ 7 files changed, 2630 insertions(+), 256 deletions(-) create mode 100644 op_crates/webgpu/01_idl_types.js rename op_crates/webgpu/{01_webgpu.js => 02_webgpu.js} (82%) create mode 100644 op_crates/webgpu/webgpu.idl diff --git a/op_crates/web/00_webidl.js b/op_crates/web/00_webidl.js index 94f51a07a875dd..dfa8e205ec502e 100644 --- a/op_crates/web/00_webidl.js +++ b/op_crates/web/00_webidl.js @@ -698,6 +698,33 @@ }; } + function illegalConstructor() { + throw new TypeError("Illegal constructor"); + } + + const brand = Symbol("[[webidl.brand]]"); + + function createBranded(Type) { + const t = Object.create(Type.prototype); + t[brand] = brand; + return t; + } + + function assertBranded(self, prototype) { + if (!(self instanceof prototype) || self[brand] !== brand) { + throw new TypeError("Illegal invocation"); + } + } + + function createInterfaceConverter(name, prototype) { + return (V, opts) => { + if (!(V instanceof prototype) || V[brand] !== brand) { + throw makeException(TypeError, `is not of type ${name}.`, opts); + } + return V; + }; + } + window.__bootstrap ??= {}; window.__bootstrap.webidl = { converters, @@ -705,5 +732,10 @@ createDictionaryConverter, createEnumConverter, createNullableConverter, + illegalConstructor, + brand, + createBranded, + assertBranded, + createInterfaceConverter, }; })(this); diff --git a/op_crates/web/02_event.js b/op_crates/web/02_event.js index d253599e5ec32d..ac813d0911c600 100644 --- a/op_crates/web/02_event.js +++ b/op_crates/web/02_event.js @@ -1204,6 +1204,7 @@ window.removeEventListener = EventTarget.prototype.removeEventListener; window.__bootstrap = (window.__bootstrap || {}); window.__bootstrap.eventTarget = { + EventTarget, setEventTargetData, }; window.__bootstrap.event = { diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 9014ff711f961e..32abc79a5a919e 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -158,7 +158,7 @@ declare namespace globalThis { */ Uint8ClampedArray( v: any, - opts?: BufferConverterOpts, + opts?: BufferConverterOpts ): Uint8ClampedArray; /** * Convert a value into a `Float32Array` (Float32Array). @@ -177,7 +177,7 @@ declare namespace globalThis { */ BufferSource( v: any, - opts?: BufferConverterOpts, + opts?: BufferConverterOpts ): ArrayBuffer | ArrayBufferView; /** * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long @@ -191,6 +191,8 @@ declare namespace globalThis { * Convert a value into a `VoidFunction` (() => void). */ VoidFunction(v: any, opts?: ValueConverterOpts): () => void; + + [type: string]: (v: any, opts: ValueConverterOpts) => any; }; /** @@ -199,7 +201,7 @@ declare namespace globalThis { declare function requiredArguments( length: number, required: number, - opts: ConverterOpts, + opts: ConverterOpts ): void; declare type Dictionary = DictionaryMember[]; declare interface DictionaryMember { @@ -222,17 +224,49 @@ declare namespace globalThis { */ declare function createEnumConverter( name: string, - values: string[], + values: string[] ): (v: any, opts: ValueConverterOpts) => string; /** * Create a converter that makes the contained type nullable. */ declare function createNullableConverter( - converter: (v: any, opts: ValueConverterOpts) => T, + converter: (v: any, opts: ValueConverterOpts) => T ): (v: any, opts: ValueConverterOpts) => T | null; + + /** + * Throw an illegal constructor error. + */ + declare function illegalConstructor(): never; + + /** + * The branding symbol. + */ + declare const brand: unique symbol; + + /** + * Create a branded instance of an interface. + */ + declare function createBranded(self: any): any; + + /** + * Assert that self is branded. + */ + declare function assertBranded(self: any, type: any): void; + + /** + * Create a converter for interfaces. + */ + declare function createInterfaceConverter( + name: string, + prototype: any + ): (v: any, opts: ValueConverterOpts) => any; } + declare var eventTarget: { + EventTarget: typeof EventTarget; + }; + declare var url: { URLSearchParams: typeof URLSearchParams; }; diff --git a/op_crates/webgpu/01_idl_types.js b/op_crates/webgpu/01_idl_types.js new file mode 100644 index 00000000000000..9825a8d03543d6 --- /dev/null +++ b/op_crates/webgpu/01_idl_types.js @@ -0,0 +1,1249 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// + +"use strict"; + +((window) => { + const webidl = window.__bootstrap.webidl; + + // DICTIONARY: GPUObjectDescriptorBase + const dictMembersGPUObjectDescriptorBase = [ + { key: "label", converter: webidl.converters["USVString"] }, + ]; + webidl.converters["GPUObjectDescriptorBase"] = webidl + .createDictionaryConverter( + "GPUObjectDescriptorBase", + dictMembersGPUObjectDescriptorBase, + ); + + // ENUM: GPUPowerPreference + webidl.converters["GPUPowerPreference"] = webidl.createEnumConverter( + "GPUPowerPreference", + [ + "low-power", + "high-performance", + ], + ); + + // DICTIONARY: GPURequestAdapterOptions + const dictMembersGPURequestAdapterOptions = [ + { + key: "powerPreference", + converter: webidl.converters["GPUPowerPreference"], + }, + ]; + webidl.converters["GPURequestAdapterOptions"] = webidl + .createDictionaryConverter( + "GPURequestAdapterOptions", + dictMembersGPURequestAdapterOptions, + ); + + // DICTIONARY: GPUDeviceDescriptor + const dictMembersGPUDeviceDescriptor = [ + { key: "nonGuaranteedFeatures", converter: webidl.converters.any }, + { key: "nonGuaranteedLimits", converter: webidl.converters.any }, + ]; + webidl.converters["GPUDeviceDescriptor"] = webidl.createDictionaryConverter( + "GPUDeviceDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUDeviceDescriptor, + ); + + // ENUM: GPUFeatureName + webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( + "GPUFeatureName", + [ + "depth-clamping", + "depth24unorm-stencil8", + "depth32float-stencil8", + "pipeline-statistics-query", + "texture-compression-bc", + "timestamp-query", + ], + ); + + // TYPEDEF: GPUSize64 + webidl.converters["GPUSize64"] = (V, opts) => + webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUBufferUsageFlags + webidl.converters["GPUBufferUsageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUBufferDescriptor + const dictMembersGPUBufferDescriptor = [ + { key: "size", converter: webidl.converters["GPUSize64"], required: true }, + { + key: "usage", + converter: webidl.converters["GPUBufferUsageFlags"], + required: true, + }, + { key: "mappedAtCreation", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPUBufferDescriptor"] = webidl.createDictionaryConverter( + "GPUBufferDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBufferDescriptor, + ); + + // TYPEDEF: GPUMapModeFlags + webidl.converters["GPUMapModeFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUExtent3D + webidl.converters["GPUExtent3D"] = webidl.converters.any; + + // TYPEDEF: GPUIntegerCoordinate + webidl.converters["GPUIntegerCoordinate"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUSize32 + webidl.converters["GPUSize32"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // ENUM: GPUTextureDimension + webidl.converters["GPUTextureDimension"] = webidl.createEnumConverter( + "GPUTextureDimension", + [ + "1d", + "2d", + "3d", + ], + ); + + // ENUM: GPUTextureFormat + webidl.converters["GPUTextureFormat"] = webidl.createEnumConverter( + "GPUTextureFormat", + [ + "r8unorm", + "r8snorm", + "r8uint", + "r8sint", + "r16uint", + "r16sint", + "r16float", + "rg8unorm", + "rg8snorm", + "rg8uint", + "rg8sint", + "r32uint", + "r32sint", + "r32float", + "rg16uint", + "rg16sint", + "rg16float", + "rgba8unorm", + "rgba8unorm-srgb", + "rgba8snorm", + "rgba8uint", + "rgba8sint", + "bgra8unorm", + "bgra8unorm-srgb", + "rgb9e5ufloat", + "rgb10a2unorm", + "rg11b10ufloat", + "rg32uint", + "rg32sint", + "rg32float", + "rgba16uint", + "rgba16sint", + "rgba16float", + "rgba32uint", + "rgba32sint", + "rgba32float", + "stencil8", + "depth16unorm", + "depth24plus", + "depth24plus-stencil8", + "depth32float", + "bc1-rgba-unorm", + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm", + "bc3-rgba-unorm-srgb", + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm", + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb", + "depth24unorm-stencil8", + "depth32float-stencil8", + ], + ); + + // TYPEDEF: GPUTextureUsageFlags + webidl.converters["GPUTextureUsageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUTextureDescriptor + const dictMembersGPUTextureDescriptor = [ + { + key: "size", + converter: webidl.converters["GPUExtent3D"], + required: true, + }, + { + key: "mipLevelCount", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + { key: "sampleCount", converter: webidl.converters["GPUSize32"] }, + { key: "dimension", converter: webidl.converters["GPUTextureDimension"] }, + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { + key: "usage", + converter: webidl.converters["GPUTextureUsageFlags"], + required: true, + }, + ]; + webidl.converters["GPUTextureDescriptor"] = webidl.createDictionaryConverter( + "GPUTextureDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUTextureDescriptor, + ); + + // ENUM: GPUTextureViewDimension + webidl.converters["GPUTextureViewDimension"] = webidl.createEnumConverter( + "GPUTextureViewDimension", + [ + "1d", + "2d", + "2d-array", + "cube", + "cube-array", + "3d", + ], + ); + + // ENUM: GPUTextureAspect + webidl.converters["GPUTextureAspect"] = webidl.createEnumConverter( + "GPUTextureAspect", + [ + "all", + "stencil-only", + "depth-only", + ], + ); + + // DICTIONARY: GPUTextureViewDescriptor + const dictMembersGPUTextureViewDescriptor = [ + { key: "format", converter: webidl.converters["GPUTextureFormat"] }, + { + key: "dimension", + converter: webidl.converters["GPUTextureViewDimension"], + }, + { key: "aspect", converter: webidl.converters["GPUTextureAspect"] }, + { + key: "baseMipLevel", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + { + key: "mipLevelCount", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + { + key: "baseArrayLayer", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + { + key: "arrayLayerCount", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + ]; + webidl.converters["GPUTextureViewDescriptor"] = webidl + .createDictionaryConverter( + "GPUTextureViewDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUTextureViewDescriptor, + ); + + // ENUM: GPUAddressMode + webidl.converters["GPUAddressMode"] = webidl.createEnumConverter( + "GPUAddressMode", + [ + "clamp-to-edge", + "repeat", + "mirror-repeat", + ], + ); + + // ENUM: GPUFilterMode + webidl.converters["GPUFilterMode"] = webidl.createEnumConverter( + "GPUFilterMode", + [ + "nearest", + "linear", + ], + ); + + // ENUM: GPUCompareFunction + webidl.converters["GPUCompareFunction"] = webidl.createEnumConverter( + "GPUCompareFunction", + [ + "never", + "less", + "equal", + "less-equal", + "greater", + "not-equal", + "greater-equal", + "always", + ], + ); + + // DICTIONARY: GPUSamplerDescriptor + const dictMembersGPUSamplerDescriptor = [ + { key: "addressModeU", converter: webidl.converters["GPUAddressMode"] }, + { key: "addressModeV", converter: webidl.converters["GPUAddressMode"] }, + { key: "addressModeW", converter: webidl.converters["GPUAddressMode"] }, + { key: "magFilter", converter: webidl.converters["GPUFilterMode"] }, + { key: "minFilter", converter: webidl.converters["GPUFilterMode"] }, + { key: "mipmapFilter", converter: webidl.converters["GPUFilterMode"] }, + { key: "lodMinClamp", converter: webidl.converters["float"] }, + { key: "lodMaxClamp", converter: webidl.converters["float"] }, + { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, + { + key: "maxAnisotropy", + converter: (V, opts) => + webidl.converters["unsigned short"](V, { ...opts, clamp: true }), + }, + ]; + webidl.converters["GPUSamplerDescriptor"] = webidl.createDictionaryConverter( + "GPUSamplerDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUSamplerDescriptor, + ); + + // DICTIONARY: GPUBindGroupLayoutDescriptor + const dictMembersGPUBindGroupLayoutDescriptor = [ + { key: "entries", converter: webidl.converters.any, required: true }, + ]; + webidl.converters["GPUBindGroupLayoutDescriptor"] = webidl + .createDictionaryConverter( + "GPUBindGroupLayoutDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBindGroupLayoutDescriptor, + ); + + // TYPEDEF: GPUShaderStageFlags + webidl.converters["GPUShaderStageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUIndex32 + webidl.converters["GPUIndex32"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // ENUM: GPUBufferBindingType + webidl.converters["GPUBufferBindingType"] = webidl.createEnumConverter( + "GPUBufferBindingType", + [ + "uniform", + "storage", + "read-only-storage", + ], + ); + + // DICTIONARY: GPUBufferBindingLayout + const dictMembersGPUBufferBindingLayout = [ + { key: "type", converter: webidl.converters["GPUBufferBindingType"] }, + { key: "hasDynamicOffset", converter: webidl.converters["boolean"] }, + { key: "minBindingSize", converter: webidl.converters["GPUSize64"] }, + ]; + webidl.converters["GPUBufferBindingLayout"] = webidl + .createDictionaryConverter( + "GPUBufferBindingLayout", + dictMembersGPUBufferBindingLayout, + ); + + // ENUM: GPUSamplerBindingType + webidl.converters["GPUSamplerBindingType"] = webidl.createEnumConverter( + "GPUSamplerBindingType", + [ + "filtering", + "non-filtering", + "comparison", + ], + ); + + // DICTIONARY: GPUSamplerBindingLayout + const dictMembersGPUSamplerBindingLayout = [ + { key: "type", converter: webidl.converters["GPUSamplerBindingType"] }, + ]; + webidl.converters["GPUSamplerBindingLayout"] = webidl + .createDictionaryConverter( + "GPUSamplerBindingLayout", + dictMembersGPUSamplerBindingLayout, + ); + + // ENUM: GPUTextureSampleType + webidl.converters["GPUTextureSampleType"] = webidl.createEnumConverter( + "GPUTextureSampleType", + [ + "float", + "unfilterable-float", + "depth", + "sint", + "uint", + ], + ); + + // DICTIONARY: GPUTextureBindingLayout + const dictMembersGPUTextureBindingLayout = [ + { key: "sampleType", converter: webidl.converters["GPUTextureSampleType"] }, + { + key: "viewDimension", + converter: webidl.converters["GPUTextureViewDimension"], + }, + { key: "multisampled", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPUTextureBindingLayout"] = webidl + .createDictionaryConverter( + "GPUTextureBindingLayout", + dictMembersGPUTextureBindingLayout, + ); + + // ENUM: GPUStorageTextureAccess + webidl.converters["GPUStorageTextureAccess"] = webidl.createEnumConverter( + "GPUStorageTextureAccess", + [ + "read-only", + "write-only", + ], + ); + + // DICTIONARY: GPUStorageTextureBindingLayout + const dictMembersGPUStorageTextureBindingLayout = [ + { + key: "access", + converter: webidl.converters["GPUStorageTextureAccess"], + required: true, + }, + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { + key: "viewDimension", + converter: webidl.converters["GPUTextureViewDimension"], + }, + ]; + webidl.converters["GPUStorageTextureBindingLayout"] = webidl + .createDictionaryConverter( + "GPUStorageTextureBindingLayout", + dictMembersGPUStorageTextureBindingLayout, + ); + + // DICTIONARY: GPUBindGroupLayoutEntry + const dictMembersGPUBindGroupLayoutEntry = [ + { + key: "binding", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + { + key: "visibility", + converter: webidl.converters["GPUShaderStageFlags"], + required: true, + }, + { key: "buffer", converter: webidl.converters["GPUBufferBindingLayout"] }, + { key: "sampler", converter: webidl.converters["GPUSamplerBindingLayout"] }, + { key: "texture", converter: webidl.converters["GPUTextureBindingLayout"] }, + { + key: "storageTexture", + converter: webidl.converters["GPUStorageTextureBindingLayout"], + }, + ]; + webidl.converters["GPUBindGroupLayoutEntry"] = webidl + .createDictionaryConverter( + "GPUBindGroupLayoutEntry", + dictMembersGPUBindGroupLayoutEntry, + ); + + // DICTIONARY: GPUBindGroupDescriptor + const dictMembersGPUBindGroupDescriptor = [ + { + key: "layout", + converter: webidl.converters["GPUBindGroupLayout"], + required: true, + }, + { key: "entries", converter: webidl.converters.any, required: true }, + ]; + webidl.converters["GPUBindGroupDescriptor"] = webidl + .createDictionaryConverter( + "GPUBindGroupDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBindGroupDescriptor, + ); + + // TYPEDEF: GPUBindingResource + webidl.converters["GPUBindingResource"] = webidl.converters.any; + + // DICTIONARY: GPUBindGroupEntry + const dictMembersGPUBindGroupEntry = [ + { + key: "binding", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + { + key: "resource", + converter: webidl.converters["GPUBindingResource"], + required: true, + }, + ]; + webidl.converters["GPUBindGroupEntry"] = webidl.createDictionaryConverter( + "GPUBindGroupEntry", + dictMembersGPUBindGroupEntry, + ); + + // DICTIONARY: GPUBufferBinding + const dictMembersGPUBufferBinding = [ + { + key: "buffer", + converter: webidl.converters["GPUBuffer"], + required: true, + }, + { key: "offset", converter: webidl.converters["GPUSize64"] }, + { key: "size", converter: webidl.converters["GPUSize64"] }, + ]; + webidl.converters["GPUBufferBinding"] = webidl.createDictionaryConverter( + "GPUBufferBinding", + dictMembersGPUBufferBinding, + ); + + // DICTIONARY: GPUPipelineLayoutDescriptor + const dictMembersGPUPipelineLayoutDescriptor = [ + { + key: "bindGroupLayouts", + converter: webidl.converters.any, + required: true, + }, + ]; + webidl.converters["GPUPipelineLayoutDescriptor"] = webidl + .createDictionaryConverter( + "GPUPipelineLayoutDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineLayoutDescriptor, + ); + + // ENUM: GPUCompilationMessageType + webidl.converters["GPUCompilationMessageType"] = webidl.createEnumConverter( + "GPUCompilationMessageType", + [ + "error", + "warning", + "info", + ], + ); + + // DICTIONARY: GPUShaderModuleDescriptor + const dictMembersGPUShaderModuleDescriptor = [ + { key: "code", converter: webidl.converters["USVString"], required: true }, + { key: "sourceMap", converter: webidl.converters["object"] }, + ]; + webidl.converters["GPUShaderModuleDescriptor"] = webidl + .createDictionaryConverter( + "GPUShaderModuleDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUShaderModuleDescriptor, + ); + + // DICTIONARY: GPUPipelineDescriptorBase + const dictMembersGPUPipelineDescriptorBase = [ + { key: "layout", converter: webidl.converters["GPUPipelineLayout"] }, + ]; + webidl.converters["GPUPipelineDescriptorBase"] = webidl + .createDictionaryConverter( + "GPUPipelineDescriptorBase", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineDescriptorBase, + ); + + // DICTIONARY: GPUProgrammableStage + const dictMembersGPUProgrammableStage = [ + { + key: "module", + converter: webidl.converters["GPUShaderModule"], + required: true, + }, + { + key: "entryPoint", + converter: webidl.converters["USVString"], + required: true, + }, + ]; + webidl.converters["GPUProgrammableStage"] = webidl.createDictionaryConverter( + "GPUProgrammableStage", + dictMembersGPUProgrammableStage, + ); + + // DICTIONARY: GPUComputePipelineDescriptor + const dictMembersGPUComputePipelineDescriptor = [ + { + key: "compute", + converter: webidl.converters["GPUProgrammableStage"], + required: true, + }, + ]; + webidl.converters["GPUComputePipelineDescriptor"] = webidl + .createDictionaryConverter( + "GPUComputePipelineDescriptor", + dictMembersGPUPipelineDescriptorBase, + dictMembersGPUComputePipelineDescriptor, + ); + + // DICTIONARY: GPUVertexState + const dictMembersGPUVertexState = [ + { key: "buffers", converter: webidl.converters.any }, + ]; + webidl.converters["GPUVertexState"] = webidl.createDictionaryConverter( + "GPUVertexState", + dictMembersGPUProgrammableStage, + dictMembersGPUVertexState, + ); + + // ENUM: GPUPrimitiveTopology + webidl.converters["GPUPrimitiveTopology"] = webidl.createEnumConverter( + "GPUPrimitiveTopology", + [ + "point-list", + "line-list", + "line-strip", + "triangle-list", + "triangle-strip", + ], + ); + + // ENUM: GPUIndexFormat + webidl.converters["GPUIndexFormat"] = webidl.createEnumConverter( + "GPUIndexFormat", + [ + "uint16", + "uint32", + ], + ); + + // ENUM: GPUFrontFace + webidl.converters["GPUFrontFace"] = webidl.createEnumConverter( + "GPUFrontFace", + [ + "ccw", + "cw", + ], + ); + + // ENUM: GPUCullMode + webidl.converters["GPUCullMode"] = webidl.createEnumConverter("GPUCullMode", [ + "none", + "front", + "back", + ]); + + // DICTIONARY: GPUPrimitiveState + const dictMembersGPUPrimitiveState = [ + { key: "topology", converter: webidl.converters["GPUPrimitiveTopology"] }, + { key: "stripIndexFormat", converter: webidl.converters["GPUIndexFormat"] }, + { key: "frontFace", converter: webidl.converters["GPUFrontFace"] }, + { key: "cullMode", converter: webidl.converters["GPUCullMode"] }, + ]; + webidl.converters["GPUPrimitiveState"] = webidl.createDictionaryConverter( + "GPUPrimitiveState", + dictMembersGPUPrimitiveState, + ); + + // ENUM: GPUStencilOperation + webidl.converters["GPUStencilOperation"] = webidl.createEnumConverter( + "GPUStencilOperation", + [ + "keep", + "zero", + "replace", + "invert", + "increment-clamp", + "decrement-clamp", + "increment-wrap", + "decrement-wrap", + ], + ); + + // DICTIONARY: GPUStencilFaceState + const dictMembersGPUStencilFaceState = [ + { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, + { key: "failOp", converter: webidl.converters["GPUStencilOperation"] }, + { key: "depthFailOp", converter: webidl.converters["GPUStencilOperation"] }, + { key: "passOp", converter: webidl.converters["GPUStencilOperation"] }, + ]; + webidl.converters["GPUStencilFaceState"] = webidl.createDictionaryConverter( + "GPUStencilFaceState", + dictMembersGPUStencilFaceState, + ); + + // TYPEDEF: GPUStencilValue + webidl.converters["GPUStencilValue"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUDepthBias + webidl.converters["GPUDepthBias"] = (V, opts) => + webidl.converters["long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUDepthStencilState + const dictMembersGPUDepthStencilState = [ + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { key: "depthWriteEnabled", converter: webidl.converters["boolean"] }, + { key: "depthCompare", converter: webidl.converters["GPUCompareFunction"] }, + { + key: "stencilFront", + converter: webidl.converters["GPUStencilFaceState"], + }, + { key: "stencilBack", converter: webidl.converters["GPUStencilFaceState"] }, + { key: "stencilReadMask", converter: webidl.converters["GPUStencilValue"] }, + { + key: "stencilWriteMask", + converter: webidl.converters["GPUStencilValue"], + }, + { key: "depthBias", converter: webidl.converters["GPUDepthBias"] }, + { key: "depthBiasSlopeScale", converter: webidl.converters["float"] }, + { key: "depthBiasClamp", converter: webidl.converters["float"] }, + { key: "clampDepth", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPUDepthStencilState"] = webidl.createDictionaryConverter( + "GPUDepthStencilState", + dictMembersGPUDepthStencilState, + ); + + // TYPEDEF: GPUSampleMask + webidl.converters["GPUSampleMask"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUMultisampleState + const dictMembersGPUMultisampleState = [ + { key: "count", converter: webidl.converters["GPUSize32"] }, + { key: "mask", converter: webidl.converters["GPUSampleMask"] }, + { key: "alphaToCoverageEnabled", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPUMultisampleState"] = webidl.createDictionaryConverter( + "GPUMultisampleState", + dictMembersGPUMultisampleState, + ); + + // DICTIONARY: GPUFragmentState + const dictMembersGPUFragmentState = [ + { key: "targets", converter: webidl.converters.any, required: true }, + ]; + webidl.converters["GPUFragmentState"] = webidl.createDictionaryConverter( + "GPUFragmentState", + dictMembersGPUProgrammableStage, + dictMembersGPUFragmentState, + ); + + // DICTIONARY: GPURenderPipelineDescriptor + const dictMembersGPURenderPipelineDescriptor = [ + { + key: "vertex", + converter: webidl.converters["GPUVertexState"], + required: true, + }, + { key: "primitive", converter: webidl.converters["GPUPrimitiveState"] }, + { + key: "depthStencil", + converter: webidl.converters["GPUDepthStencilState"], + }, + { key: "multisample", converter: webidl.converters["GPUMultisampleState"] }, + { key: "fragment", converter: webidl.converters["GPUFragmentState"] }, + ]; + webidl.converters["GPURenderPipelineDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderPipelineDescriptor", + dictMembersGPUPipelineDescriptorBase, + dictMembersGPURenderPipelineDescriptor, + ); + + // ENUM: GPUBlendFactor + webidl.converters["GPUBlendFactor"] = webidl.createEnumConverter( + "GPUBlendFactor", + [ + "zero", + "one", + "src-color", + "one-minus-src-color", + "src-alpha", + "one-minus-src-alpha", + "dst-color", + "one-minus-dst-color", + "dst-alpha", + "one-minus-dst-alpha", + "src-alpha-saturated", + "blend-color", + "one-minus-blend-color", + ], + ); + + // ENUM: GPUBlendOperation + webidl.converters["GPUBlendOperation"] = webidl.createEnumConverter( + "GPUBlendOperation", + [ + "add", + "subtract", + "reverse-subtract", + "min", + "max", + ], + ); + + // DICTIONARY: GPUBlendComponent + const dictMembersGPUBlendComponent = [ + { key: "srcFactor", converter: webidl.converters["GPUBlendFactor"] }, + { key: "dstFactor", converter: webidl.converters["GPUBlendFactor"] }, + { key: "operation", converter: webidl.converters["GPUBlendOperation"] }, + ]; + webidl.converters["GPUBlendComponent"] = webidl.createDictionaryConverter( + "GPUBlendComponent", + dictMembersGPUBlendComponent, + ); + + // DICTIONARY: GPUBlendState + const dictMembersGPUBlendState = [ + { + key: "color", + converter: webidl.converters["GPUBlendComponent"], + required: true, + }, + { + key: "alpha", + converter: webidl.converters["GPUBlendComponent"], + required: true, + }, + ]; + webidl.converters["GPUBlendState"] = webidl.createDictionaryConverter( + "GPUBlendState", + dictMembersGPUBlendState, + ); + + // TYPEDEF: GPUColorWriteFlags + webidl.converters["GPUColorWriteFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUColorTargetState + const dictMembersGPUColorTargetState = [ + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { key: "blend", converter: webidl.converters["GPUBlendState"] }, + { key: "writeMask", converter: webidl.converters["GPUColorWriteFlags"] }, + ]; + webidl.converters["GPUColorTargetState"] = webidl.createDictionaryConverter( + "GPUColorTargetState", + dictMembersGPUColorTargetState, + ); + + // ENUM: GPUVertexFormat + webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( + "GPUVertexFormat", + [ + "uchar2", + "uchar4", + "char2", + "char4", + "uchar2norm", + "uchar4norm", + "char2norm", + "char4norm", + "ushort2", + "ushort4", + "short2", + "short4", + "ushort2norm", + "ushort4norm", + "short2norm", + "short4norm", + "half2", + "half4", + "float", + "float2", + "float3", + "float4", + "uint", + "uint2", + "uint3", + "uint4", + "int", + "int2", + "int3", + "int4", + ], + ); + + // ENUM: GPUInputStepMode + webidl.converters["GPUInputStepMode"] = webidl.createEnumConverter( + "GPUInputStepMode", + [ + "vertex", + "instance", + ], + ); + + // DICTIONARY: GPUVertexBufferLayout + const dictMembersGPUVertexBufferLayout = [ + { + key: "arrayStride", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { key: "stepMode", converter: webidl.converters["GPUInputStepMode"] }, + { key: "attributes", converter: webidl.converters.any, required: true }, + ]; + webidl.converters["GPUVertexBufferLayout"] = webidl.createDictionaryConverter( + "GPUVertexBufferLayout", + dictMembersGPUVertexBufferLayout, + ); + + // DICTIONARY: GPUVertexAttribute + const dictMembersGPUVertexAttribute = [ + { + key: "format", + converter: webidl.converters["GPUVertexFormat"], + required: true, + }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { + key: "shaderLocation", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + ]; + webidl.converters["GPUVertexAttribute"] = webidl.createDictionaryConverter( + "GPUVertexAttribute", + dictMembersGPUVertexAttribute, + ); + + // DICTIONARY: GPUCommandBufferDescriptor + const dictMembersGPUCommandBufferDescriptor = []; + webidl.converters["GPUCommandBufferDescriptor"] = webidl + .createDictionaryConverter( + "GPUCommandBufferDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUCommandBufferDescriptor, + ); + + // DICTIONARY: GPUCommandEncoderDescriptor + const dictMembersGPUCommandEncoderDescriptor = [ + { key: "measureExecutionTime", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPUCommandEncoderDescriptor"] = webidl + .createDictionaryConverter( + "GPUCommandEncoderDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUCommandEncoderDescriptor, + ); + + // DICTIONARY: GPUImageDataLayout + const dictMembersGPUImageDataLayout = [ + { key: "offset", converter: webidl.converters["GPUSize64"] }, + { key: "bytesPerRow", converter: webidl.converters["GPUSize32"] }, + { key: "rowsPerImage", converter: webidl.converters["GPUSize32"] }, + ]; + webidl.converters["GPUImageDataLayout"] = webidl.createDictionaryConverter( + "GPUImageDataLayout", + dictMembersGPUImageDataLayout, + ); + + // DICTIONARY: GPUImageCopyBuffer + const dictMembersGPUImageCopyBuffer = [ + { + key: "buffer", + converter: webidl.converters["GPUBuffer"], + required: true, + }, + ]; + webidl.converters["GPUImageCopyBuffer"] = webidl.createDictionaryConverter( + "GPUImageCopyBuffer", + dictMembersGPUImageDataLayout, + dictMembersGPUImageCopyBuffer, + ); + + // TYPEDEF: GPUOrigin3D + webidl.converters["GPUOrigin3D"] = webidl.converters.any; + + // DICTIONARY: GPUImageCopyTexture + const dictMembersGPUImageCopyTexture = [ + { + key: "texture", + converter: webidl.converters["GPUTexture"], + required: true, + }, + { key: "mipLevel", converter: webidl.converters["GPUIntegerCoordinate"] }, + { key: "origin", converter: webidl.converters["GPUOrigin3D"] }, + { key: "aspect", converter: webidl.converters["GPUTextureAspect"] }, + ]; + webidl.converters["GPUImageCopyTexture"] = webidl.createDictionaryConverter( + "GPUImageCopyTexture", + dictMembersGPUImageCopyTexture, + ); + + // DICTIONARY: GPUComputePassDescriptor + const dictMembersGPUComputePassDescriptor = []; + webidl.converters["GPUComputePassDescriptor"] = webidl + .createDictionaryConverter( + "GPUComputePassDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUComputePassDescriptor, + ); + + // ENUM: GPUStoreOp + webidl.converters["GPUStoreOp"] = webidl.createEnumConverter("GPUStoreOp", [ + "store", + "clear", + ]); + + // DICTIONARY: GPURenderPassDepthStencilAttachment + const dictMembersGPURenderPassDepthStencilAttachment = [ + { + key: "view", + converter: webidl.converters["GPUTextureView"], + required: true, + }, + { key: "depthLoadValue", converter: webidl.converters.any, required: true }, + { + key: "depthStoreOp", + converter: webidl.converters["GPUStoreOp"], + required: true, + }, + { key: "depthReadOnly", converter: webidl.converters["boolean"] }, + { + key: "stencilLoadValue", + converter: webidl.converters.any, + required: true, + }, + { + key: "stencilStoreOp", + converter: webidl.converters["GPUStoreOp"], + required: true, + }, + { key: "stencilReadOnly", converter: webidl.converters["boolean"] }, + ]; + webidl.converters["GPURenderPassDepthStencilAttachment"] = webidl + .createDictionaryConverter( + "GPURenderPassDepthStencilAttachment", + dictMembersGPURenderPassDepthStencilAttachment, + ); + + // DICTIONARY: GPURenderPassDescriptor + const dictMembersGPURenderPassDescriptor = [ + { + key: "colorAttachments", + converter: webidl.converters.any, + required: true, + }, + { + key: "depthStencilAttachment", + converter: webidl.converters["GPURenderPassDepthStencilAttachment"], + }, + { key: "occlusionQuerySet", converter: webidl.converters["GPUQuerySet"] }, + ]; + webidl.converters["GPURenderPassDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderPassDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderPassDescriptor, + ); + + // DICTIONARY: GPURenderPassColorAttachment + const dictMembersGPURenderPassColorAttachment = [ + { + key: "view", + converter: webidl.converters["GPUTextureView"], + required: true, + }, + { key: "resolveTarget", converter: webidl.converters["GPUTextureView"] }, + { key: "loadValue", converter: webidl.converters.any, required: true }, + { key: "storeOp", converter: webidl.converters["GPUStoreOp"] }, + ]; + webidl.converters["GPURenderPassColorAttachment"] = webidl + .createDictionaryConverter( + "GPURenderPassColorAttachment", + dictMembersGPURenderPassColorAttachment, + ); + + // ENUM: GPULoadOp + webidl.converters["GPULoadOp"] = webidl.createEnumConverter("GPULoadOp", [ + "load", + ]); + + // DICTIONARY: GPURenderBundleDescriptor + const dictMembersGPURenderBundleDescriptor = []; + webidl.converters["GPURenderBundleDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderBundleDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderBundleDescriptor, + ); + + // DICTIONARY: GPURenderBundleEncoderDescriptor + const dictMembersGPURenderBundleEncoderDescriptor = [ + { key: "colorFormats", converter: webidl.converters.any, required: true }, + { + key: "depthStencilFormat", + converter: webidl.converters["GPUTextureFormat"], + }, + { key: "sampleCount", converter: webidl.converters["GPUSize32"] }, + ]; + webidl.converters["GPURenderBundleEncoderDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderBundleEncoderDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderBundleEncoderDescriptor, + ); + + // ENUM: GPUQueryType + webidl.converters["GPUQueryType"] = webidl.createEnumConverter( + "GPUQueryType", + [ + "occlusion", + "pipeline-statistics", + "timestamp", + ], + ); + + // DICTIONARY: GPUQuerySetDescriptor + const dictMembersGPUQuerySetDescriptor = [ + { + key: "type", + converter: webidl.converters["GPUQueryType"], + required: true, + }, + { key: "count", converter: webidl.converters["GPUSize32"], required: true }, + { key: "pipelineStatistics", converter: webidl.converters.any }, + ]; + webidl.converters["GPUQuerySetDescriptor"] = webidl.createDictionaryConverter( + "GPUQuerySetDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUQuerySetDescriptor, + ); + + // ENUM: GPUPipelineStatisticName + webidl.converters["GPUPipelineStatisticName"] = webidl.createEnumConverter( + "GPUPipelineStatisticName", + [ + "vertex-shader-invocations", + "clipper-invocations", + "clipper-primitives-out", + "fragment-shader-invocations", + "compute-shader-invocations", + ], + ); + + // ENUM: GPUDeviceLostReason + webidl.converters["GPUDeviceLostReason"] = webidl.createEnumConverter( + "GPUDeviceLostReason", + [ + "destroyed", + ], + ); + + // ENUM: GPUErrorFilter + webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter( + "GPUErrorFilter", + [ + "out-of-memory", + "validation", + ], + ); + + // TYPEDEF: GPUError + webidl.converters["GPUError"] = webidl.converters.any; + + // DICTIONARY: GPUUncapturedErrorEventInit + const dictMembersGPUUncapturedErrorEventInit = [ + { key: "error", converter: webidl.converters["GPUError"], required: true }, + ]; + webidl.converters["GPUUncapturedErrorEventInit"] = webidl + .createDictionaryConverter( + "GPUUncapturedErrorEventInit", + // dictMembersEventInit, + dictMembersGPUUncapturedErrorEventInit, + ); + + // TYPEDEF: GPUBufferDynamicOffset + webidl.converters["GPUBufferDynamicOffset"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUSignedOffset32 + webidl.converters["GPUSignedOffset32"] = (V, opts) => + webidl.converters["long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUFlagsConstant + webidl.converters["GPUFlagsConstant"] = webidl.converters["unsigned long"]; + + // DICTIONARY: GPUColorDict + const dictMembersGPUColorDict = [ + { key: "r", converter: webidl.converters["double"], required: true }, + { key: "g", converter: webidl.converters["double"], required: true }, + { key: "b", converter: webidl.converters["double"], required: true }, + { key: "a", converter: webidl.converters["double"], required: true }, + ]; + webidl.converters["GPUColorDict"] = webidl.createDictionaryConverter( + "GPUColorDict", + dictMembersGPUColorDict, + ); + + // TYPEDEF: GPUColor + webidl.converters["GPUColor"] = webidl.converters.any; + + // DICTIONARY: GPUOrigin2DDict + const dictMembersGPUOrigin2DDict = [ + { key: "x", converter: webidl.converters["GPUIntegerCoordinate"] }, + { key: "y", converter: webidl.converters["GPUIntegerCoordinate"] }, + ]; + webidl.converters["GPUOrigin2DDict"] = webidl.createDictionaryConverter( + "GPUOrigin2DDict", + dictMembersGPUOrigin2DDict, + ); + + // TYPEDEF: GPUOrigin2D + webidl.converters["GPUOrigin2D"] = webidl.converters.any; + + // DICTIONARY: GPUOrigin3DDict + const dictMembersGPUOrigin3DDict = [ + { key: "x", converter: webidl.converters["GPUIntegerCoordinate"] }, + { key: "y", converter: webidl.converters["GPUIntegerCoordinate"] }, + { key: "z", converter: webidl.converters["GPUIntegerCoordinate"] }, + ]; + webidl.converters["GPUOrigin3DDict"] = webidl.createDictionaryConverter( + "GPUOrigin3DDict", + dictMembersGPUOrigin3DDict, + ); + + // DICTIONARY: GPUExtent3DDict + const dictMembersGPUExtent3DDict = [ + { key: "width", converter: webidl.converters["GPUIntegerCoordinate"] }, + { key: "height", converter: webidl.converters["GPUIntegerCoordinate"] }, + { + key: "depthOrArrayLayers", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + ]; + webidl.converters["GPUExtent3DDict"] = webidl.createDictionaryConverter( + "GPUExtent3DDict", + dictMembersGPUExtent3DDict, + ); +})(this); diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/02_webgpu.js similarity index 82% rename from op_crates/webgpu/01_webgpu.js rename to op_crates/webgpu/02_webgpu.js index ab7ef01ce3d3d8..fd36f8028a2b50 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/02_webgpu.js @@ -3,10 +3,14 @@ // @ts-check /// /// +/// + +"use strict"; ((window) => { const core = window.Deno.core; const webidl = window.__bootstrap.webidl; + const eventTarget = window.__bootstrap.eventTarget; const ridSymbol = Symbol("rid"); @@ -54,181 +58,9 @@ } } - const wgpuEnums = { - GPUPowerPreference: webidl.createEnumConverter("GPUPowerPreference", [ - "low-power", - "high-performance", - ]), - GPUTextureDimension: webidl.createEnumConverter("GPUTextureDimension", [ - "1d", - "2d", - "3d", - ]), - GPUTextureFormat: webidl.createEnumConverter("GPUTextureFormat", [ - // 8-bit formats - "r8unorm", - "r8snorm", - "r8uint", - "r8sint", - - // 16-bit formats - "r16uint", - "r16sint", - "r16float", - "rg8unorm", - "rg8snorm", - "rg8uint", - "rg8sint", - - // 32-bit formats - "r32uint", - "r32sint", - "r32float", - "rg16uint", - "rg16sint", - "rg16float", - "rgba8unorm", - "rgba8unorm-srgb", - "rgba8snorm", - "rgba8uint", - "rgba8sint", - "bgra8unorm", - "bgra8unorm-srgb", - // Packed 32-bit formats - "rgb9e5ufloat", - "rgb10a2unorm", - "rg11b10ufloat", - - // 64-bit formats - "rg32uint", - "rg32sint", - "rg32float", - "rgba16uint", - "rgba16sint", - "rgba16float", - - // 128-bit formats - "rgba32uint", - "rgba32sint", - "rgba32float", - - // Depth and stencil formats - "stencil8", - "depth16unorm", - "depth24plus", - "depth24plus-stencil8", - "depth32float", - - // BC compressed formats usable if "texture-compression-bc" is both - // supported by the device/user agent and enabled in requestDevice. - "bc1-rgba-unorm", - "bc1-rgba-unorm-srgb", - "bc2-rgba-unorm", - "bc2-rgba-unorm-srgb", - "bc3-rgba-unorm", - "bc3-rgba-unorm-srgb", - "bc4-r-unorm", - "bc4-r-snorm", - "bc5-rg-unorm", - "bc5-rg-snorm", - "bc6h-rgb-ufloat", - "bc6h-rgb-float", - "bc7-rgba-unorm", - "bc7-rgba-unorm-srgb", - - // "depth24unorm-stencil8" feature - "depth24unorm-stencil8", - - // "depth32float-stencil8" feature - "depth32float-stencil8", - ]), - }; - const wgpuTypedefs = { - GPUSize64: (v, opts) => - webidl.converters["unsigned long long"](v, { - ...opts, - enforceRange: true, - }), - GPUSize32: (v, opts) => - webidl.converters["unsigned long"](v, { - ...opts, - enforceRange: true, - }), - GPUBufferUsageFlags: (v, opts) => - webidl.converters["unsigned long"](v, { - ...opts, - enforceRange: true, - }), - GPUIntegerCoordinate: (v, opts) => - webidl.converters["unsigned long"](v, { - ...opts, - enforceRange: true, - }), - GPUTextureUsageFlags: (v, opts) => - webidl.converters["unsigned long"](v, { - ...opts, - enforceRange: true, - }), - // TODO(lucacasonato): fixme when we implement WebIDL union and sequence - GPUExtent3D: webidl.converters.any, - }; - const wgpuDicts = { - GPURequestAdapterOptions: webidl.createDictionaryConverter( - "GPURequestAdapterOptions", - [{ converter: wgpuEnums.GPUPowerPreference, key: "powerPreference" }], - ), - GPUBufferDescriptor: webidl.createDictionaryConverter( - "GPUBufferDescriptor", - [ - { key: "size", converter: wgpuTypedefs.GPUSize64, required: true }, - { - key: "usage", - converter: wgpuTypedefs.GPUBufferUsageFlags, - required: true, - }, - { - key: "mappedAtCreation", - converter: webidl.converters.boolean, - defaultValue: false, - }, - ], - ), - GPUTextureDescriptor: webidl.createDictionaryConverter( - "GPUTextureDescriptor", - [ - { key: "size", converter: webidl.converters.any, required: true }, - { - key: "mipLevelCount", - converter: wgpuTypedefs.GPUIntegerCoordinate, - defaultValue: 1, - }, - { - key: "sampleCount", - converter: wgpuTypedefs.GPUSize64, - defaultValue: 1, - }, - { - key: "dimension", - converter: wgpuEnums.GPUTextureDimension, - defaultValue: "2d", - }, - { - key: "format", - converter: wgpuEnums.GPUTextureFormat, - required: true, - }, - { - key: "usage", - converter: wgpuTypedefs.GPUTextureUsageFlags, - required: true, - }, - ], - ), - }; - const gpu = { async requestAdapter(options = {}) { - options = wgpuDicts.GPURequestAdapterOptions(options, { + options = webidl.converters.GPURequestAdapterOptions(options, { prefix: "Failed to execute 'requestAdapter' on 'GPU'", context: "Argument 1", }); @@ -243,102 +75,192 @@ if (error) { return null; } else { - return new GPUAdapter(keySymbol, data); + return createGPUAdapter(data.name, data); } }, }; + const _name = Symbol("[[name]]"); + const _adapter = Symbol("[[adapter]]"); + + /** + * @typedef InnerGPUAdapter + * @property {number} rid + * @property {GPUAdapterFeatures} features + * @property {GPUAdapterLimits} limits + */ + + /** + * @param {string} name + * @param {InnerGPUAdapter} inner + * @returns {GPUAdapter} + */ + function createGPUAdapter(name, inner) { + /** @type {GPUAdapter} */ + const adapter = webidl.createBranded(GPUAdapter); + adapter[_name] = name; + adapter[_adapter] = inner; + return adapter; + } + class GPUAdapter { - #rid; - #name; + /** @type {string} */ + [_name]; + /** @type {InnerGPUAdapter} */ + [_adapter]; + + /** @returns {string} */ get name() { - return this.#name; + webidl.assertBranded(this, GPUAdapter); + return this[_name]; } - #features; + /** @returns {GPUAdapterFeatures} */ get features() { - return this.#features; + webidl.assertBranded(this, GPUAdapter); + return this[_adapter].features; } - #limits; + /** @returns {GPUAdapterLimits} */ get limits() { - return this.#limits; + webidl.assertBranded(this, GPUAdapter); + return this[_adapter].limits; } - constructor(key, data) { - checkKey(key); - - this.#rid = data.rid; - this.#name = data.name; - this.#features = Object.freeze(data.features); - this.#limits = Object.freeze(data.limits); + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPUDeviceDescriptor} descriptor + * @returns {Promise} + */ async requestDevice(descriptor = {}) { - const { rid, ...data } = await core.jsonOpAsync( + webidl.assertBranded(this, GPUAdapter); + descriptor = webidl.converters.GPUDeviceDescriptor(descriptor, { + prefix: "Failed to execute 'requestDevice' on 'GPUAdapter'", + context: "Argument 1", + }); + + const { rid, features, limits } = await core.jsonOpAsync( "op_webgpu_request_device", { - adapterRid: this.#rid, + adapterRid: this[_adapter].rid, ...descriptor, }, ); - return new GPUDevice(keySymbol, this, rid, { - label: descriptor.label, - ...data, - }); + return createGPUDevice( + descriptor.label ?? null, + { + rid, + adapter: this, + features: Object.freeze(features), + limits: Object.freeze(limits), + queue: createGPUQueue(descriptor.label ?? null, rid), + }, + ); } } + const _label = Symbol("[[label]]"); + const _device = Symbol("[[device]]"); + + /** + * @typedef InnerGPUDevice + * @property {GPUAdapter} adapter + * @property {number} rid + * @property {GPUFeatureName[]} features + * @property {object} limits + * @property {GPUQueue} queue + */ + + /** + * @param {string | null} label + * @param {InnerGPUDevice} inner + * @returns {GPUDevice} + */ + function createGPUDevice(label, inner) { + /** @type {GPUDevice} */ + const device = webidl.createBranded(GPUDevice); + device[_label] = label; + device[_device] = inner; + return device; + } + + webidl.converters["UVString?"] = webidl.createNullableConverter( + webidl.converters.USVString, + ); + // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging - class GPUDevice extends EventTarget { - #rid; - #adapter; + class GPUDevice extends eventTarget.EventTarget { + // TODO(lucacasonato): why does tsc complain about incorrect types here? + /** @type {string | null} */ + [_label]; + + /** + * @return {string | null} + */ + get label() { + webidl.assertBranded(this, GPUDevice); + return this[_label]; + } + /** + * @param {string | null} label + */ + set label(label) { + webidl.assertBranded(this, GPUDevice); + label = webidl.converters["UVString?"](label, { + prefix: "Failed to set 'label' on 'GPUDevice'", + context: "Argument 1", + }); + this[_label] = label; + } + + /** @type {InnerGPUDevice} */ + [_device]; + get adapter() { - return this.#adapter; + webidl.assertBranded(this, GPUDevice); + return this[_device].adapter; } - #features; get features() { - return this.#features; + webidl.assertBranded(this, GPUDevice); + return this[_device].features; } - #limits; get limits() { - return this.#limits; + webidl.assertBranded(this, GPUDevice); + return this[_device].limits; } - #queue; get queue() { - return this.#queue; + webidl.assertBranded(this, GPUDevice); + return this[_device].queue; } - constructor(key, adapter, rid, data) { - checkKey(key); - + constructor() { + webidl.illegalConstructor(); super(); - - this.#adapter = adapter; - this.#rid = rid; - this.#features = Object.freeze(data.features); - this.#limits = data.limits; - this.#queue = new GPUQueue(keySymbol, rid, data.label); - this.label = data.label; } destroy() { throw new Error("Not yet implemented"); } + /** + * @param {GPUBufferDescriptor} descriptor + */ createBuffer(descriptor) { - descriptor = wgpuDicts.GPUBufferDescriptor(descriptor, { + webidl.assertBranded(this, GPUDevice); + descriptor = webidl.converters.GPUBufferDescriptor(descriptor, { prefix: "Failed to execute 'createBuffer' on 'GPUDevice'", context: "Argument 1", }); const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }); - return new GPUBuffer( keySymbol, rid, - this.#rid, + this[_device].rid, descriptor.label, descriptor.size, descriptor.mappedAtCreation, @@ -346,12 +268,12 @@ } createTexture(descriptor) { - descriptor = wgpuDicts.GPUTextureDescriptor(descriptor, { + descriptor = webidl.converters.GPUTextureDescriptor(descriptor, { prefix: "Failed to execute 'createTexture' on 'GPUDevice'", context: "Argument 1", }); const { rid } = core.jsonOpSync("op_webgpu_create_texture", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, size: normalizeGPUExtent3D(descriptor.size), }); @@ -361,7 +283,7 @@ createSampler(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }); @@ -382,7 +304,7 @@ } const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }); @@ -391,7 +313,7 @@ createPipelineLayout(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, label: descriptor.label, bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => bindGroupLayout[ridSymbol] @@ -403,7 +325,7 @@ createBindGroup(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, label: descriptor.label, layout: descriptor.layout[ridSymbol], entries: descriptor.entries.map((entry) => { @@ -438,7 +360,7 @@ const { rid } = core.jsonOpSync( "op_webgpu_create_shader_module", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, label: descriptor.label, code: (typeof descriptor.code === "string") ? descriptor.code @@ -453,7 +375,7 @@ createComputePipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, label: descriptor.label, layout: descriptor.layout ? descriptor.layout[ridSymbol] : undefined, compute: { @@ -487,7 +409,7 @@ }; const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...d, }); @@ -504,7 +426,7 @@ createCommandEncoder(descriptor = {}) { const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }); @@ -515,7 +437,7 @@ const { rid } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }, ); @@ -525,7 +447,7 @@ createQuerySet(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { - deviceRid: this.#rid, + deviceRid: this[_device].rid, ...descriptor, }); @@ -533,18 +455,65 @@ } } + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUQueue} + */ + function createGPUQueue(label, rid) { + /** @type {GPUQueue} */ + const queue = webidl.createBranded(GPUQueue); + queue[_label] = label; + queue[_device] = rid; + return queue; + } + class GPUQueue { - #rid; - constructor(key, rid, label) { - checkKey(key); + // TODO(lucacasonato): why does tsc complain about incorrect types here? + /** @type {string | null} */ + [_label]; + + /** + * @return {string | null} + */ + get label() { + webidl.assertBranded(this, GPUDevice); + return this[_label]; + } + /** + * @param {string | null} label + */ + set label(label) { + webidl.assertBranded(this, GPUDevice); + label = webidl.converters["UVString?"](label, { + prefix: "Failed to set 'label' on 'GPUQueue'", + context: "Argument 1", + }); + this[_label] = label; + } - this.#rid = rid; - this.label = label ?? null; + /** + * The rid of the related device. + * @type {number} + */ + [_device]; + + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPUCommandBuffer[]} commandBuffers + */ submit(commandBuffers) { + webidl.assertBranded(this, GPUQueue); + webidl.requiredArguments(arguments.length, 1, { + prefix: "Failed to execute 'submit' on 'GPUQueue'", + }); + // TODO(lucacasonato): should be real converter + commandBuffers = webidl.converters.any(commandBuffers); core.jsonOpSync("op_webgpu_queue_submit", { - queueRid: this.#rid, + queueRid: this[_device], commandBuffers: commandBuffers.map((buffer) => buffer[ridSymbol]), }); } @@ -552,11 +521,43 @@ async onSubmittedWorkDone() { } + /** + * @param {GPUBuffer} buffer + * @param {number} bufferOffset + * @param {BufferSource} data + * @param {number} [dataOffset] + * @param {number} [size] + */ writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { + webidl.assertBranded(this, GPUQueue); + const prefix = "Failed to execute 'writeBuffer' on 'GPUQueue'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + buffer = webidl.converters["GPUBuffer"](buffer, { + prefix, + context: "Argument 1", + }); + bufferOffset = webidl.converters["GPUSize64"](bufferOffset, { + prefix, + context: "Argument 2", + }); + data = webidl.converters.BufferSource(data, { + prefix, + context: "Argument 3", + }); + dataOffset = webidl.converters["GPUSize64"](dataOffset, { + prefix, + context: "Argument 4", + }); + size = size === undefined + ? undefined + : webidl.converters["GPUSize64"](size, { + prefix, + context: "Argument 5", + }); core.jsonOpSync( "op_webgpu_write_buffer", { - queueRid: this.#rid, + queueRid: this[_device], buffer: buffer[ridSymbol], bufferOffset, dataOffset, @@ -570,7 +571,7 @@ core.jsonOpSync( "op_webgpu_write_texture", { - queueRid: this.#rid, + queueRid: this[_device], destination: { texture: destination.texture[ridSymbol], mipLevel: destination.mipLevel, @@ -590,6 +591,8 @@ } class GPUBuffer { + [webidl.brand] = webidl.brand; + #deviceRid; #size; #mappedSize; @@ -652,6 +655,11 @@ } } + webidl.converters["GPUBuffer"] = webidl.createInterfaceConverter( + "GPUBuffer", + GPUBuffer, + ); + class GPUTexture { constructor(key, rid, label) { checkKey(key); diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index bc6596aee3acf7..b48c5576acef49 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -102,10 +102,16 @@ impl Resource for WebGPUQuerySet { /// Execute this crates' JS source files. pub fn init(isolate: &mut deno_core::JsRuntime) { - let files = vec![( - "deno:op_crates/webgpu/01_webgpu.js", - include_str!("01_webgpu.js"), - )]; + let files = vec![ + ( + "deno:op_crates/webgpu/01_idl_types.js", + include_str!("01_idl_types.js"), + ), + ( + "deno:op_crates/webgpu/02_webgpu.js", + include_str!("02_webgpu.js"), + ), + ]; for (url, source_code) in files { isolate.execute(url, source_code).unwrap(); } @@ -138,10 +144,14 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY) { return_features.push("sampled-texture-binding-array"); } - if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING) { + if features + .contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING) + { return_features.push("sampled-texture-array-dynamic-indexing"); } - if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) { + if features + .contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) + { return_features.push("sampled-texture-array-non-uniform-indexing"); } if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { @@ -168,7 +178,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { return_features.push("texture-compression-astc-ldr"); } - if features.contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) { + if features + .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) + { return_features.push("texture-adapter-specific-format-features"); } if features.contains(wgpu_types::Features::SHADER_FLOAT64) { @@ -322,11 +334,21 @@ pub async fn op_webgpu_request_device( if passed_features.contains(&"sampled-texture-binding-array".to_string()) { features.set(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY, true); } - if passed_features.contains(&"sampled-texture-array-dynamic-indexing".to_string()) { - features.set(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING, true); + if passed_features + .contains(&"sampled-texture-array-dynamic-indexing".to_string()) + { + features.set( + wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING, + true, + ); } - if passed_features.contains(&"sampled-texture-array-non-uniform-indexing".to_string()) { - features.set(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, true); + if passed_features + .contains(&"sampled-texture-array-non-uniform-indexing".to_string()) + { + features.set( + wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + true, + ); } if passed_features.contains(&"unsized-binding-array".to_string()) { features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true); @@ -352,8 +374,13 @@ pub async fn op_webgpu_request_device( if passed_features.contains(&"texture-compression-astc-ldr".to_string()) { features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true); } - if passed_features.contains(&"texture-adapter-specific-format-features".to_string()) { - features.set(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, true); + if passed_features + .contains(&"texture-adapter-specific-format-features".to_string()) + { + features.set( + wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, + true, + ); } if passed_features.contains(&"shader-float64".to_string()) { features.set(wgpu_types::Features::SHADER_FLOAT64, true); diff --git a/op_crates/webgpu/webgpu.idl b/op_crates/webgpu/webgpu.idl new file mode 100644 index 00000000000000..598df7efbe9e49 --- /dev/null +++ b/op_crates/webgpu/webgpu.idl @@ -0,0 +1,1023 @@ +interface mixin GPUObjectBase { + attribute USVString? label; +}; + +dictionary GPUObjectDescriptorBase { + USVString label; +}; + +interface GPUAdapterLimits { + readonly attribute GPUSize32 maxTextureDimension1D; + readonly attribute GPUSize32 maxTextureDimension2D; + readonly attribute GPUSize32 maxTextureDimension3D; + readonly attribute GPUSize32 maxTextureArrayLayers; + readonly attribute GPUSize32 maxBindGroups; + readonly attribute GPUSize32 maxDynamicUniformBuffersPerPipelineLayout; + readonly attribute GPUSize32 maxDynamicStorageBuffersPerPipelineLayout; + readonly attribute GPUSize32 maxSampledTexturesPerShaderStage; + readonly attribute GPUSize32 maxSamplersPerShaderStage; + readonly attribute GPUSize32 maxStorageBuffersPerShaderStage; + readonly attribute GPUSize32 maxStorageTexturesPerShaderStage; + readonly attribute GPUSize32 maxUniformBuffersPerShaderStage; + readonly attribute GPUSize32 maxUniformBufferBindingSize; + readonly attribute GPUSize32 maxStorageBufferBindingSize; + readonly attribute GPUSize32 maxVertexBuffers; + readonly attribute GPUSize32 maxVertexAttributes; + readonly attribute GPUSize32 maxVertexBufferArrayStride; +}; + +interface GPUAdapterFeatures { + readonly setlike; +}; + +[Exposed=Window] +partial interface Navigator { + [SameObject] readonly attribute GPU gpu; +}; + +[Exposed=DedicatedWorker] +partial interface WorkerNavigator { + [SameObject] readonly attribute GPU gpu; +}; + +[Exposed=(Window, DedicatedWorker)] +interface GPU { + Promise requestAdapter(optional GPURequestAdapterOptions options = {}); +}; + +dictionary GPURequestAdapterOptions { + GPUPowerPreference powerPreference; +}; + +enum GPUPowerPreference { + "low-power", + "high-performance" +}; + +interface GPUAdapter { + readonly attribute DOMString name; + [SameObject] readonly attribute GPUAdapterFeatures features; + [SameObject] readonly attribute GPUAdapterLimits limits; + + Promise requestDevice(optional GPUDeviceDescriptor descriptor = {}); +}; + +dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { + sequence nonGuaranteedFeatures = []; + record nonGuaranteedLimits = {}; +}; + +enum GPUFeatureName { + "depth-clamping", + "depth24unorm-stencil8", + "depth32float-stencil8", + "pipeline-statistics-query", + "texture-compression-bc", + "timestamp-query", +}; + +[Exposed=(Window, DedicatedWorker), Serializable] +interface GPUDevice : EventTarget { + [SameObject] readonly attribute GPUAdapter adapter; + readonly attribute FrozenArray features; + readonly attribute object limits; + + [SameObject] readonly attribute GPUQueue queue; + + undefined destroy(); + + GPUBuffer createBuffer(GPUBufferDescriptor descriptor); + GPUTexture createTexture(GPUTextureDescriptor descriptor); + GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); + + GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); + GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor); + GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); + + GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); + GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); + GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); + Promise createComputePipelineAsync(GPUComputePipelineDescriptor descriptor); + Promise createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor); + + GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); + GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); + + GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor); +}; +GPUDevice includes GPUObjectBase; + +[Serializable] +interface GPUBuffer { + Promise mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); + ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); + undefined unmap(); + + undefined destroy(); +}; +GPUBuffer includes GPUObjectBase; + +dictionary GPUBufferDescriptor : GPUObjectDescriptorBase { + required GPUSize64 size; + required GPUBufferUsageFlags usage; + boolean mappedAtCreation = false; +}; + +typedef [EnforceRange] unsigned long GPUBufferUsageFlags; +interface GPUBufferUsage { + const GPUFlagsConstant MAP_READ = 0x0001; + const GPUFlagsConstant MAP_WRITE = 0x0002; + const GPUFlagsConstant COPY_SRC = 0x0004; + const GPUFlagsConstant COPY_DST = 0x0008; + const GPUFlagsConstant INDEX = 0x0010; + const GPUFlagsConstant VERTEX = 0x0020; + const GPUFlagsConstant UNIFORM = 0x0040; + const GPUFlagsConstant STORAGE = 0x0080; + const GPUFlagsConstant INDIRECT = 0x0100; + const GPUFlagsConstant QUERY_RESOLVE = 0x0200; +}; + +typedef [EnforceRange] unsigned long GPUMapModeFlags; +interface GPUMapMode { + const GPUFlagsConstant READ = 0x0001; + const GPUFlagsConstant WRITE = 0x0002; +}; + +[Serializable] +interface GPUTexture { + GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); + + undefined destroy(); +}; +GPUTexture includes GPUObjectBase; + +dictionary GPUTextureDescriptor : GPUObjectDescriptorBase { + required GPUExtent3D size; + GPUIntegerCoordinate mipLevelCount = 1; + GPUSize32 sampleCount = 1; + GPUTextureDimension dimension = "2d"; + required GPUTextureFormat format; + required GPUTextureUsageFlags usage; +}; + +enum GPUTextureDimension { + "1d", + "2d", + "3d", +}; + +typedef [EnforceRange] unsigned long GPUTextureUsageFlags; +interface GPUTextureUsage { + const GPUFlagsConstant COPY_SRC = 0x01; + const GPUFlagsConstant COPY_DST = 0x02; + const GPUFlagsConstant SAMPLED = 0x04; + const GPUFlagsConstant STORAGE = 0x08; + const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; +}; + +interface GPUTextureView { +}; +GPUTextureView includes GPUObjectBase; + +dictionary GPUTextureViewDescriptor : GPUObjectDescriptorBase { + GPUTextureFormat format; + GPUTextureViewDimension dimension; + GPUTextureAspect aspect = "all"; + GPUIntegerCoordinate baseMipLevel = 0; + GPUIntegerCoordinate mipLevelCount; + GPUIntegerCoordinate baseArrayLayer = 0; + GPUIntegerCoordinate arrayLayerCount; +}; + +enum GPUTextureViewDimension { + "1d", + "2d", + "2d-array", + "cube", + "cube-array", + "3d" +}; + +enum GPUTextureAspect { + "all", + "stencil-only", + "depth-only" +}; + +enum GPUTextureFormat { + // 8-bit formats + "r8unorm", + "r8snorm", + "r8uint", + "r8sint", + + // 16-bit formats + "r16uint", + "r16sint", + "r16float", + "rg8unorm", + "rg8snorm", + "rg8uint", + "rg8sint", + + // 32-bit formats + "r32uint", + "r32sint", + "r32float", + "rg16uint", + "rg16sint", + "rg16float", + "rgba8unorm", + "rgba8unorm-srgb", + "rgba8snorm", + "rgba8uint", + "rgba8sint", + "bgra8unorm", + "bgra8unorm-srgb", + // Packed 32-bit formats + "rgb9e5ufloat", + "rgb10a2unorm", + "rg11b10ufloat", + + // 64-bit formats + "rg32uint", + "rg32sint", + "rg32float", + "rgba16uint", + "rgba16sint", + "rgba16float", + + // 128-bit formats + "rgba32uint", + "rgba32sint", + "rgba32float", + + // Depth and stencil formats + "stencil8", + "depth16unorm", + "depth24plus", + "depth24plus-stencil8", + "depth32float", + + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + "bc1-rgba-unorm", + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm", + "bc3-rgba-unorm-srgb", + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm", + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb", + + // "depth24unorm-stencil8" feature + "depth24unorm-stencil8", + + // "depth32float-stencil8" feature + "depth32float-stencil8", +}; + +interface GPUSampler { +}; +GPUSampler includes GPUObjectBase; + +dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase { + GPUAddressMode addressModeU = "clamp-to-edge"; + GPUAddressMode addressModeV = "clamp-to-edge"; + GPUAddressMode addressModeW = "clamp-to-edge"; + GPUFilterMode magFilter = "nearest"; + GPUFilterMode minFilter = "nearest"; + GPUFilterMode mipmapFilter = "nearest"; + float lodMinClamp = 0; + float lodMaxClamp = 0xffffffff; // TODO: What should this be? Was Number.MAX_VALUE. + GPUCompareFunction compare; + [Clamp] unsigned short maxAnisotropy = 1; +}; + +enum GPUAddressMode { + "clamp-to-edge", + "repeat", + "mirror-repeat" +}; + +enum GPUFilterMode { + "nearest", + "linear" +}; + +enum GPUCompareFunction { + "never", + "less", + "equal", + "less-equal", + "greater", + "not-equal", + "greater-equal", + "always" +}; + +[Serializable] +interface GPUBindGroupLayout { +}; +GPUBindGroupLayout includes GPUObjectBase; + +dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase { + required sequence entries; +}; + +typedef [EnforceRange] unsigned long GPUShaderStageFlags; +interface GPUShaderStage { + const GPUFlagsConstant VERTEX = 0x1; + const GPUFlagsConstant FRAGMENT = 0x2; + const GPUFlagsConstant COMPUTE = 0x4; +}; + +dictionary GPUBindGroupLayoutEntry { + required GPUIndex32 binding; + required GPUShaderStageFlags visibility; + + GPUBufferBindingLayout buffer; + GPUSamplerBindingLayout sampler; + GPUTextureBindingLayout texture; + GPUStorageTextureBindingLayout storageTexture; +}; + +enum GPUBufferBindingType { + "uniform", + "storage", + "read-only-storage", +}; + +dictionary GPUBufferBindingLayout { + GPUBufferBindingType type = "uniform"; + boolean hasDynamicOffset = false; + GPUSize64 minBindingSize = 0; +}; + +enum GPUSamplerBindingType { + "filtering", + "non-filtering", + "comparison", +}; + +dictionary GPUSamplerBindingLayout { + GPUSamplerBindingType type = "filtering"; +}; + +enum GPUTextureSampleType { + "float", + "unfilterable-float", + "depth", + "sint", + "uint", +}; + +dictionary GPUTextureBindingLayout { + GPUTextureSampleType sampleType = "float"; + GPUTextureViewDimension viewDimension = "2d"; + boolean multisampled = false; +}; + +enum GPUStorageTextureAccess { + "read-only", + "write-only", +}; + +dictionary GPUStorageTextureBindingLayout { + required GPUStorageTextureAccess access; + required GPUTextureFormat format; + GPUTextureViewDimension viewDimension = "2d"; +}; + +interface GPUBindGroup { +}; +GPUBindGroup includes GPUObjectBase; + +dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase { + required GPUBindGroupLayout layout; + required sequence entries; +}; + +typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource; + +dictionary GPUBindGroupEntry { + required GPUIndex32 binding; + required GPUBindingResource resource; +}; + +dictionary GPUBufferBinding { + required GPUBuffer buffer; + GPUSize64 offset = 0; + GPUSize64 size; +}; + +[Serializable] +interface GPUPipelineLayout { +}; +GPUPipelineLayout includes GPUObjectBase; + +dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase { + required sequence bindGroupLayouts; +}; + +enum GPUCompilationMessageType { + "error", + "warning", + "info" +}; + +[Serializable] +interface GPUCompilationMessage { + readonly attribute DOMString message; + readonly attribute GPUCompilationMessageType type; + readonly attribute unsigned long long lineNum; + readonly attribute unsigned long long linePos; +}; + +[Serializable] +interface GPUCompilationInfo { + readonly attribute FrozenArray messages; +}; + +[Serializable] +interface GPUShaderModule { + Promise compilationInfo(); +}; +GPUShaderModule includes GPUObjectBase; + +dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { + required USVString code; + object sourceMap; +}; + +dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase { + GPUPipelineLayout layout; +}; + +interface mixin GPUPipelineBase { + GPUBindGroupLayout getBindGroupLayout(unsigned long index); +}; + +dictionary GPUProgrammableStage { + required GPUShaderModule module; + required USVString entryPoint; +}; + +[Serializable] +interface GPUComputePipeline { +}; +GPUComputePipeline includes GPUObjectBase; +GPUComputePipeline includes GPUPipelineBase; + +dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase { + required GPUProgrammableStage compute; +}; + +[Serializable] +interface GPURenderPipeline { +}; +GPURenderPipeline includes GPUObjectBase; +GPURenderPipeline includes GPUPipelineBase; + +dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { + required GPUVertexState vertex; + GPUPrimitiveState primitive = {}; + GPUDepthStencilState depthStencil; + GPUMultisampleState multisample = {}; + GPUFragmentState fragment; +}; + +enum GPUPrimitiveTopology { + "point-list", + "line-list", + "line-strip", + "triangle-list", + "triangle-strip" +}; + +dictionary GPUPrimitiveState { + GPUPrimitiveTopology topology = "triangle-list"; + GPUIndexFormat stripIndexFormat; + GPUFrontFace frontFace = "ccw"; + GPUCullMode cullMode = "none"; +}; + +enum GPUFrontFace { + "ccw", + "cw" +}; + +enum GPUCullMode { + "none", + "front", + "back" +}; + +dictionary GPUMultisampleState { + GPUSize32 count = 1; + GPUSampleMask mask = 0xFFFFFFFF; + boolean alphaToCoverageEnabled = false; +}; + +dictionary GPUFragmentState: GPUProgrammableStage { + required sequence targets; +}; + +dictionary GPUColorTargetState { + required GPUTextureFormat format; + + GPUBlendState blend; + GPUColorWriteFlags writeMask = 0xF; // GPUColorWrite.ALL +}; + +dictionary GPUBlendState { + required GPUBlendComponent color; + required GPUBlendComponent alpha; +}; + +typedef [EnforceRange] unsigned long GPUColorWriteFlags; +interface GPUColorWrite { + const GPUFlagsConstant RED = 0x1; + const GPUFlagsConstant GREEN = 0x2; + const GPUFlagsConstant BLUE = 0x4; + const GPUFlagsConstant ALPHA = 0x8; + const GPUFlagsConstant ALL = 0xF; +}; + +dictionary GPUBlendComponent { + GPUBlendFactor srcFactor = "one"; + GPUBlendFactor dstFactor = "zero"; + GPUBlendOperation operation = "add"; +}; + +enum GPUBlendFactor { + "zero", + "one", + "src-color", + "one-minus-src-color", + "src-alpha", + "one-minus-src-alpha", + "dst-color", + "one-minus-dst-color", + "dst-alpha", + "one-minus-dst-alpha", + "src-alpha-saturated", + "blend-color", + "one-minus-blend-color" +}; + +enum GPUBlendOperation { + "add", + "subtract", + "reverse-subtract", + "min", + "max" +}; + +dictionary GPUDepthStencilState { + required GPUTextureFormat format; + + boolean depthWriteEnabled = false; + GPUCompareFunction depthCompare = "always"; + + GPUStencilFaceState stencilFront = {}; + GPUStencilFaceState stencilBack = {}; + + GPUStencilValue stencilReadMask = 0xFFFFFFFF; + GPUStencilValue stencilWriteMask = 0xFFFFFFFF; + + GPUDepthBias depthBias = 0; + float depthBiasSlopeScale = 0; + float depthBiasClamp = 0; + + // Enable depth clamping (requires "depth-clamping" feature) + boolean clampDepth = false; +}; + +dictionary GPUStencilFaceState { + GPUCompareFunction compare = "always"; + GPUStencilOperation failOp = "keep"; + GPUStencilOperation depthFailOp = "keep"; + GPUStencilOperation passOp = "keep"; +}; + +enum GPUStencilOperation { + "keep", + "zero", + "replace", + "invert", + "increment-clamp", + "decrement-clamp", + "increment-wrap", + "decrement-wrap" +}; + +enum GPUIndexFormat { + "uint16", + "uint32" +}; + +enum GPUVertexFormat { + "uchar2", + "uchar4", + "char2", + "char4", + "uchar2norm", + "uchar4norm", + "char2norm", + "char4norm", + "ushort2", + "ushort4", + "short2", + "short4", + "ushort2norm", + "ushort4norm", + "short2norm", + "short4norm", + "half2", + "half4", + "float", + "float2", + "float3", + "float4", + "uint", + "uint2", + "uint3", + "uint4", + "int", + "int2", + "int3", + "int4" +}; + +enum GPUInputStepMode { + "vertex", + "instance" +}; + +dictionary GPUVertexState: GPUProgrammableStage { + sequence buffers = []; +}; + +dictionary GPUVertexBufferLayout { + required GPUSize64 arrayStride; + GPUInputStepMode stepMode = "vertex"; + required sequence attributes; +}; + +dictionary GPUVertexAttribute { + required GPUVertexFormat format; + required GPUSize64 offset; + + required GPUIndex32 shaderLocation; +}; + +interface GPUCommandBuffer { + readonly attribute Promise executionTime; +}; +GPUCommandBuffer includes GPUObjectBase; + +dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase { +}; + +interface GPUCommandEncoder { + GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); + GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); + + undefined copyBufferToBuffer( + GPUBuffer source, + GPUSize64 sourceOffset, + GPUBuffer destination, + GPUSize64 destinationOffset, + GPUSize64 size); + + undefined copyBufferToTexture( + GPUImageCopyBuffer source, + GPUImageCopyTexture destination, + GPUExtent3D copySize); + + undefined copyTextureToBuffer( + GPUImageCopyTexture source, + GPUImageCopyBuffer destination, + GPUExtent3D copySize); + + undefined copyTextureToTexture( + GPUImageCopyTexture source, + GPUImageCopyTexture destination, + GPUExtent3D copySize); + + undefined pushDebugGroup(USVString groupLabel); + undefined popDebugGroup(); + undefined insertDebugMarker(USVString markerLabel); + + undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); + + undefined resolveQuerySet( + GPUQuerySet querySet, + GPUSize32 firstQuery, + GPUSize32 queryCount, + GPUBuffer destination, + GPUSize64 destinationOffset); + + GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {}); +}; +GPUCommandEncoder includes GPUObjectBase; + +dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase { + boolean measureExecutionTime = false; + + // TODO: reusability flag? +}; + +dictionary GPUImageDataLayout { + GPUSize64 offset = 0; + GPUSize32 bytesPerRow; + GPUSize32 rowsPerImage; +}; + +dictionary GPUImageCopyBuffer : GPUImageDataLayout { + required GPUBuffer buffer; +}; + +dictionary GPUImageCopyTexture { + required GPUTexture texture; + GPUIntegerCoordinate mipLevel = 0; + GPUOrigin3D origin = {}; + GPUTextureAspect aspect = "all"; +}; + +interface mixin GPUProgrammablePassEncoder { + undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup, + optional sequence dynamicOffsets = []); + + undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup, + Uint32Array dynamicOffsetsData, + GPUSize64 dynamicOffsetsDataStart, + GPUSize32 dynamicOffsetsDataLength); + + undefined pushDebugGroup(USVString groupLabel); + undefined popDebugGroup(); + undefined insertDebugMarker(USVString markerLabel); +}; + +interface GPUComputePassEncoder { + undefined setPipeline(GPUComputePipeline pipeline); + undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1); + undefined dispatchIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); + + undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); + undefined endPipelineStatisticsQuery(); + + undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); + + undefined endPass(); +}; +GPUComputePassEncoder includes GPUObjectBase; +GPUComputePassEncoder includes GPUProgrammablePassEncoder; + +dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase { +}; + +interface mixin GPURenderEncoderBase { + undefined setPipeline(GPURenderPipeline pipeline); + + undefined setIndexBuffer(GPUBuffer buffer, GPUIndexFormat indexFormat, optional GPUSize64 offset = 0, optional GPUSize64 size = 0); + undefined setVertexBuffer(GPUIndex32 slot, GPUBuffer buffer, optional GPUSize64 offset = 0, optional GPUSize64 size = 0); + + undefined draw(GPUSize32 vertexCount, optional GPUSize32 instanceCount = 1, + optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0); + undefined drawIndexed(GPUSize32 indexCount, optional GPUSize32 instanceCount = 1, + optional GPUSize32 firstIndex = 0, + optional GPUSignedOffset32 baseVertex = 0, + optional GPUSize32 firstInstance = 0); + + undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); + undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); +}; + +interface GPURenderPassEncoder { + undefined setViewport(float x, float y, + float width, float height, + float minDepth, float maxDepth); + + undefined setScissorRect(GPUIntegerCoordinate x, GPUIntegerCoordinate y, + GPUIntegerCoordinate width, GPUIntegerCoordinate height); + + undefined setBlendColor(GPUColor color); + undefined setStencilReference(GPUStencilValue reference); + + undefined beginOcclusionQuery(GPUSize32 queryIndex); + undefined endOcclusionQuery(); + + undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); + undefined endPipelineStatisticsQuery(); + + undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); + + undefined executeBundles(sequence bundles); + undefined endPass(); +}; +GPURenderPassEncoder includes GPUObjectBase; +GPURenderPassEncoder includes GPUProgrammablePassEncoder; +GPURenderPassEncoder includes GPURenderEncoderBase; + +dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase { + required sequence colorAttachments; + GPURenderPassDepthStencilAttachment depthStencilAttachment; + GPUQuerySet occlusionQuerySet; +}; + +dictionary GPURenderPassColorAttachment { + required GPUTextureView view; + GPUTextureView resolveTarget; + + required (GPULoadOp or GPUColor) loadValue; + GPUStoreOp storeOp = "store"; +}; + +dictionary GPURenderPassDepthStencilAttachment { + required GPUTextureView view; + + required (GPULoadOp or float) depthLoadValue; + required GPUStoreOp depthStoreOp; + boolean depthReadOnly = false; + + required (GPULoadOp or GPUStencilValue) stencilLoadValue; + required GPUStoreOp stencilStoreOp; + boolean stencilReadOnly = false; +}; + +enum GPULoadOp { + "load" +}; + +enum GPUStoreOp { + "store", + "clear" +}; + +interface GPURenderBundle { +}; +GPURenderBundle includes GPUObjectBase; + +dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase { +}; + +interface GPURenderBundleEncoder { + GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); +}; +GPURenderBundleEncoder includes GPUObjectBase; +GPURenderBundleEncoder includes GPUProgrammablePassEncoder; +GPURenderBundleEncoder includes GPURenderEncoderBase; + +dictionary GPURenderBundleEncoderDescriptor : GPUObjectDescriptorBase { + required sequence colorFormats; + GPUTextureFormat depthStencilFormat; + GPUSize32 sampleCount = 1; +}; + +interface GPUQueue { + undefined submit(sequence commandBuffers); + + Promise onSubmittedWorkDone(); + + undefined writeBuffer( + GPUBuffer buffer, + GPUSize64 bufferOffset, + [AllowShared] BufferSource data, + optional GPUSize64 dataOffset = 0, + optional GPUSize64 size); + + undefined writeTexture( + GPUImageCopyTexture destination, + [AllowShared] BufferSource data, + GPUImageDataLayout dataLayout, + GPUExtent3D size); +}; +GPUQueue includes GPUObjectBase; + +interface GPUQuerySet { + undefined destroy(); +}; +GPUQuerySet includes GPUObjectBase; + +dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase { + required GPUQueryType type; + required GPUSize32 count; + sequence pipelineStatistics = []; +}; + +enum GPUQueryType { + "occlusion", + "pipeline-statistics", + "timestamp" +}; + +enum GPUPipelineStatisticName { + "vertex-shader-invocations", + "clipper-invocations", + "clipper-primitives-out", + "fragment-shader-invocations", + "compute-shader-invocations" +}; + +enum GPUDeviceLostReason { + "destroyed", +}; + +interface GPUDeviceLostInfo { + readonly attribute (GPUDeviceLostReason or undefined) reason; + readonly attribute DOMString message; +}; + +partial interface GPUDevice { + readonly attribute Promise lost; +}; + +enum GPUErrorFilter { + "out-of-memory", + "validation" +}; + +interface GPUOutOfMemoryError { + constructor(); +}; + +interface GPUValidationError { + constructor(DOMString message); + readonly attribute DOMString message; +}; + +typedef (GPUOutOfMemoryError or GPUValidationError) GPUError; + +partial interface GPUDevice { + undefined pushErrorScope(GPUErrorFilter filter); + Promise popErrorScope(); +}; + +[ + Exposed=(Window, DedicatedWorker) +] +interface GPUUncapturedErrorEvent : Event { + constructor( + DOMString type, + GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict + ); + [SameObject] readonly attribute GPUError error; +}; + +dictionary GPUUncapturedErrorEventInit : EventInit { + required GPUError error; +}; + +partial interface GPUDevice { + [Exposed=(Window, DedicatedWorker)] + attribute EventHandler onuncapturederror; +}; + +typedef [EnforceRange] unsigned long GPUBufferDynamicOffset; +typedef [EnforceRange] unsigned long GPUStencilValue; +typedef [EnforceRange] unsigned long GPUSampleMask; +typedef [EnforceRange] long GPUDepthBias; + +typedef [EnforceRange] unsigned long long GPUSize64; +typedef [EnforceRange] unsigned long GPUIntegerCoordinate; +typedef [EnforceRange] unsigned long GPUIndex32; +typedef [EnforceRange] unsigned long GPUSize32; +typedef [EnforceRange] long GPUSignedOffset32; + +typedef unsigned long GPUFlagsConstant; + +dictionary GPUColorDict { + required double r; + required double g; + required double b; + required double a; +}; +typedef (sequence or GPUColorDict) GPUColor; + +dictionary GPUOrigin2DDict { + GPUIntegerCoordinate x = 0; + GPUIntegerCoordinate y = 0; +}; +typedef (sequence or GPUOrigin2DDict) GPUOrigin2D; + +dictionary GPUOrigin3DDict { + GPUIntegerCoordinate x = 0; + GPUIntegerCoordinate y = 0; + GPUIntegerCoordinate z = 0; +}; +typedef (sequence or GPUOrigin3DDict) GPUOrigin3D; + +dictionary GPUExtent3DDict { + GPUIntegerCoordinate width = 1; + GPUIntegerCoordinate height = 1; + GPUIntegerCoordinate depthOrArrayLayers = 1; +}; +typedef (sequence or GPUExtent3DDict) GPUExtent3D; From 5d1c4312cfcc5c487c09165ab169dc23fa8745f9 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 11:28:49 +0100 Subject: [PATCH 095/144] fix another free before use --- op_crates/webgpu/bundle.rs | 47 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index c974aa880810f4..a27d7c8fe1b46e 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -148,23 +148,36 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( .get::(args.render_bundle_encoder_rid) .ok_or_else(bad_resource_id)?; - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - match args.dynamic_offsets_data { - Some(data) => data.as_ptr(), - None => { - let (prefix, data, suffix) = zero_copy[0].align_to::(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data[args.dynamic_offsets_data_start..].as_ptr() - } - }, - args.dynamic_offsets_data_length, - ); - } + // I know this might look like it can be easily deduplicated, but it can not + // be due to the lifetime of the args.dynamic_offsets_data slice. Because we + // need to use a raw pointer here the slice can be freed before the pointer + // is used in wgpu_render_pass_set_bind_group. See + // https://matrix.to/#/!XFRnMvAfptAHthwBCx:matrix.org/$HgrlhD-Me1DwsGb8UdMu2Hqubgks8s7ILwWRwigOUAg + match args.dynamic_offsets_data { + Some(data) => unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + &mut render_bundle_encoder_resource.0.borrow_mut(), + args.index, + bind_group_resource.0, + data.as_slice().as_ptr(), + args.dynamic_offsets_data_length, + ); + }, + None => { + let (prefix, data, suffix) = unsafe { zero_copy[0].align_to::() }; + assert!(prefix.is_empty()); + assert!(suffix.is_empty()); + unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + &mut render_bundle_encoder_resource.0.borrow_mut(), + args.index, + bind_group_resource.0, + data[args.dynamic_offsets_data_start..].as_ptr(), + args.dynamic_offsets_data_length, + ); + } + } + }; Ok(json!({})) } From 0262c81fff1e281c8cc64a8fba93392dc547f633 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 11:32:04 +0100 Subject: [PATCH 096/144] fmt --- op_crates/web/internal.d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 32abc79a5a919e..88e027cdae38eb 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -158,7 +158,7 @@ declare namespace globalThis { */ Uint8ClampedArray( v: any, - opts?: BufferConverterOpts + opts?: BufferConverterOpts, ): Uint8ClampedArray; /** * Convert a value into a `Float32Array` (Float32Array). @@ -177,7 +177,7 @@ declare namespace globalThis { */ BufferSource( v: any, - opts?: BufferConverterOpts + opts?: BufferConverterOpts, ): ArrayBuffer | ArrayBufferView; /** * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long @@ -201,7 +201,7 @@ declare namespace globalThis { declare function requiredArguments( length: number, required: number, - opts: ConverterOpts + opts: ConverterOpts, ): void; declare type Dictionary = DictionaryMember[]; declare interface DictionaryMember { @@ -224,14 +224,14 @@ declare namespace globalThis { */ declare function createEnumConverter( name: string, - values: string[] + values: string[], ): (v: any, opts: ValueConverterOpts) => string; /** * Create a converter that makes the contained type nullable. */ declare function createNullableConverter( - converter: (v: any, opts: ValueConverterOpts) => T + converter: (v: any, opts: ValueConverterOpts) => T, ): (v: any, opts: ValueConverterOpts) => T | null; /** @@ -259,7 +259,7 @@ declare namespace globalThis { */ declare function createInterfaceConverter( name: string, - prototype: any + prototype: any, ): (v: any, opts: ValueConverterOpts) => any; } From 9aa59ac3b5ac1f8aa74d221e614fc41da690e5a7 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 17 Feb 2021 15:50:03 +0100 Subject: [PATCH 097/144] fix env var --- op_crates/webgpu/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index dc4300d2718ffa..e419d401ff3fc6 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -428,7 +428,7 @@ pub async fn op_webgpu_request_device( let device = gfx_select_err!(adapter => instance.adapter_request_device( adapter, &descriptor, - option_env!("DENO_WEBGPU_TRACE").map(std::path::Path::new), + std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), std::marker::PhantomData ))?; From acf458a1212338b2fae42b898d9dae0fff2363f1 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 16:23:55 +0100 Subject: [PATCH 098/144] More IDL --- .../webgpu/{02_webgpu.js => 01_webgpu.js} | 602 ++++++++++++++---- .../{01_idl_types.js => 02_idl_types.js} | 228 ++++++- op_crates/webgpu/lib.rs | 8 +- runtime/js/99_main.js | 47 +- 4 files changed, 740 insertions(+), 145 deletions(-) rename op_crates/webgpu/{02_webgpu.js => 01_webgpu.js} (70%) rename op_crates/webgpu/{01_idl_types.js => 02_idl_types.js} (86%) diff --git a/op_crates/webgpu/02_webgpu.js b/op_crates/webgpu/01_webgpu.js similarity index 70% rename from op_crates/webgpu/02_webgpu.js rename to op_crates/webgpu/01_webgpu.js index fd36f8028a2b50..bed563e1b2c680 100644 --- a/op_crates/webgpu/02_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -58,8 +58,18 @@ } } - const gpu = { + class GPU { + [webidl.brand] = webidl.brand; + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPURequestAdapterOptions} options + */ async requestAdapter(options = {}) { + webidl.assertBranded(this, GPU); options = webidl.converters.GPURequestAdapterOptions(options, { prefix: "Failed to execute 'requestAdapter' on 'GPU'", context: "Argument 1", @@ -77,8 +87,8 @@ } else { return createGPUAdapter(data.name, data); } - }, - }; + } + } const _name = Symbol("[[name]]"); const _adapter = Symbol("[[adapter]]"); @@ -162,6 +172,36 @@ } const _label = Symbol("[[label]]"); + + /** + * @param {string} name + * @param {any} type + */ + function GPUObjectBaseMixin(name, type) { + let mixin = { + /** + * @return {string | null} + */ + get() { + webidl.assertBranded(this, type); + return this[_label]; + }, + /** + * @param {string | null} label + */ + set(label) { + webidl.assertBranded(this, type); + label = webidl.converters["UVString?"](label, { + prefix: `Failed to set 'label' on '${name}'`, + context: "Argument 1", + }); + this[_label] = label; + }, + }; + type.prototype[_label] = null; + Object.defineProperty(type.prototype, "label", mixin); + } + const _device = Symbol("[[device]]"); /** @@ -192,29 +232,6 @@ // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging class GPUDevice extends eventTarget.EventTarget { - // TODO(lucacasonato): why does tsc complain about incorrect types here? - /** @type {string | null} */ - [_label]; - - /** - * @return {string | null} - */ - get label() { - webidl.assertBranded(this, GPUDevice); - return this[_label]; - } - /** - * @param {string | null} label - */ - set label(label) { - webidl.assertBranded(this, GPUDevice); - label = webidl.converters["UVString?"](label, { - prefix: "Failed to set 'label' on 'GPUDevice'", - context: "Argument 1", - }); - this[_label] = label; - } - /** @type {InnerGPUDevice} */ [_device]; @@ -442,7 +459,7 @@ }, ); - return new GPURenderBundleEncoder(keySymbol, rid, descriptor.label); + return createGPURenderBundleEncoder(descriptor.label ?? null, rid); } createQuerySet(descriptor) { @@ -451,9 +468,10 @@ ...descriptor, }); - return new GPUQuerySet(keySymbol, rid, descriptor.label); + return createGPUQuerySet(descriptor.label ?? null, rid); } } + GPUObjectBaseMixin("GPUDevice", GPUDevice); /** * @param {string | null} label @@ -469,29 +487,6 @@ } class GPUQueue { - // TODO(lucacasonato): why does tsc complain about incorrect types here? - /** @type {string | null} */ - [_label]; - - /** - * @return {string | null} - */ - get label() { - webidl.assertBranded(this, GPUDevice); - return this[_label]; - } - /** - * @param {string | null} label - */ - set label(label) { - webidl.assertBranded(this, GPUDevice); - label = webidl.converters["UVString?"](label, { - prefix: "Failed to set 'label' on 'GPUQueue'", - context: "Argument 1", - }); - this[_label] = label; - } - /** * The rid of the related device. * @type {number} @@ -519,6 +514,7 @@ } async onSubmittedWorkDone() { + webidl.assertBranded(this, GPUQueue); } /** @@ -563,11 +559,37 @@ dataOffset, size, }, - data, + new Uint8Array(ArrayBuffer.isView(data) ? data.buffer : data), ); } + /** + * @param {GPUImageCopyTexture} destination + * @param {BufferSource} data + * @param {GPUImageDataLayout} dataLayout + * @param {GPUExtent3D} size + */ writeTexture(destination, data, dataLayout, size) { + webidl.assertBranded(this, GPUQueue); + const prefix = "Failed to execute 'writeTexture' on 'GPUQueue'"; + webidl.requiredArguments(arguments.length, 4, { prefix }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 1", + }); + data = webidl.converters.BufferSource(data, { + prefix, + context: "Argument 2", + }); + dataLayout = webidl.converters.GPUImageDataLayout(dataLayout, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUExtent3D(size, { + prefix, + context: "Argument 4", + }); + core.jsonOpSync( "op_webgpu_write_texture", { @@ -581,7 +603,7 @@ dataLayout, size: normalizeGPUExtent3D(size), }, - data, + new Uint8Array(ArrayBuffer.isView(data) ? data.buffer : data), ); } @@ -589,6 +611,9 @@ throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPUQueue", GPUQueue); + + const _rid = Symbol("[[rid]]"); class GPUBuffer { [webidl.brand] = webidl.brand; @@ -654,12 +679,6 @@ throw new Error("Not yet implemented"); } } - - webidl.converters["GPUBuffer"] = webidl.createInterfaceConverter( - "GPUBuffer", - GPUBuffer, - ); - class GPUTexture { constructor(key, rid, label) { checkKey(key); @@ -741,6 +760,8 @@ } class GPUComputePipeline { + [webidl.brand] = webidl.brand; + constructor(key, rid, label) { checkKey(key); @@ -762,6 +783,8 @@ } class GPURenderPipeline { + [webidl.brand] = webidl.brand; + constructor(key, rid, label) { checkKey(key); @@ -872,11 +895,10 @@ }, ); - return new GPUComputePassEncoder( - keySymbol, + return createGPUComputePassEncoder( + descriptor.label ?? null, this.#rid, rid, - descriptor.label, ); } @@ -1009,7 +1031,7 @@ ...descriptor, }); - return new GPUCommandBuffer(keySymbol, rid, descriptor.label); + return createGPUCommandBuffer(descriptor.label ?? null, rid); } } @@ -1220,71 +1242,163 @@ } } + const _encoder = Symbol("[[encoder]]"); + + /** + * @param {string | null} label + * @param {number} encoderRid + * @param {number} rid + * @returns {GPUComputePassEncoder} + */ + function createGPUComputePassEncoder(label, encoderRid, rid) { + /** @type {GPUComputePassEncoder} */ + const commandBuffer = webidl.createBranded(GPUComputePassEncoder); + commandBuffer[_label] = label; + commandBuffer[_encoder] = encoderRid; + commandBuffer[_rid] = rid; + return commandBuffer; + } + class GPUComputePassEncoder { - #commandEncoderRid; - #rid; + /** @type {number} */ + [_encoder]; - constructor(key, commandEncoderRid, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this.#commandEncoderRid = commandEncoderRid; - this.#rid = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPUComputePipeline} pipeline + */ setPipeline(pipeline) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPUComputePipeline(pipeline, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { - computePassRid: this.#rid, + computePassRid: this[_rid], pipeline: pipeline[ridSymbol], }); } + + /** + * @param {number} x + * @param {number} y + * @param {number} z + */ dispatch(x, y = 1, z = 1) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); + y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); + z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); core.jsonOpSync("op_webgpu_compute_pass_dispatch", { - computePassRid: this.#rid, + computePassRid: this[_rid], x, y, z, }); } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ dispatchIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { - computePassRid: this.#rid, + computePassRid: this[_rid], indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ beginPipelineStatisticsQuery(querySet, queryIndex) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); core.jsonOpSync( "op_webgpu_compute_pass_begin_pipeline_statistics_query", { - computePassRid: this.#rid, - querySet: querySet[ridSymbol], + computePassRid: this[_rid], + querySet: querySet[_rid], queryIndex, }, ); } + endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { - computePassRid: this.#rid, + computePassRid: this[_rid], }); } + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { - computePassRid: this.#rid, - querySet: querySet[ridSymbol], + computePassRid: this[_rid], + querySet: querySet[_rid], queryIndex, }); } endPass() { + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pass", { - commandEncoderRid: this.#commandEncoderRid, - computePassRid: this.#rid, + commandEncoderRid: this[_encoder], + computePassRid: this[_rid], }); } + // TODO(lucacasonato): has an overload setBindGroup( index, bindGroup, @@ -1297,7 +1411,7 @@ core.jsonOpSync( "op_webgpu_compute_pass_set_bind_group", { - computePassRid: this.#rid, + computePassRid: this[_rid], index, bindGroup: bind, dynamicOffsetsDataStart, @@ -1308,7 +1422,7 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_compute_pass_set_bind_group", { - computePassRid: this.#rid, + computePassRid: this[_rid], index, bindGroup: bind, dynamicOffsetsData, @@ -1318,59 +1432,119 @@ } } + /** + * @param {string} groupLabel + */ pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.GPURenderBundleDescriptor(groupLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_compute_pass_push_debug_group", { - computePassRid: this.#rid, + computePassRid: this[_rid], groupLabel, }); } + popDebugGroup() { core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { - computePassRid: this.#rid, + computePassRid: this[_rid], }); } + + /** + * @param {string} markerLabel + */ insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.GPURenderBundleDescriptor(markerLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_compute_pass_insert_debug_marker", { - computePassRid: this.#rid, + computePassRid: this[_rid], markerLabel, }); } } + GPUObjectBaseMixin("GPUComputePassEncoder", GPUComputePassEncoder); + + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUCommandBuffer} + */ + function createGPUCommandBuffer(label, rid) { + /** @type {GPUCommandBuffer} */ + const commandBuffer = webidl.createBranded(GPUCommandBuffer); + commandBuffer[_label] = label; + commandBuffer[_rid] = rid; + return commandBuffer; + } class GPUCommandBuffer { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } get executionTime() { throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPUCommandBuffer", GPUCommandBuffer); + + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPURenderBundleEncoder} + */ + function createGPURenderBundleEncoder(label, rid) { + /** @type {GPURenderBundleEncoder} */ + const bundle = webidl.createBranded(GPURenderBundleEncoder); + bundle[_label] = label; + bundle[_rid] = rid; + return bundle; + } class GPURenderBundleEncoder { - #rid; - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this.#rid = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPURenderBundleDescriptor} descriptor + */ finish(descriptor = {}) { + webidl.assertBranded(this, GPURenderBundleEncoder); + descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { + prefix: "Failed to execute 'finish' on 'GPURenderBundleEncoder'", + context: "Argument 1", + }); const { rid } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], ...descriptor, }, ); - return new GPURenderBundle(keySymbol, rid, descriptor.label); + return createGPURenderBundle(descriptor.label ?? null, rid); } + // TODO(lucacasonato): has an overload setBindGroup( index, bindGroup, @@ -1383,7 +1557,7 @@ core.jsonOpSync( "op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], index, bindGroup: bind, dynamicOffsetsDataStart, @@ -1394,7 +1568,7 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], index, bindGroup: bind, dynamicOffsetsData, @@ -1404,43 +1578,132 @@ } } + /** + * @param {string} groupLabel + */ pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.GPURenderBundleDescriptor(groupLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], groupLabel, }); } + popDebugGroup() { + webidl.assertBranded(this, GPURenderBundleEncoder); core.jsonOpSync("op_webgpu_render_bundle_encoder_pop_debug_group", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], }); } + + /** + * @param {string} markerLabel + */ insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.GPURenderBundleDescriptor(markerLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], markerLabel, }); } + /** + * @param {GPURenderPipeline} pipeline + */ setPipeline(pipeline) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPURenderPipeline(pipeline, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], pipeline: pipeline[ridSymbol], }); } + /** + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size + */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 1", + }); + indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], buffer: buffer[ridSymbol], indexFormat, offset, size, }); } + + /** + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size + */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + slot = webidl.converters.GPUSize32(slot, { + prefix, + context: "Argument 2", + }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], slot, buffer: buffer[ridSymbol], offset, @@ -1448,15 +1711,48 @@ }); } + /** + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance + */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + vertexCount = webidl.converters.GPUSize32(vertexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstVertex = webidl.converters.GPUSize32(firstVertex, { + prefix, + context: "Argument 3", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], vertexCount, instanceCount, firstVertex, firstInstance, }); } + + /** + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance + */ drawIndexed( indexCount, instanceCount = 1, @@ -1464,8 +1760,32 @@ baseVertex = 0, firstInstance = 0, ) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indexCount = webidl.converters.GPUSize32(indexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstIndex = webidl.converters.GPUSize32(firstIndex, { + prefix, + context: "Argument 3", + }); + baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { + prefix, + context: "Argument 4", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 5", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indexed", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], indexCount, instanceCount, firstIndex, @@ -1474,42 +1794,90 @@ }); } + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ drawIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { - renderBundleEncoderRid: this.#rid, + renderBundleEncoderRid: this[_rid], indirectBuffer: indirectBuffer[ridSymbol], indirectOffset, }); } + drawIndexedIndirect(_indirectBuffer, _indirectOffset) { throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder); + + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPURenderBundle} + */ + function createGPURenderBundle(label, rid) { + /** @type {GPURenderBundle} */ + const bundle = webidl.createBranded(GPURenderBundle); + bundle[_label] = label; + bundle[_rid] = rid; + return bundle; + } class GPURenderBundle { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); + + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUQuerySet} + */ + function createGPUQuerySet(label, rid) { + /** @type {GPUQuerySet} */ + const queue = webidl.createBranded(GPUQuerySet); + queue[_label] = label; + queue[_rid] = rid; + return queue; + } class GPUQuerySet { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } destroy() { + webidl.assertBranded(this, GPUQuerySet); throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); - window.__bootstrap.webGPU = { - gpu, + window.__bootstrap.webgpu = { + gpu: webidl.createBranded(GPU), + GPU, GPUAdapter, GPUDevice, GPUQueue, diff --git a/op_crates/webgpu/01_idl_types.js b/op_crates/webgpu/02_idl_types.js similarity index 86% rename from op_crates/webgpu/01_idl_types.js rename to op_crates/webgpu/02_idl_types.js index 9825a8d03543d6..4e8559d01221ae 100644 --- a/op_crates/webgpu/01_idl_types.js +++ b/op_crates/webgpu/02_idl_types.js @@ -7,6 +7,32 @@ ((window) => { const webidl = window.__bootstrap.webidl; + const { + GPU, + GPUAdapter, + GPUDevice, + GPUQueue, + GPUBuffer, + GPUTexture, + GPUTextureView, + GPUSampler, + GPUBindGroupLayout, + GPUPipelineLayout, + GPUBindGroup, + GPUShaderModule, + GPUComputePipeline, + GPURenderPipeline, + GPUCommandEncoder, + GPURenderPassEncoder, + GPUComputePassEncoder, + GPUCommandBuffer, + GPURenderBundleEncoder, + GPURenderBundle, + GPUQuerySet, + } = window.__bootstrap.webgpu; + + // This needs to be initalized after all of the base classes are implmented, + // otherwise their converters might not be available yet. // DICTIONARY: GPUObjectDescriptorBase const dictMembersGPUObjectDescriptorBase = [ @@ -18,6 +44,21 @@ dictMembersGPUObjectDescriptorBase, ); + // // INTERFACE: GPUAdapterLimits + // webidl.converters.GPUAdapterLimits = webidl.createInterfaceConverter( + // "GPUAdapterLimits", + // GPUAdapterLimits, + // ); + + // // INTERFACE: GPUAdapterFeatures + // webidl.converters.GPUAdapterFeatures = webidl.createInterfaceConverter( + // "GPUAdapterFeatures", + // GPUAdapterFeatures, + // ); + + // INTERFACE: GPU + webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU); + // ENUM: GPUPowerPreference webidl.converters["GPUPowerPreference"] = webidl.createEnumConverter( "GPUPowerPreference", @@ -40,6 +81,12 @@ dictMembersGPURequestAdapterOptions, ); + // INTERFACE: GPUAdapter + webidl.converters.GPUAdapter = webidl.createInterfaceConverter( + "GPUAdapter", + GPUAdapter, + ); + // DICTIONARY: GPUDeviceDescriptor const dictMembersGPUDeviceDescriptor = [ { key: "nonGuaranteedFeatures", converter: webidl.converters.any }, @@ -64,6 +111,18 @@ ], ); + // INTERFACE: GPUDevice + webidl.converters.GPUDevice = webidl.createInterfaceConverter( + "GPUDevice", + GPUDevice, + ); + + // INTERFACE: GPUBuffer + webidl.converters.GPUBuffer = webidl.createInterfaceConverter( + "GPUBuffer", + GPUBuffer, + ); + // TYPEDEF: GPUSize64 webidl.converters["GPUSize64"] = (V, opts) => webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true }); @@ -88,10 +147,28 @@ dictMembersGPUBufferDescriptor, ); + // // INTERFACE: GPUBufferUsage + // webidl.converters.GPUBufferUsage = webidl.createInterfaceConverter( + // "GPUBufferUsage", + // GPUBufferUsage, + // ); + // TYPEDEF: GPUMapModeFlags webidl.converters["GPUMapModeFlags"] = (V, opts) => webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + // // INTERFACE: GPUMapMode + // webidl.converters.GPUMapMode = webidl.createInterfaceConverter( + // "GPUMapMode", + // GPUMapMode, + // ); + + // INTERFACE: GPUTexture + webidl.converters.GPUTexture = webidl.createInterfaceConverter( + "GPUTexture", + GPUTexture, + ); + // TYPEDEF: GPUExtent3D webidl.converters["GPUExtent3D"] = webidl.converters.any; @@ -211,6 +288,18 @@ dictMembersGPUTextureDescriptor, ); + // // INTERFACE: GPUTextureUsage + // webidl.converters.GPUTextureUsage = webidl.createInterfaceConverter( + // "GPUTextureUsage", + // GPUTextureUsage, + // ); + + // INTERFACE: GPUTextureView + webidl.converters.GPUTextureView = webidl.createInterfaceConverter( + "GPUTextureView", + GPUTextureView, + ); + // ENUM: GPUTextureViewDimension webidl.converters["GPUTextureViewDimension"] = webidl.createEnumConverter( "GPUTextureViewDimension", @@ -266,6 +355,12 @@ dictMembersGPUTextureViewDescriptor, ); + // INTERFACE: GPUSampler + webidl.converters.GPUSampler = webidl.createInterfaceConverter( + "GPUSampler", + GPUSampler, + ); + // ENUM: GPUAddressMode webidl.converters["GPUAddressMode"] = webidl.createEnumConverter( "GPUAddressMode", @@ -323,6 +418,12 @@ dictMembersGPUSamplerDescriptor, ); + // INTERFACE: GPUBindGroupLayout + webidl.converters.GPUBindGroupLayout = webidl.createInterfaceConverter( + "GPUBindGroupLayout", + GPUBindGroupLayout, + ); + // DICTIONARY: GPUBindGroupLayoutDescriptor const dictMembersGPUBindGroupLayoutDescriptor = [ { key: "entries", converter: webidl.converters.any, required: true }, @@ -338,6 +439,12 @@ webidl.converters["GPUShaderStageFlags"] = (V, opts) => webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + // // INTERFACE: GPUShaderStage + // webidl.converters.GPUShaderStage = webidl.createInterfaceConverter( + // "GPUShaderStage", + // GPUShaderStage, + // ); + // TYPEDEF: GPUIndex32 webidl.converters["GPUIndex32"] = (V, opts) => webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); @@ -469,6 +576,12 @@ dictMembersGPUBindGroupLayoutEntry, ); + // INTERFACE: GPUBindGroup + webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( + "GPUBindGroup", + GPUBindGroup, + ); + // DICTIONARY: GPUBindGroupDescriptor const dictMembersGPUBindGroupDescriptor = [ { @@ -521,6 +634,12 @@ dictMembersGPUBufferBinding, ); + // INTERFACE: GPUPipelineLayout + webidl.converters.GPUPipelineLayout = webidl.createInterfaceConverter( + "GPUPipelineLayout", + GPUPipelineLayout, + ); + // DICTIONARY: GPUPipelineLayoutDescriptor const dictMembersGPUPipelineLayoutDescriptor = [ { @@ -546,6 +665,24 @@ ], ); + // // INTERFACE: GPUCompilationMessage + // webidl.converters.GPUCompilationMessage = webidl.createInterfaceConverter( + // "GPUCompilationMessage", + // GPUCompilationMessage, + // ); + + // // INTERFACE: GPUCompilationInfo + // webidl.converters.GPUCompilationInfo = webidl.createInterfaceConverter( + // "GPUCompilationInfo", + // GPUCompilationInfo, + // ); + + // INTERFACE: GPUShaderModule + webidl.converters.GPUShaderModule = webidl.createInterfaceConverter( + "GPUShaderModule", + GPUShaderModule, + ); + // DICTIONARY: GPUShaderModuleDescriptor const dictMembersGPUShaderModuleDescriptor = [ { key: "code", converter: webidl.converters["USVString"], required: true }, @@ -587,6 +724,12 @@ dictMembersGPUProgrammableStage, ); + // INTERFACE: GPUComputePipeline + webidl.converters.GPUComputePipeline = webidl.createInterfaceConverter( + "GPUComputePipeline", + GPUComputePipeline, + ); + // DICTIONARY: GPUComputePipelineDescriptor const dictMembersGPUComputePipelineDescriptor = [ { @@ -602,6 +745,12 @@ dictMembersGPUComputePipelineDescriptor, ); + // INTERFACE: GPURenderPipeline + webidl.converters.GPURenderPipeline = webidl.createInterfaceConverter( + "GPURenderPipeline", + GPURenderPipeline, + ); + // DICTIONARY: GPUVertexState const dictMembersGPUVertexState = [ { key: "buffers", converter: webidl.converters.any }, @@ -852,6 +1001,12 @@ dictMembersGPUColorTargetState, ); + // // INTERFACE: GPUColorWrite + // webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( + // "GPUColorWrite", + // GPUColorWrite, + // ); + // ENUM: GPUVertexFormat webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( "GPUVertexFormat", @@ -936,6 +1091,12 @@ dictMembersGPUVertexAttribute, ); + // INTERFACE: GPUCommandBuffer + webidl.converters.GPUCommandBuffer = webidl.createInterfaceConverter( + "GPUCommandBuffer", + GPUCommandBuffer, + ); + // DICTIONARY: GPUCommandBufferDescriptor const dictMembersGPUCommandBufferDescriptor = []; webidl.converters["GPUCommandBufferDescriptor"] = webidl @@ -945,6 +1106,12 @@ dictMembersGPUCommandBufferDescriptor, ); + // INTERFACE: GPUCommandEncoder + webidl.converters.GPUCommandEncoder = webidl.createInterfaceConverter( + "GPUCommandEncoder", + GPUCommandEncoder, + ); + // DICTIONARY: GPUCommandEncoderDescriptor const dictMembersGPUCommandEncoderDescriptor = [ { key: "measureExecutionTime", converter: webidl.converters["boolean"] }, @@ -1000,6 +1167,12 @@ dictMembersGPUImageCopyTexture, ); + // INTERFACE: GPUComputePassEncoder + webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter( + "GPUComputePassEncoder", + GPUComputePassEncoder, + ); + // DICTIONARY: GPUComputePassDescriptor const dictMembersGPUComputePassDescriptor = []; webidl.converters["GPUComputePassDescriptor"] = webidl @@ -1009,6 +1182,12 @@ dictMembersGPUComputePassDescriptor, ); + // INTERFACE: GPURenderPassEncoder + webidl.converters.GPURenderPassEncoder = webidl.createInterfaceConverter( + "GPURenderPassEncoder", + GPURenderPassEncoder, + ); + // ENUM: GPUStoreOp webidl.converters["GPUStoreOp"] = webidl.createEnumConverter("GPUStoreOp", [ "store", @@ -1047,6 +1226,12 @@ dictMembersGPURenderPassDepthStencilAttachment, ); + // INTERFACE: GPUQuerySet + webidl.converters.GPUQuerySet = webidl.createInterfaceConverter( + "GPUQuerySet", + GPUQuerySet, + ); + // DICTIONARY: GPURenderPassDescriptor const dictMembersGPURenderPassDescriptor = [ { @@ -1089,6 +1274,12 @@ "load", ]); + // INTERFACE: GPURenderBundle + webidl.converters.GPURenderBundle = webidl.createInterfaceConverter( + "GPURenderBundle", + GPURenderBundle, + ); + // DICTIONARY: GPURenderBundleDescriptor const dictMembersGPURenderBundleDescriptor = []; webidl.converters["GPURenderBundleDescriptor"] = webidl @@ -1098,6 +1289,12 @@ dictMembersGPURenderBundleDescriptor, ); + // INTERFACE: GPURenderBundleEncoder + webidl.converters.GPURenderBundleEncoder = webidl.createInterfaceConverter( + "GPURenderBundleEncoder", + GPURenderBundleEncoder, + ); + // DICTIONARY: GPURenderBundleEncoderDescriptor const dictMembersGPURenderBundleEncoderDescriptor = [ { key: "colorFormats", converter: webidl.converters.any, required: true }, @@ -1114,6 +1311,12 @@ dictMembersGPURenderBundleEncoderDescriptor, ); + // INTERFACE: GPUQueue + webidl.converters.GPUQueue = webidl.createInterfaceConverter( + "GPUQueue", + GPUQueue, + ); + // ENUM: GPUQueryType webidl.converters["GPUQueryType"] = webidl.createEnumConverter( "GPUQueryType", @@ -1160,6 +1363,12 @@ ], ); + // // INTERFACE: GPUDeviceLostInfo + // webidl.converters.GPUDeviceLostInfo = webidl.createInterfaceConverter( + // "GPUDeviceLostInfo", + // GPUDeviceLostInfo, + // ); + // ENUM: GPUErrorFilter webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter( "GPUErrorFilter", @@ -1169,9 +1378,27 @@ ], ); + // // INTERFACE: GPUOutOfMemoryError + // webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( + // "GPUOutOfMemoryError", + // GPUOutOfMemoryError, + // ); + + // // INTERFACE: GPUValidationError + // webidl.converters.GPUValidationError = webidl.createInterfaceConverter( + // "GPUValidationError", + // GPUValidationError, + // ); + // TYPEDEF: GPUError webidl.converters["GPUError"] = webidl.converters.any; + // // INTERFACE: GPUUncapturedErrorEvent + // webidl.converters.GPUUncapturedErrorEvent = webidl.createInterfaceConverter( + // "GPUUncapturedErrorEvent", + // GPUUncapturedErrorEvent, + // ); + // DICTIONARY: GPUUncapturedErrorEventInit const dictMembersGPUUncapturedErrorEventInit = [ { key: "error", converter: webidl.converters["GPUError"], required: true }, @@ -1179,7 +1406,6 @@ webidl.converters["GPUUncapturedErrorEventInit"] = webidl .createDictionaryConverter( "GPUUncapturedErrorEventInit", - // dictMembersEventInit, dictMembersGPUUncapturedErrorEventInit, ); diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index dc4300d2718ffa..e143a26b81aeeb 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -104,12 +104,12 @@ impl Resource for WebGPUQuerySet { pub fn init(isolate: &mut deno_core::JsRuntime) { let files = vec![ ( - "deno:op_crates/webgpu/01_idl_types.js", - include_str!("01_idl_types.js"), + "deno:op_crates/webgpu/01_webgpu.js", + include_str!("01_webgpu.js"), ), ( - "deno:op_crates/webgpu/02_webgpu.js", - include_str!("02_webgpu.js"), + "deno:op_crates/webgpu/02_idl_types.js", + include_str!("02_idl_types.js"), ), ]; for (url, source_code) in files { diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 707f783769510a..5e6377383be61b 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -27,7 +27,7 @@ delete Object.prototype.__proto__; const headers = window.__bootstrap.headers; const streams = window.__bootstrap.streams; const fileReader = window.__bootstrap.fileReader; - const webGPU = window.__bootstrap.webGPU; + const webgpu = window.__bootstrap.webgpu; const webSocket = window.__bootstrap.webSocket; const file = window.__bootstrap.file; const fetch = window.__bootstrap.fetch; @@ -251,26 +251,27 @@ delete Object.prototype.__proto__; setInterval: util.writable(timers.setInterval), setTimeout: util.writable(timers.setTimeout), - GPUAdapter: util.nonEnumerable(webGPU.GPUAdapter), - GPUDevice: util.nonEnumerable(webGPU.GPUDevice), - GPUQueue: util.nonEnumerable(webGPU.GPUQueue), - GPUBuffer: util.nonEnumerable(webGPU.GPUBuffer), - GPUTexture: util.nonEnumerable(webGPU.GPUTexture), - GPUTextureView: util.nonEnumerable(webGPU.GPUTextureView), - GPUSampler: util.nonEnumerable(webGPU.GPUSampler), - GPUBindGroupLayout: util.nonEnumerable(webGPU.GPUBindGroupLayout), - GPUPipelineLayout: util.nonEnumerable(webGPU.GPUPipelineLayout), - GPUBindGroup: util.nonEnumerable(webGPU.GPUBindGroup), - GPUShaderModule: util.nonEnumerable(webGPU.GPUShaderModule), - GPUComputePipeline: util.nonEnumerable(webGPU.GPUComputePipeline), - GPURenderPipeline: util.nonEnumerable(webGPU.GPURenderPipeline), - GPUCommandEncoder: util.nonEnumerable(webGPU.GPUCommandEncoder), - GPURenderPassEncoder: util.nonEnumerable(webGPU.GPURenderPassEncoder), - GPUComputePassEncoder: util.nonEnumerable(webGPU.GPUComputePassEncoder), - GPUCommandBuffer: util.nonEnumerable(webGPU.GPUCommandBuffer), - GPURenderBundleEncoder: util.nonEnumerable(webGPU.GPURenderBundleEncoder), - GPURenderBundle: util.nonEnumerable(webGPU.GPURenderBundle), - GPUQuerySet: util.nonEnumerable(webGPU.GPUQuerySet), + GPU: util.nonEnumerable(webgpu.GPU), + GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), + GPUDevice: util.nonEnumerable(webgpu.GPUDevice), + GPUQueue: util.nonEnumerable(webgpu.GPUQueue), + GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer), + GPUTexture: util.nonEnumerable(webgpu.GPUTexture), + GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView), + GPUSampler: util.nonEnumerable(webgpu.GPUSampler), + GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout), + GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout), + GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup), + GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), + GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), + GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), + GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder), + GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder), + GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder), + GPUCommandBuffer: util.nonEnumerable(webgpu.GPUCommandBuffer), + GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder), + GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), + GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), }; // The console seems to be the only one that should be writable and non-enumerable @@ -279,7 +280,7 @@ delete Object.prototype.__proto__; windowOrWorkerGlobalScope.console.enumerable = false; const windowNavigatorProperties = { - gpu: webGPU.gpu, + gpu: webgpu.gpu, }; const mainRuntimeGlobalProperties = { @@ -301,7 +302,7 @@ delete Object.prototype.__proto__; }; const workerNavigatorProperties = { - gpu: webGPU.gpu, + gpu: webgpu.gpu, }; const workerRuntimeGlobalProperties = { From 1bd9cb129a88d6efe15fee69d0dd59f36edb8afb Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 16:33:58 +0100 Subject: [PATCH 099/144] fmt + lint --- op_crates/webgpu/01_webgpu.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index bed563e1b2c680..8990b71d79675e 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -178,7 +178,8 @@ * @param {any} type */ function GPUObjectBaseMixin(name, type) { - let mixin = { + type.prototype[_label] = null; + Object.defineProperty(type.prototype, "label", { /** * @return {string | null} */ @@ -197,9 +198,7 @@ }); this[_label] = label; }, - }; - type.prototype[_label] = null; - Object.defineProperty(type.prototype, "label", mixin); + }); } const _device = Symbol("[[device]]"); @@ -509,12 +508,13 @@ commandBuffers = webidl.converters.any(commandBuffers); core.jsonOpSync("op_webgpu_queue_submit", { queueRid: this[_device], - commandBuffers: commandBuffers.map((buffer) => buffer[ridSymbol]), + commandBuffers: commandBuffers.map((buffer) => buffer[_rid]), }); } - async onSubmittedWorkDone() { + onSubmittedWorkDone() { webidl.assertBranded(this, GPUQueue); + return Promise.resolve(); } /** From e56dfe744bce3308a7f3698c013202d5dab4150b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 18:45:43 +0100 Subject: [PATCH 100/144] nearly done with webidl --- op_crates/web/00_webidl.js | 2 +- op_crates/webgpu/01_webgpu.js | 1028 +++++++++++++++++++++++++++------ 2 files changed, 849 insertions(+), 181 deletions(-) diff --git a/op_crates/web/00_webidl.js b/op_crates/web/00_webidl.js index dfa8e205ec502e..5779e4f8f6d821 100644 --- a/op_crates/web/00_webidl.js +++ b/op_crates/web/00_webidl.js @@ -602,7 +602,7 @@ opts.prefix ? opts.prefix + ": " : "" }${required} argument${ required === 1 ? "" : "s" - }, but only ${length} present.`; + } required, but only ${length} present.`; throw new TypeError(errMsg); } } diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 8990b71d79675e..e289d175a0d8df 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -12,15 +12,6 @@ const webidl = window.__bootstrap.webidl; const eventTarget = window.__bootstrap.eventTarget; - const ridSymbol = Symbol("rid"); - - const keySymbol = Symbol("key"); - function checkKey(key) { - if (key !== keySymbol) { - throw new TypeError("Illegal constructor"); - } - } - function normalizeGPUExtent3D(data) { if (Array.isArray(data)) { return { @@ -274,7 +265,6 @@ ...descriptor, }); return new GPUBuffer( - keySymbol, rid, this[_device].rid, descriptor.label, @@ -294,7 +284,7 @@ size: normalizeGPUExtent3D(descriptor.size), }); - return new GPUTexture(keySymbol, rid, descriptor.label); + return createGPUTexture(descriptor.label ?? null, rid); } createSampler(descriptor = {}) { @@ -303,7 +293,7 @@ ...descriptor, }); - return new GPUSampler(keySymbol, rid, descriptor.label); + return createGPUSampler(descriptor.label ?? null, rid); } createBindGroupLayout(descriptor) { @@ -324,7 +314,7 @@ ...descriptor, }); - return new GPUBindGroupLayout(keySymbol, rid, descriptor.label); + return createGPUBindGroupLayout(descriptor.label ?? null, rid); } createPipelineLayout(descriptor) { @@ -332,36 +322,36 @@ deviceRid: this[_device].rid, label: descriptor.label, bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => - bindGroupLayout[ridSymbol] + bindGroupLayout[_rid] ), }); - return new GPUPipelineLayout(keySymbol, rid, descriptor.label); + return createGPUPipelineLayout(descriptor.label ?? null, rid); } createBindGroup(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { deviceRid: this[_device].rid, label: descriptor.label, - layout: descriptor.layout[ridSymbol], + layout: descriptor.layout[_rid], entries: descriptor.entries.map((entry) => { if (entry.resource instanceof GPUSampler) { return { binding: entry.binding, kind: "GPUSampler", - resource: entry.resource[ridSymbol], + resource: entry.resource[_rid], }; } else if (entry.resource instanceof GPUTextureView) { return { binding: entry.binding, kind: "GPUTextureView", - resource: entry.resource[ridSymbol], + resource: entry.resource[_rid], }; } else { return { binding: entry.binding, kind: "GPUBufferBinding", - resource: entry.resource.buffer[ridSymbol], + resource: entry.resource.buffer[_rid], offset: entry.resource.offset, size: entry.resource.size, }; @@ -369,7 +359,7 @@ }), }); - return new GPUBindGroup(keySymbol, rid, descriptor.label); + return createGPUBindGroup(descriptor.label ?? null, rid); } createShaderModule(descriptor) { @@ -386,29 +376,29 @@ ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []), ); - return new GPUShaderModule(keySymbol, rid, descriptor.label); + return createGPUShaderModule(descriptor.label ?? null, rid); } createComputePipeline(descriptor) { const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { deviceRid: this[_device].rid, label: descriptor.label, - layout: descriptor.layout ? descriptor.layout[ridSymbol] : undefined, + layout: descriptor.layout ? descriptor.layout[_rid] : undefined, compute: { - module: descriptor.compute.module[ridSymbol], + module: descriptor.compute.module[_rid], entryPoint: descriptor.compute.entryPoint, }, }); - return new GPUComputePipeline(keySymbol, rid, descriptor.label); + return createGPUComputePipeline(descriptor.label ?? null, rid); } createRenderPipeline(descriptor) { const d = { label: descriptor.label, - layout: descriptor.layout?.[ridSymbol], + layout: descriptor.layout?.[_rid], vertex: { - module: descriptor.vertex.module[ridSymbol], + module: descriptor.vertex.module[_rid], entryPoint: descriptor.vertex.entryPoint, buffers: descriptor.vertex.buffers, }, @@ -417,7 +407,7 @@ multisample: descriptor.multisample, fragment: descriptor.fragment ? { - module: descriptor.fragment.module[ridSymbol], + module: descriptor.fragment.module[_rid], entryPoint: descriptor.fragment.entryPoint, targets: descriptor.fragment.targets, } @@ -429,7 +419,7 @@ ...d, }); - return new GPURenderPipeline(keySymbol, rid, descriptor.label); + return createGPURenderPipeline(descriptor.label ?? null, rid); } createComputePipelineAsync(_descriptor) { @@ -446,7 +436,7 @@ ...descriptor, }); - return new GPUCommandEncoder(keySymbol, rid, descriptor.label); + return createGPUCommandEncoder(descriptor.label ?? null, rid); } createRenderBundleEncoder(descriptor) { @@ -554,7 +544,7 @@ "op_webgpu_write_buffer", { queueRid: this[_device], - buffer: buffer[ridSymbol], + buffer: buffer[_rid], bufferOffset, dataOffset, size, @@ -595,7 +585,7 @@ { queueRid: this[_device], destination: { - texture: destination.texture[ridSymbol], + texture: destination.texture[_rid], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -625,10 +615,8 @@ #mappedRid; #mappedBuffer; - constructor(key, rid, deviceRid, label, size, mappedAtCreation) { - checkKey(key); - - this[ridSymbol] = rid; + constructor(rid, deviceRid, label, size, mappedAtCreation) { + this[_rid] = rid; this.#deviceRid = deviceRid; this.label = label ?? null; this.#size = size; @@ -643,7 +631,7 @@ this.#mappedOffset = offset; this.#mappedSize = size ?? (this.#size - offset); await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { - bufferRid: this[ridSymbol], + bufferRid: this[_rid], deviceRid: this.#deviceRid, mode, offset, @@ -656,7 +644,7 @@ const { rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { - bufferRid: this[ridSymbol], + bufferRid: this[_rid], offset, size: size ?? this.#mappedSize, }, @@ -670,7 +658,7 @@ unmap() { core.jsonOpSync("op_webgpu_buffer_unmap", { - bufferRid: this[ridSymbol], + bufferRid: this[_rid], mappedRid: this.#mappedRid, }, this.#mappedBuffer); } @@ -679,148 +667,320 @@ throw new Error("Not yet implemented"); } } + + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUTexture} + */ + function createGPUTexture(label, rid) { + /** @type {GPUTexture} */ + const texture = webidl.createBranded(GPUTexture); + texture[_label] = label; + texture[_rid] = rid; + return texture; + } + class GPUTexture { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPUTextureViewDescriptor} descriptor + */ createView(descriptor = {}) { + webidl.assertBranded(this, GPUTexture); + const prefix = "Failed to execute 'createView' on 'GPUTexture'"; + webidl.requiredArguments(arguments.length, 0, { prefix }); + descriptor = webidl.converters.GPUTextureViewDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { - textureRid: this[ridSymbol], + textureRid: this[_rid], ...descriptor, }); - return new GPUTextureView(keySymbol, rid, descriptor.label); + return createGPUTextureView(descriptor.label ?? null, rid); } destroy() { throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPUTexture", GPUTexture); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUTextureView} + */ + function createGPUTextureView(label, rid) { + /** @type {GPUTextureView} */ + const textureView = webidl.createBranded(GPUTextureView); + textureView[_label] = label; + textureView[_rid] = rid; + return textureView; + } class GPUTextureView { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPUTextureView", GPUTextureView); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUSampler} + */ + function createGPUSampler(label, rid) { + /** @type {GPUSampler} */ + const sampler = webidl.createBranded(GPUSampler); + sampler[_label] = label; + sampler[_rid] = rid; + return sampler; + } class GPUSampler { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPUSampler", GPUSampler); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUBindGroupLayout} + */ + function createGPUBindGroupLayout(label, rid) { + /** @type {GPUBindGroupLayout} */ + const bindGroupLayout = webidl.createBranded(GPUBindGroupLayout); + bindGroupLayout[_label] = label; + bindGroupLayout[_rid] = rid; + return bindGroupLayout; + } class GPUBindGroupLayout { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPUBindGroupLayout", GPUBindGroupLayout); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUPipelineLayout} + */ + function createGPUPipelineLayout(label, rid) { + /** @type {GPUPipelineLayout} */ + const pipelineLayout = webidl.createBranded(GPUPipelineLayout); + pipelineLayout[_label] = label; + pipelineLayout[_rid] = rid; + return pipelineLayout; + } class GPUPipelineLayout { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPUPipelineLayout", GPUPipelineLayout); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUBindGroup} + */ + function createGPUBindGroup(label, rid) { + /** @type {GPUBindGroup} */ + const bindGroup = webidl.createBranded(GPUBindGroup); + bindGroup[_label] = label; + bindGroup[_rid] = rid; + return bindGroup; + } class GPUBindGroup { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } } + GPUObjectBaseMixin("GPUBindGroup", GPUBindGroup); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUShaderModule} + */ + function createGPUShaderModule(label, rid) { + /** @type {GPUShaderModule} */ + const bindGroup = webidl.createBranded(GPUShaderModule); + bindGroup[_label] = label; + bindGroup[_rid] = rid; + return bindGroup; + } class GPUShaderModule { - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } compilationInfo() { throw new Error("Not yet implemented"); } } + GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUComputePipeline} + */ + function createGPUComputePipeline(label, rid) { + /** @type {GPUComputePipeline} */ + const pipeline = webidl.createBranded(GPUComputePipeline); + pipeline[_label] = label; + pipeline[_rid] = rid; + return pipeline; + } class GPUComputePipeline { - [webidl.brand] = webidl.brand; - - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {number} index + */ getBindGroupLayout(index) { + webidl.assertBranded(this, GPURenderPipeline); + const prefix = + "Failed to execute 'getBindGroupLayout' on 'GPUComputePipeline'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + index = webidl.converters["unsigned long"](index, { + prefix, + context: "Argument 1", + }); const { rid, label } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", { - computePipelineRid: this[ridSymbol], + computePipelineRid: this[_rid], index, }, ); - return new GPUBindGroupLayout(keySymbol, rid, label); + return createGPUBindGroupLayout(label, rid); } } + GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPURenderPipeline} + */ + function createGPURenderPipeline(label, rid) { + /** @type {GPURenderPipeline} */ + const pipeline = webidl.createBranded(GPURenderPipeline); + pipeline[_label] = label; + pipeline[_rid] = rid; + return pipeline; + } class GPURenderPipeline { - [webidl.brand] = webidl.brand; - - constructor(key, rid, label) { - checkKey(key); + /** @type {number} */ + [_rid]; - this[ridSymbol] = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {number} index + */ getBindGroupLayout(index) { + webidl.assertBranded(this, GPURenderPipeline); + const prefix = + "Failed to execute 'getBindGroupLayout' on 'GPURenderPipeline'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + index = webidl.converters["unsigned long"](index, { + prefix, + context: "Argument 1", + }); const { rid, label } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", { - renderPipelineRid: this[ridSymbol], + renderPipelineRid: this[_rid], index, }, ); - return new GPUBindGroupLayout(keySymbol, rid, label); + return createGPUBindGroupLayout(label, rid); } } + GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); - class GPUCommandEncoder { - #rid; + /** + * @param {string | null} label + * @param {number} rid + * @returns {GPUCommandEncoder} + */ + function createGPUCommandEncoder(label, rid) { + /** @type {GPUCommandEncoder} */ + const encoder = webidl.createBranded(GPUCommandEncoder); + encoder[_label] = label; + encoder[_rid] = rid; + return encoder; + } - constructor(key, rid, label) { - checkKey(key); + class GPUCommandEncoder { + /** @type {number} */ + [_rid]; - this.#rid = rid; - this.label = label ?? null; + constructor() { + webidl.illegalConstructor(); } + /** + * @param {GPURenderPassDescriptor} descriptor + * @return {GPURenderPassEncoder} + */ beginRenderPass(descriptor) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderPassDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + let depthStencilAttachment; if (descriptor.depthStencilAttachment) { depthStencilAttachment = { ...descriptor.depthStencilAttachment, - view: descriptor.depthStencilAttachment.view[ridSymbol], + view: descriptor.depthStencilAttachment.view[_rid], }; if ( @@ -850,14 +1010,14 @@ const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_render_pass", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], ...descriptor, colorAttachments: descriptor.colorAttachments.map( (colorAttachment) => { const attachment = { - view: colorAttachment.view[ridSymbol], + view: colorAttachment.view[_rid], resolveTarget: colorAttachment.resolveTarget - ? colorAttachment.resolveTarget[ridSymbol] + ? colorAttachment.resolveTarget[_rid] : undefined, storeOp: colorAttachment.storeOp, }; @@ -878,30 +1038,47 @@ }, ); - return new GPURenderPassEncoder( - keySymbol, - this.#rid, + return createGPURenderPassEncoder( + descriptor.label ?? null, + this[_rid], rid, - descriptor.label, ); } + /** + * @param {GPUComputePassDescriptor} descriptor + */ beginComputePass(descriptor = {}) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; + descriptor = webidl.converters.GPUComputePassDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_compute_pass", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], ...descriptor, }, ); return createGPUComputePassEncoder( descriptor.label ?? null, - this.#rid, + this[_rid], rid, ); } + /** + * @param {GPUBuffer} source + * @param {number} sourceOffset + * @param {GPUBuffer} destination + * @param {number} destinationOffset + * @param {number} size + */ copyBufferToBuffer( source, sourceOffset, @@ -909,30 +1086,76 @@ destinationOffset, size, ) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 5, { prefix }); + source = webidl.converters.GPUBuffer(source, { + prefix, + context: "Argument 1", + }); + sourceOffset = webidl.converters.GPUSize64(sourceOffset, { + prefix, + context: "Argument 2", + }); + destination = webidl.converters.GPUBuffer(destination, { + prefix, + context: "Argument 3", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 4", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 5", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_buffer", { - commandEncoderRid: this.#rid, - source: source[ridSymbol], + commandEncoderRid: this[_rid], + source: source[_rid], sourceOffset, - destination: destination[ridSymbol], + destination: destination[_rid], destinationOffset, size, }, ); } + /** + * @param {GPUImageCopyBuffer} source + * @param {GPUImageCopyTexture} destination + * @param {GPUExtent3D} copySize + */ copyBufferToTexture(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyBuffer(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); + core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_texture", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], source: { ...source, - buffer: source.buffer[ridSymbol], + buffer: source.buffer[_rid], }, destination: { - texture: destination.texture[ridSymbol], + texture: destination.texture[_rid], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -942,37 +1165,79 @@ ); } + /** + * @param {GPUImageCopyTexture} source + * @param {GPUImageCopyBuffer} destination + * @param {GPUExtent3D} copySize + */ copyTextureToBuffer(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyTexture(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyBuffer(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], source: { - texture: source.texture[ridSymbol], + texture: source.texture[_rid], mipLevel: source.mipLevel, origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { ...destination, - buffer: destination.buffer[ridSymbol], + buffer: destination.buffer[_rid], }, copySize: normalizeGPUExtent3D(copySize), }, ); } + /** + * @param {GPUImageCopyTexture} source + * @param {GPUImageCopyTexture} destination + * @param {GPUExtent3D} copySize + */ copyTextureToTexture(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyTexture(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], source: { - texture: source.texture[ridSymbol], + texture: source.texture[_rid], mipLevel: source.mipLevel, origin: source.origin ?? normalizeGPUOrigin3D(source.origin), }, destination: { - texture: destination.texture[ridSymbol], + texture: destination.texture[_rid], mipLevel: destination.mipLevel, origin: destination.origin ?? normalizeGPUOrigin3D(destination.origin), @@ -982,32 +1247,80 @@ ); } + /** + * @param {string} groupLabel + */ pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], groupLabel, }); } + popDebugGroup() { + webidl.assertBranded(this, GPUCommandEncoder); core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], }); } + + /** + * @param {string} markerLabel + */ insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], markerLabel, }); } + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { - commandEncoderRid: this.#rid, - querySet: querySet[ridSymbol], + commandEncoderRid: this[_rid], + querySet: querySet[_rid], queryIndex, }); } + /** + * @param {GPUQuerySet} querySet + * @param {number} firstQuery + * @param {number} queryCount + * @param {GPUBuffer} destination + * @param {number} destinationOffset + */ resolveQuerySet( querySet, firstQuery, @@ -1015,41 +1328,118 @@ destination, destinationOffset, ) { - core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { - commandEncoderRid: this.#rid, - querySet: querySet[ridSymbol], - firstQuery, - queryCount, - destination: destination[ridSymbol], - destinationOffset, + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = + "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 5, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + firstQuery = webidl.converters.GPUSize32(firstQuery, { + prefix, + context: "Argument 2", + }); + queryCount = webidl.converters.GPUSize32(queryCount, { + prefix, + context: "Argument 3", + }); + destination = webidl.converters.GPUQuerySet(destination, { + prefix, + context: "Argument 4", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 5", + }); + core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { + commandEncoderRid: this[_rid], + querySet: querySet[_rid], + firstQuery, + queryCount, + destination: destination[_rid], + destinationOffset, }); } + /** + * @param {GPUCommandBufferDescriptor} descriptor + * @returns {GPUCommandBuffer} + */ finish(descriptor = {}) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; + descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { - commandEncoderRid: this.#rid, + commandEncoderRid: this[_rid], ...descriptor, }); return createGPUCommandBuffer(descriptor.label ?? null, rid); } } + GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); - class GPURenderPassEncoder { - #commandEncoderRid; - #rid; + const _encoder = Symbol("[[encoder]]"); - constructor(key, commandEncoderRid, rid, label) { - checkKey(key); + /** + * @param {string | null} label + * @param {number} encoderRid + * @param {number} rid + * @returns {GPURenderPassEncoder} + */ + function createGPURenderPassEncoder(label, encoderRid, rid) { + /** @type {GPURenderPassEncoder} */ + const encoder = webidl.createBranded(GPURenderPassEncoder); + encoder[_label] = label; + encoder[_encoder] = encoderRid; + encoder[_rid] = rid; + return encoder; + } - this.#commandEncoderRid = commandEncoderRid; - this.#rid = rid; - this.label = label ?? null; + class GPURenderPassEncoder { + /** @type {number} */ + [_encoder]; + /** @type {number} */ + [_rid]; + + constructor() { + webidl.illegalConstructor(); } + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {number} minDepth + * @param {number} maxDepth + */ setViewport(x, y, width, height, minDepth, maxDepth) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setViewport' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 6, { prefix }); + x = webidl.converters.float(x, { prefix, context: "Argument 1" }); + y = webidl.converters.float(y, { prefix, context: "Argument 2" }); + width = webidl.converters.float(width, { prefix, context: "Argument 3" }); + height = webidl.converters.float(height, { + prefix, + context: "Argument 4", + }); + minDepth = webidl.converters.float(minDepth, { + prefix, + context: "Argument 5", + }); + maxDepth = webidl.converters.float(maxDepth, { + prefix, + context: "Argument 6", + }); core.jsonOpSync("op_webgpu_render_pass_set_viewport", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], x, y, width, @@ -1059,9 +1449,36 @@ }); } + /** + * + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ setScissorRect(x, y, width, height) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setScissorRect' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 4, { prefix }); + x = webidl.converters.GPUIntegerCoordinate(x, { + prefix, + context: "Argument 1", + }); + y = webidl.converters.GPUIntegerCoordinate(y, { + prefix, + context: "Argument 2", + }); + width = webidl.converters.GPUIntegerCoordinate(width, { + prefix, + context: "Argument 3", + }); + height = webidl.converters.GPUIntegerCoordinate(height, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_pass_set_scissor_rect", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], x, y, width, @@ -1069,15 +1486,38 @@ }); } + /** + * @param {GPUColor} color + */ setBlendColor(color) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setBlendColor' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + color = webidl.converters.GPUColor(color, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_set_blend_color", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], color: normalizeGPUColor(color), }); } + + /** + * @param {number} reference + */ setStencilReference(reference) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + reference = webidl.converters.GPUStencilValue(reference, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_set_stencil_reference", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], reference, }); } @@ -1085,44 +1525,93 @@ beginOcclusionQuery(_queryIndex) { throw new Error("Not yet implemented"); } + endOcclusionQuery() { throw new Error("Not yet implemented"); } + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ beginPipelineStatisticsQuery(querySet, queryIndex) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { - renderPassRid: this.#rid, - querySet: querySet[ridSymbol], + renderPassRid: this[_rid], + querySet: querySet[_rid], queryIndex, }); } + endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_end_pipeline_statistics_query", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], }); } + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_render_pass_write_timestamp", { - renderPassRid: this.#rid, - querySet: querySet[ridSymbol], + renderPassRid: this[_rid], + querySet: querySet[_rid], queryIndex, }); } + /** + * @param {GPURenderBundle[]} bundles + */ executeBundles(bundles) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + // TODO(lucacasonato): missing sequence + // bundles = webidl.converters.any(bundles, { + // prefix, + // context: "Argument 1", + // }); core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { - renderPassRid: this.#rid, - bundles: bundles.map((bundle) => bundle[ridSymbol]), + renderPassRid: this[_rid], + bundles: bundles.map((bundle) => bundle[_rid]), }); } + endPass() { core.jsonOpSync("op_webgpu_render_pass_end_pass", { - commandEncoderRid: this.#commandEncoderRid, - renderPassRid: this.#rid, + commandEncoderRid: this[_encoder], + renderPassRid: this[_rid], }); } + // TODO(lucacasonato): has an overload setBindGroup( index, bindGroup, @@ -1130,12 +1619,12 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = bindGroup[ridSymbol]; + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_pass_set_bind_group", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], index, bindGroup: bind, dynamicOffsetsDataStart, @@ -1146,7 +1635,7 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_render_pass_set_bind_group", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], index, bindGroup: bind, dynamicOffsetsData, @@ -1156,59 +1645,181 @@ } } + /** + * @param {string} groupLabel + */ pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_push_debug_group", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], groupLabel, }); } + popDebugGroup() { + webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], }); } + + /** + * @param {string} markerLabel + */ insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_insert_debug_marker", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], markerLabel, }); } + /** + * @param {GPURenderPipeline} pipeline + */ setPipeline(pipeline) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setPipeline' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPURenderPipeline(pipeline, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_set_pipeline", { - renderPassRid: this.#rid, - pipeline: pipeline[ridSymbol], + renderPassRid: this[_rid], + pipeline: pipeline[_rid], }); } + /** + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size + */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 1", + }); + indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_pass_set_index_buffer", { - renderPassRid: this.#rid, - buffer: buffer[ridSymbol], + renderPassRid: this[_rid], + buffer: buffer[_rid], indexFormat, offset, size, }); } + + /** + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size + */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + slot = webidl.converters.GPUSize32(slot, { + prefix, + context: "Argument 2", + }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_pass_set_vertex_buffer", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], slot, - buffer: buffer[ridSymbol], + buffer: buffer[_rid], offset, size, }); } + /** + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance + */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = "Failed to execute 'draw' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + vertexCount = webidl.converters.GPUSize32(vertexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstVertex = webidl.converters.GPUSize32(firstVertex, { + prefix, + context: "Argument 3", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 4", + }); core.jsonOpSync("op_webgpu_render_pass_draw", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], vertexCount, instanceCount, firstVertex, firstInstance, }); } + + /** + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance + */ drawIndexed( indexCount, instanceCount = 1, @@ -1216,8 +1827,32 @@ baseVertex = 0, firstInstance = 0, ) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + indexCount = webidl.converters.GPUSize32(indexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstIndex = webidl.converters.GPUSize32(firstIndex, { + prefix, + context: "Argument 3", + }); + baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { + prefix, + context: "Argument 4", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 5", + }); core.jsonOpSync("op_webgpu_render_pass_draw_indexed", { - renderPassRid: this.#rid, + renderPassRid: this[_rid], indexCount, instanceCount, firstIndex, @@ -1226,23 +1861,55 @@ }); } + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ drawIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_render_pass_draw_indirect", { - renderPassRid: this.#rid, - indirectBuffer: indirectBuffer[ridSymbol], + renderPassRid: this[_rid], + indirectBuffer: indirectBuffer[_rid], indirectOffset, }); } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ drawIndexedIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); core.jsonOpSync("op_webgpu_render_pass_draw_indexed_indirect", { - renderPassRid: this.#rid, - indirectBuffer: indirectBuffer[ridSymbol], + renderPassRid: this[_rid], + indirectBuffer: indirectBuffer[_rid], indirectOffset, }); } } - - const _encoder = Symbol("[[encoder]]"); + GPUObjectBaseMixin("GPURenderPassEncoder", GPURenderPassEncoder); /** * @param {string | null} label @@ -1284,7 +1951,7 @@ }); core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { computePassRid: this[_rid], - pipeline: pipeline[ridSymbol], + pipeline: pipeline[_rid], }); } @@ -1327,7 +1994,7 @@ }); core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { computePassRid: this[_rid], - indirectBuffer: indirectBuffer[ridSymbol], + indirectBuffer: indirectBuffer[_rid], indirectOffset, }); } @@ -1406,7 +2073,7 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = bindGroup[ridSymbol]; + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_compute_pass_set_bind_group", @@ -1440,7 +2107,7 @@ const prefix = "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.GPURenderBundleDescriptor(groupLabel, { + groupLabel = webidl.converters.USVString(groupLabel, { prefix, context: "Argument 1", }); @@ -1451,6 +2118,7 @@ } popDebugGroup() { + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { computePassRid: this[_rid], }); @@ -1464,7 +2132,7 @@ const prefix = "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.GPURenderBundleDescriptor(markerLabel, { + markerLabel = webidl.converters.USVString(markerLabel, { prefix, context: "Argument 1", }); @@ -1552,7 +2220,7 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - const bind = bindGroup[ridSymbol]; + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_bundle_encoder_set_bind_group", @@ -1586,7 +2254,7 @@ const prefix = "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.GPURenderBundleDescriptor(groupLabel, { + groupLabel = webidl.converters.USVString(groupLabel, { prefix, context: "Argument 1", }); @@ -1611,7 +2279,7 @@ const prefix = "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.GPURenderBundleDescriptor(markerLabel, { + markerLabel = webidl.converters.USVString(markerLabel, { prefix, context: "Argument 1", }); @@ -1635,7 +2303,7 @@ }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { renderBundleEncoderRid: this[_rid], - pipeline: pipeline[ridSymbol], + pipeline: pipeline[_rid], }); } @@ -1668,7 +2336,7 @@ }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { renderBundleEncoderRid: this[_rid], - buffer: buffer[ridSymbol], + buffer: buffer[_rid], indexFormat, offset, size, @@ -1705,7 +2373,7 @@ core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { renderBundleEncoderRid: this[_rid], slot, - buffer: buffer[ridSymbol], + buffer: buffer[_rid], offset, size, }); @@ -1720,7 +2388,7 @@ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); + webidl.requiredArguments(arguments.length, 1, { prefix }); vertexCount = webidl.converters.GPUSize32(vertexCount, { prefix, context: "Argument 1", @@ -1763,7 +2431,7 @@ webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); + webidl.requiredArguments(arguments.length, 1, { prefix }); indexCount = webidl.converters.GPUSize32(indexCount, { prefix, context: "Argument 1", @@ -1813,7 +2481,7 @@ }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { renderBundleEncoderRid: this[_rid], - indirectBuffer: indirectBuffer[ridSymbol], + indirectBuffer: indirectBuffer[_rid], indirectOffset, }); } From f97fba7647d0de8cc3c7b5f011f5166c9b106a04 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 21:35:03 +0100 Subject: [PATCH 101/144] GPUDevice webidl --- op_crates/webgpu/01_webgpu.js | 122 +++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index e289d175a0d8df..bc338cd1a798fc 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -256,8 +256,10 @@ */ createBuffer(descriptor) { webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createBuffer' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); descriptor = webidl.converters.GPUBufferDescriptor(descriptor, { - prefix: "Failed to execute 'createBuffer' on 'GPUDevice'", + prefix, context: "Argument 1", }); const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { @@ -273,9 +275,15 @@ ); } + /** + * @param {GPUTextureDescriptor} descriptor + */ createTexture(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createTexture' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); descriptor = webidl.converters.GPUTextureDescriptor(descriptor, { - prefix: "Failed to execute 'createTexture' on 'GPUDevice'", + prefix, context: "Argument 1", }); const { rid } = core.jsonOpSync("op_webgpu_create_texture", { @@ -287,7 +295,17 @@ return createGPUTexture(descriptor.label ?? null, rid); } + /** + * @param {GPUSamplerDescriptor} descriptor + */ createSampler(descriptor = {}) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createSampler' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUSamplerDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { deviceRid: this[_device].rid, ...descriptor, @@ -296,7 +314,17 @@ return createGPUSampler(descriptor.label ?? null, rid); } + /** + * @param {GPUBindGroupLayoutDescriptor} descriptor + */ createBindGroupLayout(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createBindGroupLayout' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUBindGroupLayoutDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); for (const entry of descriptor.entries) { let i = 0; if (entry.buffer) i++; @@ -317,7 +345,17 @@ return createGPUBindGroupLayout(descriptor.label ?? null, rid); } + /** + * @param {GPUPipelineLayoutDescriptor} descriptor + */ createPipelineLayout(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createPipelineLayout' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUPipelineLayoutDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { deviceRid: this[_device].rid, label: descriptor.label, @@ -329,7 +367,17 @@ return createGPUPipelineLayout(descriptor.label ?? null, rid); } + /** + * @param {GPUBindGroupDescriptor} descriptor + */ createBindGroup(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createBindGroup' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUBindGroupDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { deviceRid: this[_device].rid, label: descriptor.label, @@ -362,7 +410,17 @@ return createGPUBindGroup(descriptor.label ?? null, rid); } + /** + * @param {GPUShaderModuleDescriptor} descriptor + */ createShaderModule(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createShaderModule' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUShaderModuleDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync( "op_webgpu_create_shader_module", { @@ -373,13 +431,25 @@ : undefined, sourceMap: descriptor.sourceMap, }, - ...(descriptor.code instanceof Uint32Array ? [descriptor.code] : []), + ...(descriptor.code instanceof Uint32Array + ? [new Uint8Array(descriptor.code.buffer)] + : []), ); return createGPUShaderModule(descriptor.label ?? null, rid); } + /** + * @param {GPUComputePipelineDescriptor} descriptor + */ createComputePipeline(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createComputePipeline' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUComputePipelineDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { deviceRid: this[_device].rid, label: descriptor.label, @@ -393,7 +463,17 @@ return createGPUComputePipeline(descriptor.label ?? null, rid); } + /** + * @param {GPURenderPipelineDescriptor} descriptor + */ createRenderPipeline(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createRenderPipeline' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderPipelineDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const d = { label: descriptor.label, layout: descriptor.layout?.[_rid], @@ -430,7 +510,16 @@ throw new Error("Not yet implemented"); // easy polyfill } + /** + * @param {GPUCommandEncoderDescriptor} descriptor + */ createCommandEncoder(descriptor = {}) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createCommandEncoder' on 'GPUDevice'"; + descriptor = webidl.converters.GPUCommandEncoderDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { deviceRid: this[_device].rid, ...descriptor, @@ -439,7 +528,21 @@ return createGPUCommandEncoder(descriptor.label ?? null, rid); } + /** + * @param {GPURenderBundleEncoderDescriptor} descriptor + */ createRenderBundleEncoder(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = + "Failed to execute 'createRenderBundleEncoder' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderBundleEncoderDescriptor( + descriptor, + { + prefix, + context: "Argument 1", + }, + ); const { rid } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { @@ -451,7 +554,20 @@ return createGPURenderBundleEncoder(descriptor.label ?? null, rid); } + /** + * @param {GPUQuerySetDescriptor} descriptor + */ createQuerySet(descriptor) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'createQuerySet' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUQuerySetDescriptor( + descriptor, + { + prefix, + context: "Argument 1", + }, + ); const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { deviceRid: this[_device].rid, ...descriptor, From bea8d68db0f921697e9e4355ca85e58b1827d488 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 17 Feb 2021 22:01:27 +0100 Subject: [PATCH 102/144] add flags classes --- op_crates/webgpu/01_webgpu.js | 318 +++++++++++++++++++++------------- runtime/js/99_main.js | 4 + 2 files changed, 204 insertions(+), 118 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index bc338cd1a798fc..284d4b6b7fadd6 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -57,7 +57,7 @@ } /** - * @param {GPURequestAdapterOptions} options + * @param {GPURequestAdapterOptions} options */ async requestAdapter(options = {}) { webidl.assertBranded(this, GPU); @@ -92,7 +92,7 @@ */ /** - * @param {string} name + * @param {string} name * @param {InnerGPUAdapter} inner * @returns {GPUAdapter} */ @@ -252,7 +252,7 @@ } /** - * @param {GPUBufferDescriptor} descriptor + * @param {GPUBufferDescriptor} descriptor */ createBuffer(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -276,7 +276,7 @@ } /** - * @param {GPUTextureDescriptor} descriptor + * @param {GPUTextureDescriptor} descriptor */ createTexture(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -296,7 +296,7 @@ } /** - * @param {GPUSamplerDescriptor} descriptor + * @param {GPUSamplerDescriptor} descriptor */ createSampler(descriptor = {}) { webidl.assertBranded(this, GPUDevice); @@ -315,7 +315,7 @@ } /** - * @param {GPUBindGroupLayoutDescriptor} descriptor + * @param {GPUBindGroupLayoutDescriptor} descriptor */ createBindGroupLayout(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -346,7 +346,7 @@ } /** - * @param {GPUPipelineLayoutDescriptor} descriptor + * @param {GPUPipelineLayoutDescriptor} descriptor */ createPipelineLayout(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -368,7 +368,7 @@ } /** - * @param {GPUBindGroupDescriptor} descriptor + * @param {GPUBindGroupDescriptor} descriptor */ createBindGroup(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -411,7 +411,7 @@ } /** - * @param {GPUShaderModuleDescriptor} descriptor + * @param {GPUShaderModuleDescriptor} descriptor */ createShaderModule(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -440,7 +440,7 @@ } /** - * @param {GPUComputePipelineDescriptor} descriptor + * @param {GPUComputePipelineDescriptor} descriptor */ createComputePipeline(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -555,7 +555,7 @@ } /** - * @param {GPUQuerySetDescriptor} descriptor + * @param {GPUQuerySetDescriptor} descriptor */ createQuerySet(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -593,7 +593,7 @@ class GPUQueue { /** - * The rid of the related device. + * The rid of the related device. * @type {number} */ [_device]; @@ -603,7 +603,7 @@ } /** - * @param {GPUCommandBuffer[]} commandBuffers + * @param {GPUCommandBuffer[]} commandBuffers */ submit(commandBuffers) { webidl.assertBranded(this, GPUQueue); @@ -624,11 +624,11 @@ } /** - * @param {GPUBuffer} buffer - * @param {number} bufferOffset - * @param {BufferSource} data - * @param {number} [dataOffset] - * @param {number} [size] + * @param {GPUBuffer} buffer + * @param {number} bufferOffset + * @param {BufferSource} data + * @param {number} [dataOffset] + * @param {number} [size] */ writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { webidl.assertBranded(this, GPUQueue); @@ -670,10 +670,10 @@ } /** - * @param {GPUImageCopyTexture} destination - * @param {BufferSource} data - * @param {GPUImageDataLayout} dataLayout - * @param {GPUExtent3D} size + * @param {GPUImageCopyTexture} destination + * @param {BufferSource} data + * @param {GPUImageDataLayout} dataLayout + * @param {GPUExtent3D} size */ writeTexture(destination, data, dataLayout, size) { webidl.assertBranded(this, GPUQueue); @@ -784,6 +784,48 @@ } } + class GPUBufferUsage { + static get MAP_READ() { + return 0x0001; + } + static get MAP_WRITE() { + return 0x0002; + } + static get COPY_SRC() { + return 0x0004; + } + static get COPY_DST() { + return 0x0008; + } + static get INDEX() { + return 0x0010; + } + static get VERTEX() { + return 0x0020; + } + static get UNIFORM() { + return 0x0040; + } + static get STORAGE() { + return 0x0080; + } + static get INDIRECT() { + return 0x0100; + } + static get QUERY_RESOLVE() { + return 0x0200; + } + } + + class GPUMapMode { + static get READ() { + return 0x0001; + } + static get WRITE() { + return 0x0002; + } + } + /** * @param {string | null} label * @param {number} rid @@ -806,7 +848,7 @@ } /** - * @param {GPUTextureViewDescriptor} descriptor + * @param {GPUTextureViewDescriptor} descriptor */ createView(descriptor = {}) { webidl.assertBranded(this, GPUTexture); @@ -831,6 +873,24 @@ } GPUObjectBaseMixin("GPUTexture", GPUTexture); + class GPUTextureUsage { + static get COPY_SRC() { + return 0x01; + } + static get COPY_DST() { + return 0x02; + } + static get SAMPLED() { + return 0x04; + } + static get STORAGE() { + return 0x08; + } + static get RENDER_ATTACHMENT() { + return 0x10; + } + } + /** * @param {string | null} label * @param {number} rid @@ -988,7 +1048,7 @@ } /** - * @param {number} index + * @param {number} index */ getBindGroupLayout(index) { webidl.assertBranded(this, GPURenderPipeline); @@ -1033,7 +1093,7 @@ } /** - * @param {number} index + * @param {number} index */ getBindGroupLayout(index) { webidl.assertBranded(this, GPURenderPipeline); @@ -1057,6 +1117,24 @@ } GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); + class GPUColorWrite { + static get RED() { + return 0x1; + } + static get GREEN() { + return 0x2; + } + static get BLUE() { + return 0x4; + } + static get ALPHA() { + return 0x8; + } + static get ALL() { + return 0xF; + } + } + /** * @param {string | null} label * @param {number} rid @@ -1162,7 +1240,7 @@ } /** - * @param {GPUComputePassDescriptor} descriptor + * @param {GPUComputePassDescriptor} descriptor */ beginComputePass(descriptor = {}) { webidl.assertBranded(this, GPUCommandEncoder); @@ -1189,11 +1267,11 @@ } /** - * @param {GPUBuffer} source - * @param {number} sourceOffset - * @param {GPUBuffer} destination - * @param {number} destinationOffset - * @param {number} size + * @param {GPUBuffer} source + * @param {number} sourceOffset + * @param {GPUBuffer} destination + * @param {number} destinationOffset + * @param {number} size */ copyBufferToBuffer( source, @@ -1364,7 +1442,7 @@ } /** - * @param {string} groupLabel + * @param {string} groupLabel */ pushDebugGroup(groupLabel) { webidl.assertBranded(this, GPUCommandEncoder); @@ -1389,7 +1467,7 @@ } /** - * @param {string} markerLabel + * @param {string} markerLabel */ insertDebugMarker(markerLabel) { webidl.assertBranded(this, GPUCommandEncoder); @@ -1407,8 +1485,8 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex + * @param {GPUQuerySet} querySet + * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { webidl.assertBranded(this, GPUCommandEncoder); @@ -1431,11 +1509,11 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} firstQuery - * @param {number} queryCount - * @param {GPUBuffer} destination - * @param {number} destinationOffset + * @param {GPUQuerySet} querySet + * @param {number} firstQuery + * @param {number} queryCount + * @param {GPUBuffer} destination + * @param {number} destinationOffset */ resolveQuerySet( querySet, @@ -1479,7 +1557,7 @@ } /** - * @param {GPUCommandBufferDescriptor} descriptor + * @param {GPUCommandBufferDescriptor} descriptor * @returns {GPUCommandBuffer} */ finish(descriptor = {}) { @@ -1527,12 +1605,12 @@ } /** - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height - * @param {number} minDepth - * @param {number} maxDepth + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {number} minDepth + * @param {number} maxDepth */ setViewport(x, y, width, height, minDepth, maxDepth) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1566,11 +1644,11 @@ } /** - * - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height + * + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height */ setScissorRect(x, y, width, height) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1603,7 +1681,7 @@ } /** - * @param {GPUColor} color + * @param {GPUColor} color */ setBlendColor(color) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1621,7 +1699,7 @@ } /** - * @param {number} reference + * @param {number} reference */ setStencilReference(reference) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1647,8 +1725,8 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex + * @param {GPUQuerySet} querySet + * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1678,8 +1756,8 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex + * @param {GPUQuerySet} querySet + * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1702,7 +1780,7 @@ } /** - * @param {GPURenderBundle[]} bundles + * @param {GPURenderBundle[]} bundles */ executeBundles(bundles) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1762,7 +1840,7 @@ } /** - * @param {string} groupLabel + * @param {string} groupLabel */ pushDebugGroup(groupLabel) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1787,7 +1865,7 @@ } /** - * @param {string} markerLabel + * @param {string} markerLabel */ insertDebugMarker(markerLabel) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1805,7 +1883,7 @@ } /** - * @param {GPURenderPipeline} pipeline + * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1823,10 +1901,10 @@ } /** - * @param {GPUBuffer} buffer - * @param {GPUIndexFormat} indexFormat - * @param {number} offset - * @param {number} size + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1859,10 +1937,10 @@ } /** - * @param {number} slot - * @param {GPUBuffer} buffer - * @param {number} offset - * @param {number} size + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1895,10 +1973,10 @@ } /** - * @param {number} vertexCount - * @param {number} instanceCount - * @param {number} firstVertex - * @param {number} firstInstance + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -1930,11 +2008,11 @@ } /** - * @param {number} indexCount - * @param {number} instanceCount - * @param {number} firstIndex - * @param {number} baseVertex - * @param {number} firstInstance + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance */ drawIndexed( indexCount, @@ -1978,8 +2056,8 @@ } /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -2002,8 +2080,8 @@ } /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset */ drawIndexedIndirect(indirectBuffer, indirectOffset) { webidl.assertBranded(this, GPURenderPassEncoder); @@ -2054,7 +2132,7 @@ } /** - * @param {GPUComputePipeline} pipeline + * @param {GPUComputePipeline} pipeline */ setPipeline(pipeline) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2072,9 +2150,9 @@ } /** - * @param {number} x - * @param {number} y - * @param {number} z + * @param {number} x + * @param {number} y + * @param {number} z */ dispatch(x, y = 1, z = 1) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2092,8 +2170,8 @@ } /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset */ dispatchIndirect(indirectBuffer, indirectOffset) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2116,8 +2194,8 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex + * @param {GPUQuerySet} querySet + * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2150,8 +2228,8 @@ } /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex + * @param {GPUQuerySet} querySet + * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2216,7 +2294,7 @@ } /** - * @param {string} groupLabel + * @param {string} groupLabel */ pushDebugGroup(groupLabel) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2241,7 +2319,7 @@ } /** - * @param {string} markerLabel + * @param {string} markerLabel */ insertDebugMarker(markerLabel) { webidl.assertBranded(this, GPUComputePassEncoder); @@ -2309,7 +2387,7 @@ } /** - * @param {GPURenderBundleDescriptor} descriptor + * @param {GPURenderBundleDescriptor} descriptor */ finish(descriptor = {}) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2363,7 +2441,7 @@ } /** - * @param {string} groupLabel + * @param {string} groupLabel */ pushDebugGroup(groupLabel) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2388,7 +2466,7 @@ } /** - * @param {string} markerLabel + * @param {string} markerLabel */ insertDebugMarker(markerLabel) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2406,7 +2484,7 @@ } /** - * @param {GPURenderPipeline} pipeline + * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2424,10 +2502,10 @@ } /** - * @param {GPUBuffer} buffer - * @param {GPUIndexFormat} indexFormat - * @param {number} offset - * @param {number} size + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2460,10 +2538,10 @@ } /** - * @param {number} slot - * @param {GPUBuffer} buffer - * @param {number} offset - * @param {number} size + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2496,10 +2574,10 @@ } /** - * @param {number} vertexCount - * @param {number} instanceCount - * @param {number} firstVertex - * @param {number} firstInstance + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2531,11 +2609,11 @@ } /** - * @param {number} indexCount - * @param {number} instanceCount - * @param {number} firstIndex - * @param {number} baseVertex - * @param {number} firstInstance + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance */ drawIndexed( indexCount, @@ -2579,8 +2657,8 @@ } /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { webidl.assertBranded(this, GPURenderBundleEncoder); @@ -2666,6 +2744,9 @@ GPUDevice, GPUQueue, GPUBuffer, + GPUBufferUsage, + GPUMapMode, + GPUTextureUsage, GPUTexture, GPUTextureView, GPUSampler, @@ -2675,6 +2756,7 @@ GPUShaderModule, GPUComputePipeline, GPURenderPipeline, + GPUColorWrite, GPUCommandEncoder, GPURenderPassEncoder, GPUComputePassEncoder, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 5e6377383be61b..712f28e04a87a2 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -256,7 +256,10 @@ delete Object.prototype.__proto__; GPUDevice: util.nonEnumerable(webgpu.GPUDevice), GPUQueue: util.nonEnumerable(webgpu.GPUQueue), GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer), + GPUBufferUsage: util.nonEnumerable(webgpu.GPUBufferUsage), + GPUMapMode: util.nonEnumerable(webgpu.GPUMapMode), GPUTexture: util.nonEnumerable(webgpu.GPUTexture), + GPUTextureUsage: util.nonEnumerable(webgpu.GPUTextureUsage), GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView), GPUSampler: util.nonEnumerable(webgpu.GPUSampler), GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout), @@ -265,6 +268,7 @@ delete Object.prototype.__proto__; GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), + GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite), GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder), GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder), GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder), From 635169b304e5718438a2a1b8bb075251c0799fc2 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 17 Feb 2021 22:37:05 +0100 Subject: [PATCH 103/144] adapter features --- op_crates/webgpu/01_webgpu.js | 55 ++++++++++++++++++++++++++++++++++- runtime/js/99_main.js | 1 + 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 284d4b6b7fadd6..99c9cec0ad2789 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -154,7 +154,7 @@ { rid, adapter: this, - features: Object.freeze(features), + features: createGPUAdapterFeatures(features), limits: Object.freeze(limits), queue: createGPUQueue(descriptor.label ?? null, rid), }, @@ -162,6 +162,58 @@ } } + const _features = Symbol("[[set]]"); + + function createGPUAdapterFeatures(features) { + /** @type {GPUAdapterFeatures} */ + const adapterFeatures = webidl.createBranded(GPUAdapterFeatures); + adapterFeatures[_features] = new Set(features); + return adapterFeatures; + } + + class GPUAdapterFeatures { + /** @type {Set} */ + [_features]; + + constructor() { + webidl.illegalConstructor(); + } + + /** @return {IterableIterator<[string, string]>} */ + entries() { + return this[_features].entries(); + } + + /** @return {void} */ + forEach(callbackfn, thisArg) { + this[_features].forEach(callbackfn, thisArg); + } + + /** @return {boolean} */ + has(value) { + return this[_features].has(value); + } + + /** @return {string[]} */ + keys() { + return this[_features].keys(); + } + + /** @return {IterableIterator} */ + values() { + return this[_features].values(); + } + + /** @return {number} */ + get size() { + return this[_features].size; + } + + [Symbol.iterator]() { + return this[_features][Symbol.iterator](); + } + } + const _label = Symbol("[[label]]"); /** @@ -2741,6 +2793,7 @@ gpu: webidl.createBranded(GPU), GPU, GPUAdapter, + GPUAdapterFeatures, GPUDevice, GPUQueue, GPUBuffer, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 712f28e04a87a2..037c1127cf11c5 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -253,6 +253,7 @@ delete Object.prototype.__proto__; GPU: util.nonEnumerable(webgpu.GPU), GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), + GPUAdapterFeatures: util.nonEnumerable(webgpu.GPUAdapterFeatures), GPUDevice: util.nonEnumerable(webgpu.GPUDevice), GPUQueue: util.nonEnumerable(webgpu.GPUQueue), GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer), From 84df17fe85079e4ca7ea5a1a968d22b38b39a311 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Wed, 17 Feb 2021 23:00:32 +0100 Subject: [PATCH 104/144] adapter limits --- op_crates/webgpu/01_webgpu.js | 101 +++++++++++++++++++++++++++++++++- runtime/js/99_main.js | 1 + 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 99c9cec0ad2789..74eef43fb6d488 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -100,7 +100,11 @@ /** @type {GPUAdapter} */ const adapter = webidl.createBranded(GPUAdapter); adapter[_name] = name; - adapter[_adapter] = inner; + adapter[_adapter] = { + ...inner, + features: createGPUAdapterFeatures(inner.features), + limits: createGPUAdapterLimits(inner.limits), + }; return adapter; } @@ -154,7 +158,7 @@ { rid, adapter: this, - features: createGPUAdapterFeatures(features), + features: Object.freeze(features), limits: Object.freeze(limits), queue: createGPUQueue(descriptor.label ?? null, rid), }, @@ -162,7 +166,97 @@ } } - const _features = Symbol("[[set]]"); + const _limits = Symbol("[[limits]]"); + + function createGPUAdapterLimits(features) { + /** @type {GPUAdapterLimits} */ + const adapterFeatures = webidl.createBranded(GPUAdapterLimits); + adapterFeatures[_limits] = features; + return adapterFeatures; + } + + /** + * @typedef InnerAdapterLimits + * @property {number} maxTextureDimension1D + * @property {number} maxTextureDimension2D + * @property {number} maxTextureDimension3D + * @property {number} maxTextureArrayLayers + * @property {number} maxBindGroups + * @property {number} maxDynamicUniformBuffersPerPipelineLayout + * @property {number} maxDynamicStorageBuffersPerPipelineLayout + * @property {number} maxSampledTexturesPerShaderStage + * @property {number} maxSamplersPerShaderStage + * @property {number} maxStorageBuffersPerShaderStage + * @property {number} maxStorageTexturesPerShaderStage + * @property {number} maxUniformBuffersPerShaderStage + * @property {number} maxUniformBufferBindingSize + * @property {number} maxStorageBufferBindingSize + * @property {number} maxVertexBuffers + * @property {number} maxVertexAttributes + * @property {number} maxVertexBufferArrayStride + */ + + class GPUAdapterLimits { + /** @type {InnerAdapterLimits} */ + [_limits]; + constructor() { + webidl.illegalConstructor(); + } + + get maxTextureDimension1D() { + throw new TypeError("Not yet implemented"); + } + get maxTextureDimension2D() { + throw new TypeError("Not yet implemented"); + } + get maxTextureDimension3D() { + throw new TypeError("Not yet implemented"); + } + get maxTextureArrayLayers() { + throw new TypeError("Not yet implemented"); + } + get maxBindGroups() { + return this[_limits].maxBindGroups; + } + get maxDynamicUniformBuffersPerPipelineLayout() { + return this[_limits].maxDynamicUniformBuffersPerPipelineLayout; + } + get maxDynamicStorageBuffersPerPipelineLayout() { + return this[_limits].maxDynamicStorageBuffersPerPipelineLayout; + } + get maxSampledTexturesPerShaderStage() { + return this[_limits].maxSampledTexturesPerShaderStage; + } + get maxSamplersPerShaderStage() { + return this[_limits].maxSamplersPerShaderStage; + } + get maxStorageBuffersPerShaderStage() { + return this[_limits].maxStorageBuffersPerShaderStage; + } + get maxStorageTexturesPerShaderStage() { + return this[_limits].maxStorageTexturesPerShaderStage; + } + get maxUniformBuffersPerShaderStage() { + return this[_limits].maxUniformBuffersPerShaderStage; + } + get maxUniformBufferBindingSize() { + return this[_limits].maxUniformBufferBindingSize; + } + get maxStorageBufferBindingSize() { + throw new TypeError("Not yet implemented"); + } + get maxVertexBuffers() { + throw new TypeError("Not yet implemented"); + } + get maxVertexAttributes() { + throw new TypeError("Not yet implemented"); + } + get maxVertexBufferArrayStride() { + throw new TypeError("Not yet implemented"); + } + } + + const _features = Symbol("[[features]]"); function createGPUAdapterFeatures(features) { /** @type {GPUAdapterFeatures} */ @@ -2793,6 +2887,7 @@ gpu: webidl.createBranded(GPU), GPU, GPUAdapter, + GPUAdapterLimits, GPUAdapterFeatures, GPUDevice, GPUQueue, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 037c1127cf11c5..3371e812685e4a 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -253,6 +253,7 @@ delete Object.prototype.__proto__; GPU: util.nonEnumerable(webgpu.GPU), GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), + GPUAdapterLimits: util.nonEnumerable(webgpu.GPUAdapterLimits), GPUAdapterFeatures: util.nonEnumerable(webgpu.GPUAdapterFeatures), GPUDevice: util.nonEnumerable(webgpu.GPUDevice), GPUQueue: util.nonEnumerable(webgpu.GPUQueue), From 277b156a58041efe98404333d7cd0af2fcaf6c63 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 17 Feb 2021 23:21:47 +0100 Subject: [PATCH 105/144] webidl for GPUBuffer --- op_crates/webgpu/01_webgpu.js | 338 +++++++++++++++++++++++++++++----- op_crates/webgpu/buffer.rs | 6 +- 2 files changed, 299 insertions(+), 45 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index bc338cd1a798fc..f72533f67ce735 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -3,6 +3,7 @@ // @ts-check /// /// +/// /// "use strict"; @@ -266,12 +267,30 @@ deviceRid: this[_device].rid, ...descriptor, }); - return new GPUBuffer( - rid, + /** @type {CreateGPUBufferOptions} */ + let options; + if (descriptor.mappedAtCreation) { + options = { + mapping: new ArrayBuffer(descriptor.size), + mappingRange: [0, descriptor.size], + mappedRanges: [], + state: "mapped at creation", + }; + } else { + options = { + mapping: null, + mappedRanges: null, + mappingRange: null, + state: "unmapped", + }; + } + return createGPUBuffer( + descriptor.label ?? null, this[_device].rid, - descriptor.label, + rid, descriptor.size, - descriptor.mappedAtCreation, + descriptor.usage, + options, ); } @@ -721,62 +740,295 @@ const _rid = Symbol("[[rid]]"); + const _size = Symbol("[[size]]"); + const _usage = Symbol("[[usage]]"); + const _state = Symbol("[[state]]"); + const _mappingRange = Symbol("[[mapping_range]]"); + const _mappedRanges = Symbol("[[mapped_ranges]]"); + const _mapMode = Symbol("[[map_mode]]"); + + /** + * @typedef CreateGPUBufferOptions + * @property {ArrayBuffer | null} mapping + * @property {number[] | null} mappingRange + * @property {[ArrayBuffer, number, number][] | null} mappedRanges + * @property {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy" } state + */ + + /** + * @param {string | null} label + * @param {number} deviceRid + * @param {number} rid + * @param {number} size + * @param {number} usage + * @param {CreateGPUBufferOptions} options + * @returns {GPUBuffer} + */ + function createGPUBuffer(label, deviceRid, rid, size, usage, options) { + /** @type {GPUBuffer} */ + const buffer = webidl.createBranded(GPUBuffer); + buffer[_label] = label; + buffer[_device] = deviceRid; + buffer[_rid] = rid; + buffer[_size] = size; + buffer[_usage] = usage; + buffer[_mappingRange] = options.mappingRange; + buffer[_mappedRanges] = options.mappedRanges; + buffer[_state] = options.state; + return buffer; + } + class GPUBuffer { - [webidl.brand] = webidl.brand; + /** @type {number} */ + [_device]; - #deviceRid; - #size; - #mappedSize; - #mappedOffset; - #mappedRid; - #mappedBuffer; - - constructor(rid, deviceRid, label, size, mappedAtCreation) { - this[_rid] = rid; - this.#deviceRid = deviceRid; - this.label = label ?? null; - this.#size = size; - - if (mappedAtCreation) { - this.#mappedSize = size; - this.#mappedOffset = 0; - } + /** @type {number} */ + [_rid]; + + /** @type {number} */ + [_size]; + + /** @type {number} */ + [_usage]; + + /** @type {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy"} */ + [_state]; + + /** @type {[number, number] | null} */ + [_mappingRange]; + + /** @type {[ArrayBuffer, number, number][] | null} */ + [_mappedRanges]; + + /** @type {number} */ + [_mapMode]; + + constructor() { + webidl.illegalConstructor(); } - async mapAsync(mode, offset = 0, size = undefined) { - this.#mappedOffset = offset; - this.#mappedSize = size ?? (this.#size - offset); - await core.jsonOpAsync("op_webgpu_buffer_get_map_async", { - bufferRid: this[_rid], - deviceRid: this.#deviceRid, - mode, - offset, - size: this.#mappedSize, + /** + * @param {number} mode + * @param {number} offset + * @param {number} [size] + */ + async mapAsync(mode, offset = 0, size) { + webidl.assertBranded(this, GPUBuffer); + const prefix = "Failed to execute 'mapAsync' on 'GPUBuffer'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + mode = webidl.converters.GPUMapModeFlags(mode, { + prefix, + context: "Argument 1", }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 2", + }); + size = size === undefined + ? undefined + : webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 3", + }); + /** @type {number} */ + let rangeSize; + if (size === undefined) { + rangeSize = Math.max(0, this[_size] - offset); + } else { + rangeSize = this[_size]; + } + if ((offset % 8) !== 0) { + throw new DOMException( + `${prefix}: offset must be a multiple of 8.`, + "OperationError", + ); + } + if ((rangeSize % 4) !== 0) { + throw new DOMException( + `${prefix}: rangeSize must be a multiple of 4.`, + "OperationError", + ); + } + if ((offset + rangeSize) <= this[_size]) { + throw new DOMException( + `${prefix}: offset + rangeSize must be less or equal to buffer size.`, + "OperationError", + ); + } + if (this[_state] !== "unmapped") { + throw new DOMException( + `${prefix}: GPUBuffer is not currently unmapped.`, + "OperationError", + ); + } + const readMode = (mode & 0x0001) === 0x0001; + const writeMode = (mode & 0x0002) === 0x0002; + if (readMode && writeMode) { + throw new DOMException( + `${prefix}: only one of READ or WRITE map mode may be set.`, + "OperationError", + ); + } + if (readMode && !((this[_usage] && 0x0001) === 0x0001)) { + throw new DOMException( + `${prefix}: READ map mode not valid because buffer does not have MAP_READ usage.`, + "OperationError", + ); + } + if (writeMode && !((this[_usage] && 0x0002) === 0x0002)) { + throw new DOMException( + `${prefix}: WRITE map mode not valid because buffer does not have MAP_WRITE usage.`, + "OperationError", + ); + } + + this[_mapMode] = mode; + this[_state] = "mapping pending"; + await core.jsonOpAsync( + "op_webgpu_buffer_get_map_async", + { + bufferRid: this[_rid], + deviceRid: this[_device], + mode, + offset, + size: rangeSize, + }, + ); + this[_state] = "mapped"; + this[_mappingRange] = [offset, offset + rangeSize]; + /** @type {[ArrayBuffer, number, number][] | null} */ + this[_mappedRanges] = []; } - getMappedRange(offset = 0, size = undefined) { - const buffer = new Uint8Array(size ?? this.#mappedSize); + /** + * @param {number} offset + * @param {number} size + */ + getMappedRange(offset = 0, size) { + webidl.assertBranded(this, GPUBuffer); + const prefix = "Failed to execute 'getMappedRange' on 'GPUBuffer'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 1", + }); + size = size === undefined + ? undefined + : webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 2", + }); + /** @type {number} */ + let rangeSize; + if (size === undefined) { + rangeSize = Math.max(0, this[_size] - offset); + } else { + rangeSize = this[_size]; + } + if (this[_state] !== "mapped" && this[_state] !== "mapped at creation") { + throw new DOMException( + `${prefix}: buffer is not mapped.`, + "OperationError", + ); + } + if ((offset % 8) !== 0) { + throw new DOMException( + `${prefix}: offset must be a multiple of 8.`, + "OperationError", + ); + } + if ((rangeSize % 4) !== 0) { + throw new DOMException( + `${prefix}: rangeSize must be a multiple of 4.`, + "OperationError", + ); + } + const mappingRange = this[_mappingRange]; + if (!mappingRange) { + throw new DOMException(`${prefix}: invalid state.`, "OperationError"); + } + if (offset >= mappingRange[0]) { + throw new DOMException( + `${prefix}: offset is out of bounds.`, + "OperationError", + ); + } + if ((offset + rangeSize) <= mappingRange[1]) { + throw new DOMException( + `${prefix}: offset is out of bounds.`, + "OperationError", + ); + } + const mappedRanges = this[_mappedRanges]; + if (!mappedRanges) { + throw new DOMException(`${prefix}: invalid state.`, "OperationError"); + } + for (const [buffer, _rid, start] of mappedRanges) { + // TODO(lucacasonato): is this logic correct? + const end = start + buffer.byteLength; + if ( + (start >= offset && start < (offset + rangeSize)) || + (end >= offset && end < (offset + rangeSize)) + ) { + throw new DOMException( + `${prefix}: requested buffer overlaps with another mapped range.`, + "OperationError", + ); + } + } + + const buffer = new ArrayBuffer(rangeSize); const { rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { bufferRid: this[_rid], - offset, - size: size ?? this.#mappedSize, + offset: offset - mappingRange[0], + size: rangeSize, }, - buffer, + new Uint8Array(buffer), ); - this.#mappedRid = rid; - this.#mappedBuffer = buffer; - return this.#mappedBuffer.buffer; + mappedRanges.push([buffer, rid, offset]); + + return buffer; } unmap() { - core.jsonOpSync("op_webgpu_buffer_unmap", { - bufferRid: this[_rid], - mappedRid: this.#mappedRid, - }, this.#mappedBuffer); + webidl.assertBranded(this, GPUBuffer); + const prefix = "Failed to execute 'unmap' on 'GPUBuffer'"; + if (this[_state] === "unmapped" || this[_state] === "destroyed") { + throw new DOMException( + `${prefix}: buffer is not ready to be unmapped.`, + "OperationError", + ); + } + if (this[_state] === "mapping pending") { + // TODO(lucacasonato): this is not spec compliant. + throw new DOMException( + `${prefix}: can not unmap while mapping. This is a Deno limitation.`, + "OperationError", + ); + } else if ( + this[_state] === "mapped" || this[_state] === "mapped at creation" + ) { + const mappedRanges = this[_mappedRanges]; + const mapMode = this[_mapMode]; + if (!mappedRanges || !mapMode) { + throw new DOMException(`${prefix}: invalid state.`, "OperationError"); + } + for (const [buffer, rid] of mappedRanges) { + const write = this[_state] === "mapped at creation" || + (this[_state] === "mapped" && (mapMode & 0x0002) === 0x0002); + core.jsonOpSync("op_webgpu_buffer_unmap", { + bufferRid: this[_rid], + mappedRid: rid, + }, ...(write ? [new Uint8Array(buffer)] : [])); + } + this[_mappingRange] = null; + this[_mappedRanges] = null; + } + + this[_state] = "unmapped"; } destroy() { diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 751b0fa823437a..6aa7e37ec96a87 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -234,8 +234,10 @@ pub fn op_webgpu_buffer_unmap( let slice_pointer = mapped_resource.0; let size = mapped_resource.1; - let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) }; - slice.copy_from_slice(&zero_copy[0]); + if let Some(buffer) = zero_copy.get(0) { + let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) }; + slice.copy_from_slice(&buffer); + } gfx_select!(buffer => instance.buffer_unmap(buffer))?; From 52d8cbba80de73bd315f5bc9c2fc7af17c0aa7dc Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 10:17:37 +0100 Subject: [PATCH 106/144] add GPUShaderStage --- runtime/js/99_main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 3371e812685e4a..4e28a11777e1a4 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -268,6 +268,7 @@ delete Object.prototype.__proto__; GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout), GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup), GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), + GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage), GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite), From b7fc5353b23066f67b6fa16d3aa2a9205c54f4aa Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 10:17:37 +0100 Subject: [PATCH 107/144] add GPUShaderStage --- op_crates/webgpu/01_webgpu.js | 35 +++++++++++++++++++++++++++++++++++ runtime/js/99_main.js | 1 + 2 files changed, 36 insertions(+) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index f168cf3c7ebfa8..2aff50e70ab78f 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1183,6 +1183,10 @@ } class GPUBufferUsage { + constructor() { + webidl.illegalConstructor(); + } + static get MAP_READ() { return 0x0001; } @@ -1216,6 +1220,10 @@ } class GPUMapMode { + constructor() { + webidl.illegalConstructor(); + } + static get READ() { return 0x0001; } @@ -1272,6 +1280,10 @@ GPUObjectBaseMixin("GPUTexture", GPUTexture); class GPUTextureUsage { + constructor() { + webidl.illegalConstructor(); + } + static get COPY_SRC() { return 0x01; } @@ -1425,6 +1437,24 @@ } GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); + class GPUShaderStage { + constructor() { + webidl.illegalConstructor(); + } + + static get VERTEX() { + return 0x1; + } + + static get FRAGMENT() { + return 0x2; + } + + static get COMPUTE() { + return 0x4; + } + } + /** * @param {string | null} label * @param {number} rid @@ -1516,6 +1546,10 @@ GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); class GPUColorWrite { + constructor() { + webidl.illegalConstructor(); + } + static get RED() { return 0x1; } @@ -3154,6 +3188,7 @@ GPUPipelineLayout, GPUBindGroup, GPUShaderModule, + GPUShaderStage, GPUComputePipeline, GPURenderPipeline, GPUColorWrite, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 3371e812685e4a..4e28a11777e1a4 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -268,6 +268,7 @@ delete Object.prototype.__proto__; GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout), GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup), GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), + GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage), GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite), From 539e9baa633633960a7355f2e14873b2a9bc6eaa Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 13:44:29 +0100 Subject: [PATCH 108/144] fix --- op_crates/webgpu/01_webgpu.js | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index f168cf3c7ebfa8..1a1e3450f153b7 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -995,9 +995,9 @@ "OperationError", ); } - if ((offset + rangeSize) <= this[_size]) { + if ((offset + rangeSize) > this[_size]) { throw new DOMException( - `${prefix}: offset + rangeSize must be less or equal to buffer size.`, + `${prefix}: offset + rangeSize must be less than or equal to buffer size.`, "OperationError", ); } @@ -1009,9 +1009,9 @@ } const readMode = (mode & 0x0001) === 0x0001; const writeMode = (mode & 0x0002) === 0x0002; - if (readMode && writeMode) { + if ((readMode && writeMode) || (!readMode && !writeMode)) { throw new DOMException( - `${prefix}: only one of READ or WRITE map mode may be set.`, + `${prefix}: exactly one of READ or WRITE map mode must be set.`, "OperationError", ); } @@ -1053,7 +1053,6 @@ getMappedRange(offset = 0, size) { webidl.assertBranded(this, GPUBuffer); const prefix = "Failed to execute 'getMappedRange' on 'GPUBuffer'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); offset = webidl.converters.GPUSize64(offset, { prefix, context: "Argument 1", @@ -1093,13 +1092,13 @@ if (!mappingRange) { throw new DOMException(`${prefix}: invalid state.`, "OperationError"); } - if (offset >= mappingRange[0]) { + if (offset < mappingRange[0]) { throw new DOMException( `${prefix}: offset is out of bounds.`, "OperationError", ); } - if ((offset + rangeSize) <= mappingRange[1]) { + if ((offset + rangeSize) > mappingRange[1]) { throw new DOMException( `${prefix}: offset is out of bounds.`, "OperationError", @@ -1157,14 +1156,28 @@ } else if ( this[_state] === "mapped" || this[_state] === "mapped at creation" ) { + /** @type {boolean} */ + let write = false; + if (this[_state] === "mapped at creation") { + write = true; + } else if (this[_state] === "mapped") { + const mapMode = this[_mapMode]; + if (mapMode === undefined) { + throw new DOMException( + `${prefix}: invalid state.`, + "OperationError", + ); + } + if ((mapMode & 0x0002) === 0x0002) { + write = true; + } + } + const mappedRanges = this[_mappedRanges]; - const mapMode = this[_mapMode]; - if (!mappedRanges || !mapMode) { + if (!mappedRanges) { throw new DOMException(`${prefix}: invalid state.`, "OperationError"); } for (const [buffer, rid] of mappedRanges) { - const write = this[_state] === "mapped at creation" || - (this[_state] === "mapped" && (mapMode & 0x0002) === 0x0002); core.jsonOpSync("op_webgpu_buffer_unmap", { bufferRid: this[_rid], mappedRid: rid, From 6ed1e68fdcc1e7b7808ee7806a3315f984aa1510 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 13:44:35 +0100 Subject: [PATCH 109/144] createSequenceConverter --- op_crates/web/00_webidl.js | 63 +++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/op_crates/web/00_webidl.js b/op_crates/web/00_webidl.js index 5779e4f8f6d821..3b6dc8749482bb 100644 --- a/op_crates/web/00_webidl.js +++ b/op_crates/web/00_webidl.js @@ -698,12 +698,57 @@ }; } - function illegalConstructor() { - throw new TypeError("Illegal constructor"); + // https://heycam.github.io/webidl/#es-sequence + function createSequenceConverter(converter) { + return function (V, opts = {}) { + if (typeof V !== "object") { + throw makeException( + TypeError, + "can not be converted to sequence.", + opts, + ); + } + const method = V?.[Symbol.iterator]; + if (method === undefined) { + throw makeException( + TypeError, + "can not be converted to sequence.", + opts, + ); + } + const iter = method(); + const array = []; + while (true) { + const res = iter?.next?.(); + if (res === undefined) { + throw makeException( + TypeError, + "can not be converted to sequence.", + opts, + ); + } + if (res.done === true) break; + const val = converter(val, { + ...opts, + context: `${opts.context}, index ${array.length}`, + }); + array.push(val); + } + return array; + }; } const brand = Symbol("[[webidl.brand]]"); + function createInterfaceConverter(name, prototype) { + return (V, opts) => { + if (!(V instanceof prototype) || V[brand] !== brand) { + throw makeException(TypeError, `is not of type ${name}.`, opts); + } + return V; + }; + } + function createBranded(Type) { const t = Object.create(Type.prototype); t[brand] = brand; @@ -716,13 +761,8 @@ } } - function createInterfaceConverter(name, prototype) { - return (V, opts) => { - if (!(V instanceof prototype) || V[brand] !== brand) { - throw makeException(TypeError, `is not of type ${name}.`, opts); - } - return V; - }; + function illegalConstructor() { + throw new TypeError("Illegal constructor"); } window.__bootstrap ??= {}; @@ -732,10 +772,11 @@ createDictionaryConverter, createEnumConverter, createNullableConverter, - illegalConstructor, + createSequenceConverter, + createInterfaceConverter, brand, createBranded, assertBranded, - createInterfaceConverter, + illegalConstructor, }; })(this); From 12cd525eeb2145c14f4517e307235354adeed07d Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 14:06:44 +0100 Subject: [PATCH 110/144] change args to use structs --- op_crates/webgpu/binding.rs | 20 ++--- op_crates/webgpu/buffer.rs | 26 ++---- op_crates/webgpu/bundle.rs | 79 ++++++------------ op_crates/webgpu/command_encoder.rs | 86 +++++++------------ op_crates/webgpu/compute_pass.rs | 70 ++++++---------- op_crates/webgpu/lib.rs | 20 ++--- op_crates/webgpu/pipeline.rs | 28 ++----- op_crates/webgpu/queue.rs | 20 ++--- op_crates/webgpu/render_pass.rs | 124 +++++++++------------------- op_crates/webgpu/sampler.rs | 8 +- op_crates/webgpu/shader.rs | 8 +- op_crates/webgpu/texture.rs | 14 ++-- 12 files changed, 167 insertions(+), 336 deletions(-) diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index 994f193e7f3850..0602e3c73d7c7b 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -70,7 +70,7 @@ struct GPUBindGroupLayoutEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateBindGroupLayoutArgs { +pub struct CreateBindGroupLayoutArgs { device_rid: u32, label: Option, entries: Vec, @@ -78,11 +78,9 @@ struct CreateBindGroupLayoutArgs { pub fn op_webgpu_create_bind_group_layout( state: &mut OpState, - args: Value, + args: CreateBindGroupLayoutArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateBindGroupLayoutArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -213,7 +211,7 @@ pub fn op_webgpu_create_bind_group_layout( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreatePipelineLayoutArgs { +pub struct CreatePipelineLayoutArgs { device_rid: u32, label: Option, bind_group_layouts: Vec, @@ -221,11 +219,9 @@ struct CreatePipelineLayoutArgs { pub fn op_webgpu_create_pipeline_layout( state: &mut OpState, - args: Value, + args: CreatePipelineLayoutArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreatePipelineLayoutArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -276,7 +272,7 @@ struct GPUBindGroupEntry { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateBindGroupArgs { +pub struct CreateBindGroupArgs { device_rid: u32, label: Option, layout: u32, @@ -285,11 +281,9 @@ struct CreateBindGroupArgs { pub fn op_webgpu_create_bind_group( state: &mut OpState, - args: Value, + args: CreateBindGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateBindGroupArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 6aa7e37ec96a87..2d1899b10c6624 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -6,7 +6,7 @@ use deno_core::futures::channel::oneshot; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -30,7 +30,7 @@ impl Resource for WebGPUBufferMapped { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateBufferArgs { +pub struct CreateBufferArgs { device_rid: u32, label: Option, size: u64, @@ -40,11 +40,9 @@ struct CreateBufferArgs { pub fn op_webgpu_create_buffer( state: &mut OpState, - args: Value, + args: CreateBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateBufferArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -74,7 +72,7 @@ pub fn op_webgpu_create_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct BufferGetMapAsyncArgs { +pub struct BufferGetMapAsyncArgs { buffer_rid: u32, device_rid: u32, mode: u32, @@ -84,11 +82,9 @@ struct BufferGetMapAsyncArgs { pub async fn op_webgpu_buffer_get_map_async( state: Rc>, - args: Value, + args: BufferGetMapAsyncArgs, _bufs: BufVec, ) -> Result { - let args: BufferGetMapAsyncArgs = serde_json::from_value(args)?; - let (sender, receiver) = oneshot::channel::>(); let device; @@ -166,7 +162,7 @@ pub async fn op_webgpu_buffer_get_map_async( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct BufferGetMappedRangeArgs { +pub struct BufferGetMappedRangeArgs { buffer_rid: u32, offset: u64, size: u64, @@ -174,11 +170,9 @@ struct BufferGetMappedRangeArgs { pub fn op_webgpu_buffer_get_mapped_range( state: &mut OpState, - args: Value, + args: BufferGetMappedRangeArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: BufferGetMappedRangeArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let buffer_resource = state .resource_table @@ -208,18 +202,16 @@ pub fn op_webgpu_buffer_get_mapped_range( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct BufferUnmapArgs { +pub struct BufferUnmapArgs { buffer_rid: u32, mapped_rid: u32, } pub fn op_webgpu_buffer_unmap( state: &mut OpState, - args: Value, + args: BufferUnmapArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: BufferUnmapArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let buffer_resource = state .resource_table diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index a27d7c8fe1b46e..424bb628edd186 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -31,7 +31,7 @@ impl Resource for WebGPURenderBundle { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateRenderBundleEncoderArgs { +pub struct CreateRenderBundleEncoderArgs { device_rid: u32, label: Option, color_formats: Vec, @@ -41,11 +41,9 @@ struct CreateRenderBundleEncoderArgs { pub fn op_webgpu_create_render_bundle_encoder( state: &mut OpState, - args: Value, + args: CreateRenderBundleEncoderArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateRenderBundleEncoderArgs = serde_json::from_value(args)?; - let device_resource = state .resource_table .get::(args.device_rid) @@ -83,18 +81,16 @@ pub fn op_webgpu_create_render_bundle_encoder( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderFinishArgs { +pub struct RenderBundleEncoderFinishArgs { render_bundle_encoder_rid: u32, label: Option, } pub fn op_webgpu_render_bundle_encoder_finish( state: &mut OpState, - args: Value, + args: RenderBundleEncoderFinishArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderFinishArgs = serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .take::(args.render_bundle_encoder_rid) @@ -123,7 +119,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderSetBindGroupArgs { +pub struct RenderBundleEncoderSetBindGroupArgs { render_bundle_encoder_rid: u32, index: u32, bind_group: u32, @@ -134,11 +130,9 @@ struct RenderBundleEncoderSetBindGroupArgs { pub fn op_webgpu_render_bundle_encoder_set_bind_group( state: &mut OpState, - args: Value, + args: RenderBundleEncoderSetBindGroupArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_resource = state .resource_table .get::(args.bind_group) @@ -184,19 +178,16 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderPushDebugGroupArgs { +pub struct RenderBundleEncoderPushDebugGroupArgs { render_bundle_encoder_rid: u32, group_label: String, } pub fn op_webgpu_render_bundle_encoder_push_debug_group( state: &mut OpState, - args: Value, + args: RenderBundleEncoderPushDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderPushDebugGroupArgs = - serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .get::(args.render_bundle_encoder_rid) @@ -215,18 +206,15 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderPopDebugGroupArgs { +pub struct RenderBundleEncoderPopDebugGroupArgs { render_bundle_encoder_rid: u32, } pub fn op_webgpu_render_bundle_encoder_pop_debug_group( state: &mut OpState, - args: Value, + args: RenderBundleEncoderPopDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderPopDebugGroupArgs = - serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .get::(args.render_bundle_encoder_rid) @@ -243,19 +231,16 @@ pub fn op_webgpu_render_bundle_encoder_pop_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderInsertDebugMarkerArgs { +pub struct RenderBundleEncoderInsertDebugMarkerArgs { render_bundle_encoder_rid: u32, marker_label: String, } pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( state: &mut OpState, - args: Value, + args: RenderBundleEncoderInsertDebugMarkerArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderInsertDebugMarkerArgs = - serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .get::(args.render_bundle_encoder_rid) @@ -274,18 +259,16 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderSetPipelineArgs { +pub struct RenderBundleEncoderSetPipelineArgs { render_bundle_encoder_rid: u32, pipeline: u32, } pub fn op_webgpu_render_bundle_encoder_set_pipeline( state: &mut OpState, - args: Value, + args: RenderBundleEncoderSetPipelineArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderSetPipelineArgs = serde_json::from_value(args)?; - let render_pipeline_resource = state .resource_table .get::(args.pipeline) @@ -305,7 +288,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderSetIndexBufferArgs { +pub struct RenderBundleEncoderSetIndexBufferArgs { render_bundle_encoder_rid: u32, buffer: u32, index_format: String, @@ -315,12 +298,9 @@ struct RenderBundleEncoderSetIndexBufferArgs { pub fn op_webgpu_render_bundle_encoder_set_index_buffer( state: &mut OpState, - args: Value, + args: RenderBundleEncoderSetIndexBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderSetIndexBufferArgs = - serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.buffer) @@ -345,7 +325,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderSetVertexBufferArgs { +pub struct RenderBundleEncoderSetVertexBufferArgs { render_bundle_encoder_rid: u32, slot: u32, buffer: u32, @@ -355,12 +335,9 @@ struct RenderBundleEncoderSetVertexBufferArgs { pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( state: &mut OpState, - args: Value, + args: RenderBundleEncoderSetVertexBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderSetVertexBufferArgs = - serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.buffer) @@ -383,7 +360,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderDrawArgs { +pub struct RenderBundleEncoderDrawArgs { render_bundle_encoder_rid: u32, vertex_count: u32, instance_count: u32, @@ -393,11 +370,9 @@ struct RenderBundleEncoderDrawArgs { pub fn op_webgpu_render_bundle_encoder_draw( state: &mut OpState, - args: Value, + args: RenderBundleEncoderDrawArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderDrawArgs = serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .get::(args.render_bundle_encoder_rid) @@ -416,7 +391,7 @@ pub fn op_webgpu_render_bundle_encoder_draw( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderDrawIndexedArgs { +pub struct RenderBundleEncoderDrawIndexedArgs { render_bundle_encoder_rid: u32, index_count: u32, instance_count: u32, @@ -427,11 +402,9 @@ struct RenderBundleEncoderDrawIndexedArgs { pub fn op_webgpu_render_bundle_encoder_draw_indexed( state: &mut OpState, - args: Value, + args: RenderBundleEncoderDrawIndexedArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderDrawIndexedArgs = serde_json::from_value(args)?; - let render_bundle_encoder_resource = state .resource_table .get::(args.render_bundle_encoder_rid) @@ -451,7 +424,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderBundleEncoderDrawIndirectArgs { +pub struct RenderBundleEncoderDrawIndirectArgs { render_bundle_encoder_rid: u32, indirect_buffer: u32, indirect_offset: u64, @@ -459,11 +432,9 @@ struct RenderBundleEncoderDrawIndirectArgs { pub fn op_webgpu_render_bundle_encoder_draw_indirect( state: &mut OpState, - args: Value, + args: RenderBundleEncoderDrawIndirectArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderBundleEncoderDrawIndirectArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.indirect_buffer) diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index a23b44c4d8c107..cf02d57369d075 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -38,7 +38,7 @@ fn serialize_store_op(store_op: String) -> wgpu_core::command::StoreOp { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateCommandEncoderArgs { +pub struct CreateCommandEncoderArgs { device_rid: u32, label: Option, _measure_execution_time: Option, // not yet implemented @@ -46,11 +46,9 @@ struct CreateCommandEncoderArgs { pub fn op_webgpu_create_command_encoder( state: &mut OpState, - args: Value, + args: CreateCommandEncoderArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateCommandEncoderArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -79,7 +77,7 @@ pub fn op_webgpu_create_command_encoder( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct GPURenderPassColorAttachment { +pub struct GPURenderPassColorAttachment { view: u32, resolve_target: Option, load_op: String, @@ -103,7 +101,7 @@ struct GPURenderPassDepthStencilAttachment { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderBeginRenderPassArgs { +pub struct CommandEncoderBeginRenderPassArgs { command_encoder_rid: u32, label: Option, color_attachments: Vec, @@ -113,11 +111,9 @@ struct CommandEncoderBeginRenderPassArgs { pub fn op_webgpu_command_encoder_begin_render_pass( state: &mut OpState, - args: Value, + args: CommandEncoderBeginRenderPassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderBeginRenderPassArgs = serde_json::from_value(args)?; - let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -243,18 +239,16 @@ pub fn op_webgpu_command_encoder_begin_render_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderBeginComputePassArgs { +pub struct CommandEncoderBeginComputePassArgs { command_encoder_rid: u32, label: Option, } pub fn op_webgpu_command_encoder_begin_compute_pass( state: &mut OpState, - args: Value, + args: CommandEncoderBeginComputePassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderBeginComputePassArgs = serde_json::from_value(args)?; - let command_encoder_resource = state .resource_table .get::(args.command_encoder_rid) @@ -282,7 +276,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderCopyBufferToBufferArgs { +pub struct CommandEncoderCopyBufferToBufferArgs { command_encoder_rid: u32, source: u32, source_offset: u64, @@ -293,12 +287,9 @@ struct CommandEncoderCopyBufferToBufferArgs { pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( state: &mut OpState, - args: Value, + args: CommandEncoderCopyBufferToBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderCopyBufferToBufferArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -356,7 +347,7 @@ pub struct GPUImageCopyTexture { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderCopyBufferToTextureArgs { +pub struct CommandEncoderCopyBufferToTextureArgs { command_encoder_rid: u32, source: GPUImageCopyBuffer, destination: GPUImageCopyTexture, @@ -365,12 +356,9 @@ struct CommandEncoderCopyBufferToTextureArgs { pub fn op_webgpu_command_encoder_copy_buffer_to_texture( state: &mut OpState, - args: Value, + args: CommandEncoderCopyBufferToTextureArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderCopyBufferToTextureArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -422,7 +410,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderCopyTextureToBufferArgs { +pub struct CommandEncoderCopyTextureToBufferArgs { command_encoder_rid: u32, source: GPUImageCopyTexture, destination: GPUImageCopyBuffer, @@ -431,12 +419,9 @@ struct CommandEncoderCopyTextureToBufferArgs { pub fn op_webgpu_command_encoder_copy_texture_to_buffer( state: &mut OpState, - args: Value, + args: CommandEncoderCopyTextureToBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderCopyTextureToBufferArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -487,7 +472,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderCopyTextureToTextureArgs { +pub struct CommandEncoderCopyTextureToTextureArgs { command_encoder_rid: u32, source: GPUImageCopyTexture, destination: GPUImageCopyTexture, @@ -496,12 +481,9 @@ struct CommandEncoderCopyTextureToTextureArgs { pub fn op_webgpu_command_encoder_copy_texture_to_texture( state: &mut OpState, - args: Value, + args: CommandEncoderCopyTextureToTextureArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderCopyTextureToTextureArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -556,18 +538,16 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderPushDebugGroupArgs { +pub struct CommandEncoderPushDebugGroupArgs { command_encoder_rid: u32, group_label: String, } pub fn op_webgpu_command_encoder_push_debug_group( state: &mut OpState, - args: Value, + args: CommandEncoderPushDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderPushDebugGroupArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -583,17 +563,15 @@ pub fn op_webgpu_command_encoder_push_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderPopDebugGroupArgs { +pub struct CommandEncoderPopDebugGroupArgs { command_encoder_rid: u32, } pub fn op_webgpu_command_encoder_pop_debug_group( state: &mut OpState, - args: Value, + args: CommandEncoderPopDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderPopDebugGroupArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -608,18 +586,16 @@ pub fn op_webgpu_command_encoder_pop_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderInsertDebugMarkerArgs { +pub struct CommandEncoderInsertDebugMarkerArgs { command_encoder_rid: u32, marker_label: String, } pub fn op_webgpu_command_encoder_insert_debug_marker( state: &mut OpState, - args: Value, + args: CommandEncoderInsertDebugMarkerArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderInsertDebugMarkerArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -637,7 +613,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderWriteTimestampArgs { +pub struct CommandEncoderWriteTimestampArgs { command_encoder_rid: u32, query_set: u32, query_index: u32, @@ -645,11 +621,9 @@ struct CommandEncoderWriteTimestampArgs { pub fn op_webgpu_command_encoder_write_timestamp( state: &mut OpState, - args: Value, + args: CommandEncoderWriteTimestampArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderWriteTimestampArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -672,7 +646,7 @@ pub fn op_webgpu_command_encoder_write_timestamp( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderResolveQuerySetArgs { +pub struct CommandEncoderResolveQuerySetArgs { command_encoder_rid: u32, query_set: u32, first_query: u32, @@ -683,11 +657,9 @@ struct CommandEncoderResolveQuerySetArgs { pub fn op_webgpu_command_encoder_resolve_query_set( state: &mut OpState, - args: Value, + args: CommandEncoderResolveQuerySetArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderResolveQuerySetArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -717,18 +689,16 @@ pub fn op_webgpu_command_encoder_resolve_query_set( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CommandEncoderFinishArgs { +pub struct CommandEncoderFinishArgs { command_encoder_rid: u32, label: Option, } pub fn op_webgpu_command_encoder_finish( state: &mut OpState, - args: Value, + args: CommandEncoderFinishArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CommandEncoderFinishArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 6c9235abd69e49..6ebaafa16c0fc8 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -21,18 +21,16 @@ impl Resource for WebGPUComputePass { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassSetPipelineArgs { +pub struct ComputePassSetPipelineArgs { compute_pass_rid: u32, pipeline: u32, } pub fn op_webgpu_compute_pass_set_pipeline( state: &mut OpState, - args: Value, + args: ComputePassSetPipelineArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassSetPipelineArgs = serde_json::from_value(args)?; - let compute_pipeline_resource = state .resource_table .get::(args.pipeline) @@ -52,7 +50,7 @@ pub fn op_webgpu_compute_pass_set_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassDispatchArgs { +pub struct ComputePassDispatchArgs { compute_pass_rid: u32, x: u32, y: u32, @@ -61,11 +59,9 @@ struct ComputePassDispatchArgs { pub fn op_webgpu_compute_pass_dispatch( state: &mut OpState, - args: Value, + args: ComputePassDispatchArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassDispatchArgs = serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -83,7 +79,7 @@ pub fn op_webgpu_compute_pass_dispatch( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassDispatchIndirectArgs { +pub struct ComputePassDispatchIndirectArgs { compute_pass_rid: u32, indirect_buffer: u32, indirect_offset: u64, @@ -91,11 +87,9 @@ struct ComputePassDispatchIndirectArgs { pub fn op_webgpu_compute_pass_dispatch_indirect( state: &mut OpState, - args: Value, + args: ComputePassDispatchIndirectArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassDispatchIndirectArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.indirect_buffer) @@ -116,7 +110,7 @@ pub fn op_webgpu_compute_pass_dispatch_indirect( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassBeginPipelineStatisticsQueryArgs { +pub struct ComputePassBeginPipelineStatisticsQueryArgs { compute_pass_rid: u32, query_set: u32, query_index: u32, @@ -124,12 +118,9 @@ struct ComputePassBeginPipelineStatisticsQueryArgs { pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( state: &mut OpState, - args: Value, + args: ComputePassBeginPipelineStatisticsQueryArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassBeginPipelineStatisticsQueryArgs = - serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -152,18 +143,15 @@ pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassEndPipelineStatisticsQueryArgs { +pub struct ComputePassEndPipelineStatisticsQueryArgs { compute_pass_rid: u32, } pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( state: &mut OpState, - args: Value, + args: ComputePassEndPipelineStatisticsQueryArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassEndPipelineStatisticsQueryArgs = - serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -180,7 +168,7 @@ pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassWriteTimestampArgs { +pub struct ComputePassWriteTimestampArgs { compute_pass_rid: u32, query_set: u32, query_index: u32, @@ -188,11 +176,9 @@ struct ComputePassWriteTimestampArgs { pub fn op_webgpu_compute_pass_write_timestamp( state: &mut OpState, - args: Value, + args: ComputePassWriteTimestampArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassWriteTimestampArgs = serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -215,18 +201,16 @@ pub fn op_webgpu_compute_pass_write_timestamp( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassEndPassArgs { +pub struct ComputePassEndPassArgs { command_encoder_rid: u32, compute_pass_rid: u32, } pub fn op_webgpu_compute_pass_end_pass( state: &mut OpState, - args: Value, + args: ComputePassEndPassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassEndPassArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -251,7 +235,7 @@ pub fn op_webgpu_compute_pass_end_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassSetBindGroupArgs { +pub struct ComputePassSetBindGroupArgs { compute_pass_rid: u32, index: u32, bind_group: u32, @@ -262,11 +246,9 @@ struct ComputePassSetBindGroupArgs { pub fn op_webgpu_compute_pass_set_bind_group( state: &mut OpState, - args: Value, + args: ComputePassSetBindGroupArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_resource = state .resource_table .get::(args.bind_group) @@ -299,18 +281,16 @@ pub fn op_webgpu_compute_pass_set_bind_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassPushDebugGroupArgs { +pub struct ComputePassPushDebugGroupArgs { compute_pass_rid: u32, group_label: String, } pub fn op_webgpu_compute_pass_push_debug_group( state: &mut OpState, - args: Value, + args: ComputePassPushDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassPushDebugGroupArgs = serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -330,17 +310,15 @@ pub fn op_webgpu_compute_pass_push_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassPopDebugGroupArgs { +pub struct ComputePassPopDebugGroupArgs { compute_pass_rid: u32, } pub fn op_webgpu_compute_pass_pop_debug_group( state: &mut OpState, - args: Value, + args: ComputePassPopDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassPopDebugGroupArgs = serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) @@ -355,18 +333,16 @@ pub fn op_webgpu_compute_pass_pop_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePassInsertDebugMarkerArgs { +pub struct ComputePassInsertDebugMarkerArgs { compute_pass_rid: u32, marker_label: String, } pub fn op_webgpu_compute_pass_insert_debug_marker( state: &mut OpState, - args: Value, + args: ComputePassInsertDebugMarkerArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePassInsertDebugMarkerArgs = serde_json::from_value(args)?; - let compute_pass_resource = state .resource_table .get::(args.compute_pass_rid) diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index ddf09e358a0f01..830171a552c9ff 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -7,7 +7,7 @@ use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{BufVec, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -195,17 +195,15 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&str> { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RequestAdapterArgs { +pub struct RequestAdapterArgs { power_preference: Option, } pub async fn op_webgpu_request_adapter( state: Rc>, - args: Value, + args: RequestAdapterArgs, _bufs: BufVec, ) -> Result { - let args: RequestAdapterArgs = serde_json::from_value(args)?; - let mut state = state.borrow_mut(); check_unstable(&state, "navigator.gpu.requestAdapter"); let instance = state.borrow::(); @@ -289,7 +287,7 @@ struct GPULimits { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RequestDeviceArgs { +pub struct RequestDeviceArgs { adapter_rid: u32, label: Option, non_guaranteed_features: Option>, @@ -298,11 +296,9 @@ struct RequestDeviceArgs { pub async fn op_webgpu_request_device( state: Rc>, - args: Value, + args: RequestDeviceArgs, _bufs: BufVec, ) -> Result { - let args: RequestDeviceArgs = serde_json::from_value(args)?; - let mut state = state.borrow_mut(); let adapter_resource = state .resource_table @@ -459,7 +455,7 @@ pub async fn op_webgpu_request_device( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateQuerySetArgs { +pub struct CreateQuerySetArgs { device_rid: u32, _label: Option, // not yet implemented #[serde(rename = "type")] @@ -470,11 +466,9 @@ struct CreateQuerySetArgs { pub fn op_webgpu_create_query_set( state: &mut OpState, - args: Value, + args: CreateQuerySetArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateQuerySetArgs = serde_json::from_value(args)?; - let device_resource = state .resource_table .get::(args.device_rid) diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 811eb9097dc7b4..83342b2e8d4b7b 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -149,7 +149,7 @@ struct GPUProgrammableStage { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateComputePipelineArgs { +pub struct CreateComputePipelineArgs { device_rid: u32, label: Option, layout: Option, @@ -158,11 +158,9 @@ struct CreateComputePipelineArgs { pub fn op_webgpu_create_compute_pipeline( state: &mut OpState, - args: Value, + args: CreateComputePipelineArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateComputePipelineArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -223,19 +221,16 @@ pub fn op_webgpu_create_compute_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct ComputePipelineGetBindGroupLayoutArgs { +pub struct ComputePipelineGetBindGroupLayoutArgs { compute_pipeline_rid: u32, index: u32, } pub fn op_webgpu_compute_pipeline_get_bind_group_layout( state: &mut OpState, - args: Value, + args: ComputePipelineGetBindGroupLayoutArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: ComputePipelineGetBindGroupLayoutArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let compute_pipeline_resource = state .resource_table @@ -356,7 +351,7 @@ struct GPUFragmentState { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateRenderPipelineArgs { +pub struct CreateRenderPipelineArgs { device_rid: u32, label: Option, layout: Option, @@ -369,11 +364,9 @@ struct CreateRenderPipelineArgs { pub fn op_webgpu_create_render_pipeline( state: &mut OpState, - args: Value, + args: CreateRenderPipelineArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateRenderPipelineArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -620,19 +613,16 @@ pub fn op_webgpu_create_render_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPipelineGetBindGroupLayoutArgs { +pub struct RenderPipelineGetBindGroupLayoutArgs { render_pipeline_rid: u32, index: u32, } pub fn op_webgpu_render_pipeline_get_bind_group_layout( state: &mut OpState, - args: Value, + args: RenderPipelineGetBindGroupLayoutArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPipelineGetBindGroupLayoutArgs = - serde_json::from_value(args)?; - let instance = state.borrow::(); let render_pipeline_resource = state .resource_table diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index e2509b1f4eaf31..b1c9eab6b2cb38 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -5,25 +5,23 @@ use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::OpState; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use serde::Deserialize; type WebGPUQueue = super::WebGPUDevice; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct QueueSubmitArgs { +pub struct QueueSubmitArgs { queue_rid: u32, command_buffers: Vec, } pub fn op_webgpu_queue_submit( state: &mut OpState, - args: Value, + args: QueueSubmitArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: QueueSubmitArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let queue_resource = state .resource_table @@ -56,7 +54,7 @@ struct GPUImageDataLayout { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct QueueWriteBufferArgs { +pub struct QueueWriteBufferArgs { queue_rid: u32, buffer: u32, buffer_offset: u64, @@ -66,11 +64,9 @@ struct QueueWriteBufferArgs { pub fn op_webgpu_write_buffer( state: &mut OpState, - args: Value, + args: QueueWriteBufferArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: QueueWriteBufferArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let buffer_resource = state .resource_table @@ -99,7 +95,7 @@ pub fn op_webgpu_write_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct QueueWriteTextureArgs { +pub struct QueueWriteTextureArgs { queue_rid: u32, destination: super::command_encoder::GPUImageCopyTexture, data_layout: GPUImageDataLayout, @@ -108,11 +104,9 @@ struct QueueWriteTextureArgs { pub fn op_webgpu_write_texture( state: &mut OpState, - args: Value, + args: QueueWriteTextureArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: QueueWriteTextureArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let texture_resource = state .resource_table diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 1d21fba9f59e70..3861df1485e6a7 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -21,7 +21,7 @@ impl Resource for WebGPURenderPass { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetViewportArgs { +pub struct RenderPassSetViewportArgs { render_pass_rid: u32, x: f32, y: f32, @@ -33,11 +33,9 @@ struct RenderPassSetViewportArgs { pub fn op_webgpu_render_pass_set_viewport( state: &mut OpState, - args: Value, + args: RenderPassSetViewportArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetViewportArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -58,7 +56,7 @@ pub fn op_webgpu_render_pass_set_viewport( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetScissorRectArgs { +pub struct RenderPassSetScissorRectArgs { render_pass_rid: u32, x: u32, y: u32, @@ -68,11 +66,9 @@ struct RenderPassSetScissorRectArgs { pub fn op_webgpu_render_pass_set_scissor_rect( state: &mut OpState, - args: Value, + args: RenderPassSetScissorRectArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetScissorRectArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -100,18 +96,16 @@ pub struct GPUColor { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetBlendColorArgs { +pub struct RenderPassSetBlendColorArgs { render_pass_rid: u32, color: GPUColor, } pub fn op_webgpu_render_pass_set_blend_color( state: &mut OpState, - args: Value, + args: RenderPassSetBlendColorArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetBlendColorArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -132,18 +126,16 @@ pub fn op_webgpu_render_pass_set_blend_color( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetStencilReferenceArgs { +pub struct RenderPassSetStencilReferenceArgs { render_pass_rid: u32, reference: u32, } pub fn op_webgpu_render_pass_set_stencil_reference( state: &mut OpState, - args: Value, + args: RenderPassSetStencilReferenceArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetStencilReferenceArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -159,7 +151,7 @@ pub fn op_webgpu_render_pass_set_stencil_reference( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassBeginPipelineStatisticsQueryArgs { +pub struct RenderPassBeginPipelineStatisticsQueryArgs { render_pass_rid: u32, query_set: u32, query_index: u32, @@ -167,12 +159,9 @@ struct RenderPassBeginPipelineStatisticsQueryArgs { pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( state: &mut OpState, - args: Value, + args: RenderPassBeginPipelineStatisticsQueryArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassBeginPipelineStatisticsQueryArgs = - serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -195,18 +184,15 @@ pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassEndPipelineStatisticsQueryArgs { +pub struct RenderPassEndPipelineStatisticsQueryArgs { render_pass_rid: u32, } pub fn op_webgpu_render_pass_end_pipeline_statistics_query( state: &mut OpState, - args: Value, + args: RenderPassEndPipelineStatisticsQueryArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassEndPipelineStatisticsQueryArgs = - serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -223,7 +209,7 @@ pub fn op_webgpu_render_pass_end_pipeline_statistics_query( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassWriteTimestampArgs { +pub struct RenderPassWriteTimestampArgs { render_pass_rid: u32, query_set: u32, query_index: u32, @@ -231,11 +217,9 @@ struct RenderPassWriteTimestampArgs { pub fn op_webgpu_render_pass_write_timestamp( state: &mut OpState, - args: Value, + args: RenderPassWriteTimestampArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassWriteTimestampArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -258,18 +242,16 @@ pub fn op_webgpu_render_pass_write_timestamp( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassExecuteBundlesArgs { +pub struct RenderPassExecuteBundlesArgs { render_pass_rid: u32, bundles: Vec, } pub fn op_webgpu_render_pass_execute_bundles( state: &mut OpState, - args: Value, + args: RenderPassExecuteBundlesArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassExecuteBundlesArgs = serde_json::from_value(args)?; - let mut render_bundle_ids = vec![]; for rid in &args.bundles { @@ -298,18 +280,16 @@ pub fn op_webgpu_render_pass_execute_bundles( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassEndPassArgs { +pub struct RenderPassEndPassArgs { command_encoder_rid: u32, render_pass_rid: u32, } pub fn op_webgpu_render_pass_end_pass( state: &mut OpState, - args: Value, + args: RenderPassEndPassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassEndPassArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let command_encoder_resource = state .resource_table @@ -331,7 +311,7 @@ pub fn op_webgpu_render_pass_end_pass( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetBindGroupArgs { +pub struct RenderPassSetBindGroupArgs { render_pass_rid: u32, index: u32, bind_group: u32, @@ -342,11 +322,9 @@ struct RenderPassSetBindGroupArgs { pub fn op_webgpu_render_pass_set_bind_group( state: &mut OpState, - args: Value, + args: RenderPassSetBindGroupArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetBindGroupArgs = serde_json::from_value(args)?; - let bind_group_resource = state .resource_table .get::(args.bind_group) @@ -392,18 +370,16 @@ pub fn op_webgpu_render_pass_set_bind_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassPushDebugGroupArgs { +pub struct RenderPassPushDebugGroupArgs { render_pass_rid: u32, group_label: String, } pub fn op_webgpu_render_pass_push_debug_group( state: &mut OpState, - args: Value, + args: RenderPassPushDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassPushDebugGroupArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -423,17 +399,15 @@ pub fn op_webgpu_render_pass_push_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassPopDebugGroupArgs { +pub struct RenderPassPopDebugGroupArgs { render_pass_rid: u32, } pub fn op_webgpu_render_pass_pop_debug_group( state: &mut OpState, - args: Value, + args: RenderPassPopDebugGroupArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassPopDebugGroupArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -448,18 +422,16 @@ pub fn op_webgpu_render_pass_pop_debug_group( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassInsertDebugMarkerArgs { +pub struct RenderPassInsertDebugMarkerArgs { render_pass_rid: u32, marker_label: String, } pub fn op_webgpu_render_pass_insert_debug_marker( state: &mut OpState, - args: Value, + args: RenderPassInsertDebugMarkerArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassInsertDebugMarkerArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -479,18 +451,16 @@ pub fn op_webgpu_render_pass_insert_debug_marker( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetPipelineArgs { +pub struct RenderPassSetPipelineArgs { render_pass_rid: u32, pipeline: u32, } pub fn op_webgpu_render_pass_set_pipeline( state: &mut OpState, - args: Value, + args: RenderPassSetPipelineArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetPipelineArgs = serde_json::from_value(args)?; - let render_pipeline_resource = state .resource_table .get::(args.pipeline) @@ -510,7 +480,7 @@ pub fn op_webgpu_render_pass_set_pipeline( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetIndexBufferArgs { +pub struct RenderPassSetIndexBufferArgs { render_pass_rid: u32, buffer: u32, index_format: String, @@ -520,11 +490,9 @@ struct RenderPassSetIndexBufferArgs { pub fn op_webgpu_render_pass_set_index_buffer( state: &mut OpState, - args: Value, + args: RenderPassSetIndexBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetIndexBufferArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.buffer) @@ -546,7 +514,7 @@ pub fn op_webgpu_render_pass_set_index_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassSetVertexBufferArgs { +pub struct RenderPassSetVertexBufferArgs { render_pass_rid: u32, slot: u32, buffer: u32, @@ -556,11 +524,9 @@ struct RenderPassSetVertexBufferArgs { pub fn op_webgpu_render_pass_set_vertex_buffer( state: &mut OpState, - args: Value, + args: RenderPassSetVertexBufferArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassSetVertexBufferArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.buffer) @@ -583,7 +549,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassDrawArgs { +pub struct RenderPassDrawArgs { render_pass_rid: u32, vertex_count: u32, instance_count: u32, @@ -593,11 +559,9 @@ struct RenderPassDrawArgs { pub fn op_webgpu_render_pass_draw( state: &mut OpState, - args: Value, + args: RenderPassDrawArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassDrawArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -616,7 +580,7 @@ pub fn op_webgpu_render_pass_draw( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassDrawIndexedArgs { +pub struct RenderPassDrawIndexedArgs { render_pass_rid: u32, index_count: u32, instance_count: u32, @@ -627,11 +591,9 @@ struct RenderPassDrawIndexedArgs { pub fn op_webgpu_render_pass_draw_indexed( state: &mut OpState, - args: Value, + args: RenderPassDrawIndexedArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassDrawIndexedArgs = serde_json::from_value(args)?; - let render_pass_resource = state .resource_table .get::(args.render_pass_rid) @@ -651,7 +613,7 @@ pub fn op_webgpu_render_pass_draw_indexed( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassDrawIndirectArgs { +pub struct RenderPassDrawIndirectArgs { render_pass_rid: u32, indirect_buffer: u32, indirect_offset: u64, @@ -659,11 +621,9 @@ struct RenderPassDrawIndirectArgs { pub fn op_webgpu_render_pass_draw_indirect( state: &mut OpState, - args: Value, + args: RenderPassDrawIndirectArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassDrawIndirectArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.indirect_buffer) @@ -684,7 +644,7 @@ pub fn op_webgpu_render_pass_draw_indirect( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct RenderPassDrawIndexedIndirectArgs { +pub struct RenderPassDrawIndexedIndirectArgs { render_pass_rid: u32, indirect_buffer: u32, indirect_offset: u64, @@ -692,11 +652,9 @@ struct RenderPassDrawIndexedIndirectArgs { pub fn op_webgpu_render_pass_draw_indexed_indirect( state: &mut OpState, - args: Value, + args: RenderPassDrawIndexedIndirectArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: RenderPassDrawIndexedIndirectArgs = serde_json::from_value(args)?; - let buffer_resource = state .resource_table .get::(args.indirect_buffer) diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index 1400281eef265a..d111526a6a346c 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -61,7 +61,7 @@ pub fn serialize_compare_function( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateSamplerArgs { +pub struct CreateSamplerArgs { device_rid: u32, label: Option, address_mode_u: Option, @@ -78,11 +78,9 @@ struct CreateSamplerArgs { pub fn op_webgpu_create_sampler( state: &mut OpState, - args: Value, + args: CreateSamplerArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateSamplerArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index 36e99095c3e24d..da9749f7743761 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -4,7 +4,7 @@ use deno_core::error::bad_resource_id; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -18,7 +18,7 @@ impl Resource for WebGPUShaderModule { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateShaderModuleArgs { +pub struct CreateShaderModuleArgs { device_rid: u32, label: Option, code: Option, @@ -27,11 +27,9 @@ struct CreateShaderModuleArgs { pub fn op_webgpu_create_shader_module( state: &mut OpState, - args: Value, + args: CreateShaderModuleArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateShaderModuleArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index a8a1566fc93915..c4ab76da5132cc 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -4,7 +4,7 @@ use deno_core::error::AnyError; use deno_core::error::{bad_resource_id, not_supported}; use deno_core::serde_json::json; use deno_core::serde_json::Value; -use deno_core::{serde_json, ZeroCopyBuf}; +use deno_core::ZeroCopyBuf; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; @@ -131,7 +131,7 @@ pub struct GPUExtent3D { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateTextureArgs { +pub struct CreateTextureArgs { device_rid: u32, label: Option, size: GPUExtent3D, @@ -144,11 +144,9 @@ struct CreateTextureArgs { pub fn op_webgpu_create_texture( state: &mut OpState, - args: Value, + args: CreateTextureArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateTextureArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let device_resource = state .resource_table @@ -193,7 +191,7 @@ pub fn op_webgpu_create_texture( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct CreateTextureViewArgs { +pub struct CreateTextureViewArgs { texture_rid: u32, label: Option, format: Option, @@ -207,11 +205,9 @@ struct CreateTextureViewArgs { pub fn op_webgpu_create_texture_view( state: &mut OpState, - args: Value, + args: CreateTextureViewArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let args: CreateTextureViewArgs = serde_json::from_value(args)?; - let instance = state.borrow::(); let texture_resource = state .resource_table From 72ef8217695a14f66b7b281f515328880307fd42 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 14:06:59 +0100 Subject: [PATCH 111/144] add typings for flag classes --- op_crates/webgpu/lib.deno_webgpu.d.ts | 64 ++++++++++++--------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index 469849fce81246..f464d1bfc22ccb 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -156,28 +156,24 @@ declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase { } declare type GPUBufferUsageFlags = number; -/* -declare interface GPUBufferUsage { - const GPUFlagsConstant MAP_READ = 0x0001; - const GPUFlagsConstant MAP_WRITE = 0x0002; - const GPUFlagsConstant COPY_SRC = 0x0004; - const GPUFlagsConstant COPY_DST = 0x0008; - const GPUFlagsConstant INDEX = 0x0010; - const GPUFlagsConstant VERTEX = 0x0020; - const GPUFlagsConstant UNIFORM = 0x0040; - const GPUFlagsConstant STORAGE = 0x0080; - const GPUFlagsConstant INDIRECT = 0x0100; - const GPUFlagsConstant QUERY_RESOLVE = 0x0200; -}; -*/ +declare class GPUBufferUsage { + static MAP_READ: 0x0001; + static MAP_WRITE: 0x0002; + static COPY_SRC: 0x0004; + static COPY_DST: 0x0008; + static INDEX: 0x0010; + static VERTEX: 0x0020; + static UNIFORM: 0x0040; + static STORAGE: 0x0080; + static INDIRECT: 0x0100; + static QUERY_RESOLVE: 0x0200; +} declare type GPUMapModeFlags = number; -/* -declare interface GPUMapMode { - const GPUFlagsConstant READ = 0x0001; - const GPUFlagsConstant WRITE = 0x0002; -}; -*/ +declare class GPUMapMode { + static READ: 0x0001; + static WRITE: 0x0002; +} declare interface GPUTexture extends GPUObjectBase { createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView; @@ -196,15 +192,13 @@ declare interface GPUTextureDescriptor extends GPUObjectDescriptorBase { declare type GPUTextureDimension = "1d" | "2d" | "3d"; declare type GPUTextureUsageFlags = number; -/* -declare interface GPUTextureUsage { - const GPUFlagsConstant COPY_SRC = 0x01; - const GPUFlagsConstant COPY_DST = 0x02; - const GPUFlagsConstant SAMPLED = 0x04; - const GPUFlagsConstant STORAGE = 0x08; - const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; -}; -*/ +declare class GPUTextureUsage { + static COPY_SRC: 0x01; + static COPY_DST: 0x02; + static SAMPLED: 0x04; + static STORAGE: 0x08; + static RENDER_ATTACHMENT: 0x10; +} declare interface GPUTextureView extends GPUObjectBase {} @@ -333,13 +327,11 @@ declare interface GPUBindGroupLayoutEntry { } declare type GPUShaderStageFlags = number; -/* -declare interface GPUShaderStage { - const GPUFlagsConstant VERTEX = 0x1; - const GPUFlagsConstant FRAGMENT = 0x2; - const GPUFlagsConstant COMPUTE = 0x4; -}; -*/ +declare class GPUShaderStage { + static VERTEX: 0x1; + static FRAGMENT: 0x2; + static COMPUTE: 0x4; +} declare interface GPUBufferBindingLayout { type?: GPUBufferBindingType; From 4071ce9c9d0383fd1db09b0ada7cf272ff9a4f99 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 14:29:10 +0100 Subject: [PATCH 112/144] fix sequence converter and idl_types --- op_crates/web/00_webidl.js | 7 +- op_crates/web/internal.d.ts | 19 +- op_crates/webgpu/02_idl_types.js | 847 +++++++++++++++++++++---------- 3 files changed, 597 insertions(+), 276 deletions(-) diff --git a/op_crates/web/00_webidl.js b/op_crates/web/00_webidl.js index 3b6dc8749482bb..ab30473915b9d9 100644 --- a/op_crates/web/00_webidl.js +++ b/op_crates/web/00_webidl.js @@ -708,15 +708,14 @@ opts, ); } - const method = V?.[Symbol.iterator]; - if (method === undefined) { + const iter = V?.[Symbol.iterator]?.(); + if (iter === undefined) { throw makeException( TypeError, "can not be converted to sequence.", opts, ); } - const iter = method(); const array = []; while (true) { const res = iter?.next?.(); @@ -728,7 +727,7 @@ ); } if (res.done === true) break; - const val = converter(val, { + const val = converter(res.value, { ...opts, context: `${opts.context}, index ${array.length}`, }); diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 88e027cdae38eb..5d2eb91f77eb9c 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -158,7 +158,7 @@ declare namespace globalThis { */ Uint8ClampedArray( v: any, - opts?: BufferConverterOpts, + opts?: BufferConverterOpts ): Uint8ClampedArray; /** * Convert a value into a `Float32Array` (Float32Array). @@ -177,7 +177,7 @@ declare namespace globalThis { */ BufferSource( v: any, - opts?: BufferConverterOpts, + opts?: BufferConverterOpts ): ArrayBuffer | ArrayBufferView; /** * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long @@ -201,7 +201,7 @@ declare namespace globalThis { declare function requiredArguments( length: number, required: number, - opts: ConverterOpts, + opts: ConverterOpts ): void; declare type Dictionary = DictionaryMember[]; declare interface DictionaryMember { @@ -224,16 +224,23 @@ declare namespace globalThis { */ declare function createEnumConverter( name: string, - values: string[], + values: string[] ): (v: any, opts: ValueConverterOpts) => string; /** * Create a converter that makes the contained type nullable. */ declare function createNullableConverter( - converter: (v: any, opts: ValueConverterOpts) => T, + converter: (v: any, opts: ValueConverterOpts) => T ): (v: any, opts: ValueConverterOpts) => T | null; + /** + * Create a converter that converts a sequence of the inner type. + */ + declare function createSequenceConverter( + converter: (v: any, opts: ValueConverterOpts) => T + ): (v: any, opts: ValueConverterOpts) => T[]; + /** * Throw an illegal constructor error. */ @@ -259,7 +266,7 @@ declare namespace globalThis { */ declare function createInterfaceConverter( name: string, - prototype: any, + prototype: any ): (v: any, opts: ValueConverterOpts) => any; } diff --git a/op_crates/webgpu/02_idl_types.js b/op_crates/webgpu/02_idl_types.js index 4e8559d01221ae..5de8852bf26434 100644 --- a/op_crates/webgpu/02_idl_types.js +++ b/op_crates/webgpu/02_idl_types.js @@ -10,9 +10,14 @@ const { GPU, GPUAdapter, + GPUAdapterLimits, + GPUAdapterFeatures, GPUDevice, GPUQueue, GPUBuffer, + GPUBufferUsage, + GPUMapMode, + GPUTextureUsage, GPUTexture, GPUTextureView, GPUSampler, @@ -20,8 +25,10 @@ GPUPipelineLayout, GPUBindGroup, GPUShaderModule, + GPUShaderStage, GPUComputePipeline, GPURenderPipeline, + GPUColorWrite, GPUCommandEncoder, GPURenderPassEncoder, GPUComputePassEncoder, @@ -44,17 +51,17 @@ dictMembersGPUObjectDescriptorBase, ); - // // INTERFACE: GPUAdapterLimits - // webidl.converters.GPUAdapterLimits = webidl.createInterfaceConverter( - // "GPUAdapterLimits", - // GPUAdapterLimits, - // ); + // INTERFACE: GPUAdapterLimits + webidl.converters.GPUAdapterLimits = webidl.createInterfaceConverter( + "GPUAdapterLimits", + GPUAdapterLimits, + ); - // // INTERFACE: GPUAdapterFeatures - // webidl.converters.GPUAdapterFeatures = webidl.createInterfaceConverter( - // "GPUAdapterFeatures", - // GPUAdapterFeatures, - // ); + // INTERFACE: GPUAdapterFeatures + webidl.converters.GPUAdapterFeatures = webidl.createInterfaceConverter( + "GPUAdapterFeatures", + GPUAdapterFeatures, + ); // INTERFACE: GPU webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU); @@ -87,17 +94,6 @@ GPUAdapter, ); - // DICTIONARY: GPUDeviceDescriptor - const dictMembersGPUDeviceDescriptor = [ - { key: "nonGuaranteedFeatures", converter: webidl.converters.any }, - { key: "nonGuaranteedLimits", converter: webidl.converters.any }, - ]; - webidl.converters["GPUDeviceDescriptor"] = webidl.createDictionaryConverter( - "GPUDeviceDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUDeviceDescriptor, - ); - // ENUM: GPUFeatureName webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( "GPUFeatureName", @@ -111,6 +107,27 @@ ], ); + // DICTIONARY: GPUDeviceDescriptor + const dictMembersGPUDeviceDescriptor = [ + { + key: "nonGuaranteedFeatures", + converter: webidl.createSequenceConverter( + webidl.converters["GPUFeatureName"], + ), + defaultValue: [], + }, + { + key: "nonGuaranteedLimits", + converter: webidl.converters.any, + defaultValue: {}, + }, + ]; + webidl.converters["GPUDeviceDescriptor"] = webidl.createDictionaryConverter( + "GPUDeviceDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUDeviceDescriptor, + ); + // INTERFACE: GPUDevice webidl.converters.GPUDevice = webidl.createInterfaceConverter( "GPUDevice", @@ -139,7 +156,11 @@ converter: webidl.converters["GPUBufferUsageFlags"], required: true, }, - { key: "mappedAtCreation", converter: webidl.converters["boolean"] }, + { + key: "mappedAtCreation", + converter: webidl.converters["boolean"], + defaultValue: false, + }, ]; webidl.converters["GPUBufferDescriptor"] = webidl.createDictionaryConverter( "GPUBufferDescriptor", @@ -147,21 +168,21 @@ dictMembersGPUBufferDescriptor, ); - // // INTERFACE: GPUBufferUsage - // webidl.converters.GPUBufferUsage = webidl.createInterfaceConverter( - // "GPUBufferUsage", - // GPUBufferUsage, - // ); + // INTERFACE: GPUBufferUsage + webidl.converters.GPUBufferUsage = webidl.createInterfaceConverter( + "GPUBufferUsage", + GPUBufferUsage, + ); // TYPEDEF: GPUMapModeFlags webidl.converters["GPUMapModeFlags"] = (V, opts) => webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - // // INTERFACE: GPUMapMode - // webidl.converters.GPUMapMode = webidl.createInterfaceConverter( - // "GPUMapMode", - // GPUMapMode, - // ); + // INTERFACE: GPUMapMode + webidl.converters.GPUMapMode = webidl.createInterfaceConverter( + "GPUMapMode", + GPUMapMode, + ); // INTERFACE: GPUTexture webidl.converters.GPUTexture = webidl.createInterfaceConverter( @@ -268,9 +289,18 @@ { key: "mipLevelCount", converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, + { + key: "sampleCount", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, + }, + { + key: "dimension", + converter: webidl.converters["GPUTextureDimension"], + defaultValue: "2d", }, - { key: "sampleCount", converter: webidl.converters["GPUSize32"] }, - { key: "dimension", converter: webidl.converters["GPUTextureDimension"] }, { key: "format", converter: webidl.converters["GPUTextureFormat"], @@ -288,11 +318,11 @@ dictMembersGPUTextureDescriptor, ); - // // INTERFACE: GPUTextureUsage - // webidl.converters.GPUTextureUsage = webidl.createInterfaceConverter( - // "GPUTextureUsage", - // GPUTextureUsage, - // ); + // INTERFACE: GPUTextureUsage + webidl.converters.GPUTextureUsage = webidl.createInterfaceConverter( + "GPUTextureUsage", + GPUTextureUsage, + ); // INTERFACE: GPUTextureView webidl.converters.GPUTextureView = webidl.createInterfaceConverter( @@ -330,10 +360,15 @@ key: "dimension", converter: webidl.converters["GPUTextureViewDimension"], }, - { key: "aspect", converter: webidl.converters["GPUTextureAspect"] }, + { + key: "aspect", + converter: webidl.converters["GPUTextureAspect"], + defaultValue: "all", + }, { key: "baseMipLevel", converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, }, { key: "mipLevelCount", @@ -342,6 +377,7 @@ { key: "baseArrayLayer", converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, }, { key: "arrayLayerCount", @@ -397,19 +433,52 @@ // DICTIONARY: GPUSamplerDescriptor const dictMembersGPUSamplerDescriptor = [ - { key: "addressModeU", converter: webidl.converters["GPUAddressMode"] }, - { key: "addressModeV", converter: webidl.converters["GPUAddressMode"] }, - { key: "addressModeW", converter: webidl.converters["GPUAddressMode"] }, - { key: "magFilter", converter: webidl.converters["GPUFilterMode"] }, - { key: "minFilter", converter: webidl.converters["GPUFilterMode"] }, - { key: "mipmapFilter", converter: webidl.converters["GPUFilterMode"] }, - { key: "lodMinClamp", converter: webidl.converters["float"] }, - { key: "lodMaxClamp", converter: webidl.converters["float"] }, + { + key: "addressModeU", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "addressModeV", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "addressModeW", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "magFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "minFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "mipmapFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "lodMinClamp", + converter: webidl.converters["float"], + defaultValue: 0, + }, + { + key: "lodMaxClamp", + converter: webidl.converters["float"], + defaultValue: 0xffffffff, + }, { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, { key: "maxAnisotropy", converter: (V, opts) => webidl.converters["unsigned short"](V, { ...opts, clamp: true }), + defaultValue: 1, }, ]; webidl.converters["GPUSamplerDescriptor"] = webidl.createDictionaryConverter( @@ -424,31 +493,14 @@ GPUBindGroupLayout, ); - // DICTIONARY: GPUBindGroupLayoutDescriptor - const dictMembersGPUBindGroupLayoutDescriptor = [ - { key: "entries", converter: webidl.converters.any, required: true }, - ]; - webidl.converters["GPUBindGroupLayoutDescriptor"] = webidl - .createDictionaryConverter( - "GPUBindGroupLayoutDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUBindGroupLayoutDescriptor, - ); + // TYPEDEF: GPUIndex32 + webidl.converters["GPUIndex32"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); // TYPEDEF: GPUShaderStageFlags webidl.converters["GPUShaderStageFlags"] = (V, opts) => webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - // // INTERFACE: GPUShaderStage - // webidl.converters.GPUShaderStage = webidl.createInterfaceConverter( - // "GPUShaderStage", - // GPUShaderStage, - // ); - - // TYPEDEF: GPUIndex32 - webidl.converters["GPUIndex32"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - // ENUM: GPUBufferBindingType webidl.converters["GPUBufferBindingType"] = webidl.createEnumConverter( "GPUBufferBindingType", @@ -461,9 +513,21 @@ // DICTIONARY: GPUBufferBindingLayout const dictMembersGPUBufferBindingLayout = [ - { key: "type", converter: webidl.converters["GPUBufferBindingType"] }, - { key: "hasDynamicOffset", converter: webidl.converters["boolean"] }, - { key: "minBindingSize", converter: webidl.converters["GPUSize64"] }, + { + key: "type", + converter: webidl.converters["GPUBufferBindingType"], + defaultValue: "uniform", + }, + { + key: "hasDynamicOffset", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + { + key: "minBindingSize", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, ]; webidl.converters["GPUBufferBindingLayout"] = webidl .createDictionaryConverter( @@ -483,7 +547,11 @@ // DICTIONARY: GPUSamplerBindingLayout const dictMembersGPUSamplerBindingLayout = [ - { key: "type", converter: webidl.converters["GPUSamplerBindingType"] }, + { + key: "type", + converter: webidl.converters["GPUSamplerBindingType"], + defaultValue: "filtering", + }, ]; webidl.converters["GPUSamplerBindingLayout"] = webidl .createDictionaryConverter( @@ -505,12 +573,21 @@ // DICTIONARY: GPUTextureBindingLayout const dictMembersGPUTextureBindingLayout = [ - { key: "sampleType", converter: webidl.converters["GPUTextureSampleType"] }, + { + key: "sampleType", + converter: webidl.converters["GPUTextureSampleType"], + defaultValue: "float", + }, { key: "viewDimension", converter: webidl.converters["GPUTextureViewDimension"], + defaultValue: "2d", + }, + { + key: "multisampled", + converter: webidl.converters["boolean"], + defaultValue: false, }, - { key: "multisampled", converter: webidl.converters["boolean"] }, ]; webidl.converters["GPUTextureBindingLayout"] = webidl .createDictionaryConverter( @@ -542,6 +619,7 @@ { key: "viewDimension", converter: webidl.converters["GPUTextureViewDimension"], + defaultValue: "2d", }, ]; webidl.converters["GPUStorageTextureBindingLayout"] = webidl @@ -576,28 +654,35 @@ dictMembersGPUBindGroupLayoutEntry, ); - // INTERFACE: GPUBindGroup - webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( - "GPUBindGroup", - GPUBindGroup, - ); - - // DICTIONARY: GPUBindGroupDescriptor - const dictMembersGPUBindGroupDescriptor = [ + // DICTIONARY: GPUBindGroupLayoutDescriptor + const dictMembersGPUBindGroupLayoutDescriptor = [ { - key: "layout", - converter: webidl.converters["GPUBindGroupLayout"], + key: "entries", + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupLayoutEntry"], + ), required: true, }, - { key: "entries", converter: webidl.converters.any, required: true }, ]; - webidl.converters["GPUBindGroupDescriptor"] = webidl + webidl.converters["GPUBindGroupLayoutDescriptor"] = webidl .createDictionaryConverter( - "GPUBindGroupDescriptor", + "GPUBindGroupLayoutDescriptor", dictMembersGPUObjectDescriptorBase, - dictMembersGPUBindGroupDescriptor, + dictMembersGPUBindGroupLayoutDescriptor, ); + // INTERFACE: GPUShaderStage + webidl.converters.GPUShaderStage = webidl.createInterfaceConverter( + "GPUShaderStage", + GPUShaderStage, + ); + + // INTERFACE: GPUBindGroup + webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( + "GPUBindGroup", + GPUBindGroup, + ); + // TYPEDEF: GPUBindingResource webidl.converters["GPUBindingResource"] = webidl.converters.any; @@ -619,6 +704,28 @@ dictMembersGPUBindGroupEntry, ); + // DICTIONARY: GPUBindGroupDescriptor + const dictMembersGPUBindGroupDescriptor = [ + { + key: "layout", + converter: webidl.converters["GPUBindGroupLayout"], + required: true, + }, + { + key: "entries", + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupEntry"], + ), + required: true, + }, + ]; + webidl.converters["GPUBindGroupDescriptor"] = webidl + .createDictionaryConverter( + "GPUBindGroupDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBindGroupDescriptor, + ); + // DICTIONARY: GPUBufferBinding const dictMembersGPUBufferBinding = [ { @@ -626,7 +733,11 @@ converter: webidl.converters["GPUBuffer"], required: true, }, - { key: "offset", converter: webidl.converters["GPUSize64"] }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, { key: "size", converter: webidl.converters["GPUSize64"] }, ]; webidl.converters["GPUBufferBinding"] = webidl.createDictionaryConverter( @@ -644,7 +755,9 @@ const dictMembersGPUPipelineLayoutDescriptor = [ { key: "bindGroupLayouts", - converter: webidl.converters.any, + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupLayout"], + ), required: true, }, ]; @@ -751,9 +864,111 @@ GPURenderPipeline, ); + // ENUM: GPUInputStepMode + webidl.converters["GPUInputStepMode"] = webidl.createEnumConverter( + "GPUInputStepMode", + [ + "vertex", + "instance", + ], + ); + + // ENUM: GPUVertexFormat + webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( + "GPUVertexFormat", + [ + "uchar2", + "uchar4", + "char2", + "char4", + "uchar2norm", + "uchar4norm", + "char2norm", + "char4norm", + "ushort2", + "ushort4", + "short2", + "short4", + "ushort2norm", + "ushort4norm", + "short2norm", + "short4norm", + "half2", + "half4", + "float", + "float2", + "float3", + "float4", + "uint", + "uint2", + "uint3", + "uint4", + "int", + "int2", + "int3", + "int4", + ], + ); + + // DICTIONARY: GPUVertexAttribute + const dictMembersGPUVertexAttribute = [ + { + key: "format", + converter: webidl.converters["GPUVertexFormat"], + required: true, + }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { + key: "shaderLocation", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + ]; + webidl.converters["GPUVertexAttribute"] = webidl.createDictionaryConverter( + "GPUVertexAttribute", + dictMembersGPUVertexAttribute, + ); + + // DICTIONARY: GPUVertexBufferLayout + const dictMembersGPUVertexBufferLayout = [ + { + key: "arrayStride", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { + key: "stepMode", + converter: webidl.converters["GPUInputStepMode"], + defaultValue: "vertex", + }, + { + key: "attributes", + converter: webidl.createSequenceConverter( + webidl.converters["GPUVertexAttribute"], + ), + required: true, + }, + ]; + webidl.converters["GPUVertexBufferLayout"] = webidl.createDictionaryConverter( + "GPUVertexBufferLayout", + dictMembersGPUVertexBufferLayout, + ); + // DICTIONARY: GPUVertexState const dictMembersGPUVertexState = [ - { key: "buffers", converter: webidl.converters.any }, + { + key: "buffers", + converter: webidl.createSequenceConverter( + webidl.createNullableConverter( + webidl.converters["GPUVertexBufferLayout"], + ), + ), + defaultValue: [], + }, ]; webidl.converters["GPUVertexState"] = webidl.createDictionaryConverter( "GPUVertexState", @@ -800,10 +1015,22 @@ // DICTIONARY: GPUPrimitiveState const dictMembersGPUPrimitiveState = [ - { key: "topology", converter: webidl.converters["GPUPrimitiveTopology"] }, + { + key: "topology", + converter: webidl.converters["GPUPrimitiveTopology"], + defaultValue: "triangle-list", + }, { key: "stripIndexFormat", converter: webidl.converters["GPUIndexFormat"] }, - { key: "frontFace", converter: webidl.converters["GPUFrontFace"] }, - { key: "cullMode", converter: webidl.converters["GPUCullMode"] }, + { + key: "frontFace", + converter: webidl.converters["GPUFrontFace"], + defaultValue: "ccw", + }, + { + key: "cullMode", + converter: webidl.converters["GPUCullMode"], + defaultValue: "none", + }, ]; webidl.converters["GPUPrimitiveState"] = webidl.createDictionaryConverter( "GPUPrimitiveState", @@ -827,10 +1054,26 @@ // DICTIONARY: GPUStencilFaceState const dictMembersGPUStencilFaceState = [ - { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, - { key: "failOp", converter: webidl.converters["GPUStencilOperation"] }, - { key: "depthFailOp", converter: webidl.converters["GPUStencilOperation"] }, - { key: "passOp", converter: webidl.converters["GPUStencilOperation"] }, + { + key: "compare", + converter: webidl.converters["GPUCompareFunction"], + defaultValue: "always", + }, + { + key: "failOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, + { + key: "depthFailOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, + { + key: "passOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, ]; webidl.converters["GPUStencilFaceState"] = webidl.createDictionaryConverter( "GPUStencilFaceState", @@ -852,22 +1095,56 @@ converter: webidl.converters["GPUTextureFormat"], required: true, }, - { key: "depthWriteEnabled", converter: webidl.converters["boolean"] }, - { key: "depthCompare", converter: webidl.converters["GPUCompareFunction"] }, + { + key: "depthWriteEnabled", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + { + key: "depthCompare", + converter: webidl.converters["GPUCompareFunction"], + defaultValue: "always", + }, { key: "stencilFront", converter: webidl.converters["GPUStencilFaceState"], + defaultValue: {}, + }, + { + key: "stencilBack", + converter: webidl.converters["GPUStencilFaceState"], + defaultValue: {}, + }, + { + key: "stencilReadMask", + converter: webidl.converters["GPUStencilValue"], + defaultValue: 0xFFFFFFFF, }, - { key: "stencilBack", converter: webidl.converters["GPUStencilFaceState"] }, - { key: "stencilReadMask", converter: webidl.converters["GPUStencilValue"] }, { key: "stencilWriteMask", converter: webidl.converters["GPUStencilValue"], + defaultValue: 0xFFFFFFFF, + }, + { + key: "depthBias", + converter: webidl.converters["GPUDepthBias"], + defaultValue: 0, + }, + { + key: "depthBiasSlopeScale", + converter: webidl.converters["float"], + defaultValue: 0, + }, + { + key: "depthBiasClamp", + converter: webidl.converters["float"], + defaultValue: 0, + }, + { + key: "clampDepth", + converter: webidl.converters["boolean"], + defaultValue: false, }, - { key: "depthBias", converter: webidl.converters["GPUDepthBias"] }, - { key: "depthBiasSlopeScale", converter: webidl.converters["float"] }, - { key: "depthBiasClamp", converter: webidl.converters["float"] }, - { key: "clampDepth", converter: webidl.converters["boolean"] }, ]; webidl.converters["GPUDepthStencilState"] = webidl.createDictionaryConverter( "GPUDepthStencilState", @@ -880,46 +1157,26 @@ // DICTIONARY: GPUMultisampleState const dictMembersGPUMultisampleState = [ - { key: "count", converter: webidl.converters["GPUSize32"] }, - { key: "mask", converter: webidl.converters["GPUSampleMask"] }, - { key: "alphaToCoverageEnabled", converter: webidl.converters["boolean"] }, - ]; - webidl.converters["GPUMultisampleState"] = webidl.createDictionaryConverter( - "GPUMultisampleState", - dictMembersGPUMultisampleState, - ); - - // DICTIONARY: GPUFragmentState - const dictMembersGPUFragmentState = [ - { key: "targets", converter: webidl.converters.any, required: true }, - ]; - webidl.converters["GPUFragmentState"] = webidl.createDictionaryConverter( - "GPUFragmentState", - dictMembersGPUProgrammableStage, - dictMembersGPUFragmentState, - ); - - // DICTIONARY: GPURenderPipelineDescriptor - const dictMembersGPURenderPipelineDescriptor = [ { - key: "vertex", - converter: webidl.converters["GPUVertexState"], - required: true, + key: "count", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, }, - { key: "primitive", converter: webidl.converters["GPUPrimitiveState"] }, { - key: "depthStencil", - converter: webidl.converters["GPUDepthStencilState"], + key: "mask", + converter: webidl.converters["GPUSampleMask"], + defaultValue: 0xFFFFFFFF, + }, + { + key: "alphaToCoverageEnabled", + converter: webidl.converters["boolean"], + defaultValue: false, }, - { key: "multisample", converter: webidl.converters["GPUMultisampleState"] }, - { key: "fragment", converter: webidl.converters["GPUFragmentState"] }, ]; - webidl.converters["GPURenderPipelineDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderPipelineDescriptor", - dictMembersGPUPipelineDescriptorBase, - dictMembersGPURenderPipelineDescriptor, - ); + webidl.converters["GPUMultisampleState"] = webidl.createDictionaryConverter( + "GPUMultisampleState", + dictMembersGPUMultisampleState, + ); // ENUM: GPUBlendFactor webidl.converters["GPUBlendFactor"] = webidl.createEnumConverter( @@ -955,9 +1212,21 @@ // DICTIONARY: GPUBlendComponent const dictMembersGPUBlendComponent = [ - { key: "srcFactor", converter: webidl.converters["GPUBlendFactor"] }, - { key: "dstFactor", converter: webidl.converters["GPUBlendFactor"] }, - { key: "operation", converter: webidl.converters["GPUBlendOperation"] }, + { + key: "srcFactor", + converter: webidl.converters["GPUBlendFactor"], + defaultValue: "one", + }, + { + key: "dstFactor", + converter: webidl.converters["GPUBlendFactor"], + defaultValue: "zero", + }, + { + key: "operation", + converter: webidl.converters["GPUBlendOperation"], + defaultValue: "add", + }, ]; webidl.converters["GPUBlendComponent"] = webidl.createDictionaryConverter( "GPUBlendComponent", @@ -994,101 +1263,67 @@ required: true, }, { key: "blend", converter: webidl.converters["GPUBlendState"] }, - { key: "writeMask", converter: webidl.converters["GPUColorWriteFlags"] }, + { + key: "writeMask", + converter: webidl.converters["GPUColorWriteFlags"], + defaultValue: 0xF, + }, ]; webidl.converters["GPUColorTargetState"] = webidl.createDictionaryConverter( "GPUColorTargetState", dictMembersGPUColorTargetState, ); - // // INTERFACE: GPUColorWrite - // webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( - // "GPUColorWrite", - // GPUColorWrite, - // ); - - // ENUM: GPUVertexFormat - webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( - "GPUVertexFormat", - [ - "uchar2", - "uchar4", - "char2", - "char4", - "uchar2norm", - "uchar4norm", - "char2norm", - "char4norm", - "ushort2", - "ushort4", - "short2", - "short4", - "ushort2norm", - "ushort4norm", - "short2norm", - "short4norm", - "half2", - "half4", - "float", - "float2", - "float3", - "float4", - "uint", - "uint2", - "uint3", - "uint4", - "int", - "int2", - "int3", - "int4", - ], - ); - - // ENUM: GPUInputStepMode - webidl.converters["GPUInputStepMode"] = webidl.createEnumConverter( - "GPUInputStepMode", - [ - "vertex", - "instance", - ], - ); - - // DICTIONARY: GPUVertexBufferLayout - const dictMembersGPUVertexBufferLayout = [ + // DICTIONARY: GPUFragmentState + const dictMembersGPUFragmentState = [ { - key: "arrayStride", - converter: webidl.converters["GPUSize64"], + key: "targets", + converter: webidl.createSequenceConverter( + webidl.converters["GPUColorTargetState"], + ), required: true, }, - { key: "stepMode", converter: webidl.converters["GPUInputStepMode"] }, - { key: "attributes", converter: webidl.converters.any, required: true }, ]; - webidl.converters["GPUVertexBufferLayout"] = webidl.createDictionaryConverter( - "GPUVertexBufferLayout", - dictMembersGPUVertexBufferLayout, + webidl.converters["GPUFragmentState"] = webidl.createDictionaryConverter( + "GPUFragmentState", + dictMembersGPUProgrammableStage, + dictMembersGPUFragmentState, ); - // DICTIONARY: GPUVertexAttribute - const dictMembersGPUVertexAttribute = [ + // DICTIONARY: GPURenderPipelineDescriptor + const dictMembersGPURenderPipelineDescriptor = [ { - key: "format", - converter: webidl.converters["GPUVertexFormat"], + key: "vertex", + converter: webidl.converters["GPUVertexState"], required: true, }, { - key: "offset", - converter: webidl.converters["GPUSize64"], - required: true, + key: "primitive", + converter: webidl.converters["GPUPrimitiveState"], + defaultValue: {}, }, { - key: "shaderLocation", - converter: webidl.converters["GPUIndex32"], - required: true, + key: "depthStencil", + converter: webidl.converters["GPUDepthStencilState"], + }, + { + key: "multisample", + converter: webidl.converters["GPUMultisampleState"], + defaultValue: {}, }, + { key: "fragment", converter: webidl.converters["GPUFragmentState"] }, ]; - webidl.converters["GPUVertexAttribute"] = webidl.createDictionaryConverter( - "GPUVertexAttribute", - dictMembersGPUVertexAttribute, + webidl.converters["GPURenderPipelineDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderPipelineDescriptor", + dictMembersGPUPipelineDescriptorBase, + dictMembersGPURenderPipelineDescriptor, + ); + + // INTERFACE: GPUColorWrite + webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( + "GPUColorWrite", + GPUColorWrite, ); // INTERFACE: GPUCommandBuffer @@ -1114,7 +1349,11 @@ // DICTIONARY: GPUCommandEncoderDescriptor const dictMembersGPUCommandEncoderDescriptor = [ - { key: "measureExecutionTime", converter: webidl.converters["boolean"] }, + { + key: "measureExecutionTime", + converter: webidl.converters["boolean"], + defaultValue: false, + }, ]; webidl.converters["GPUCommandEncoderDescriptor"] = webidl .createDictionaryConverter( @@ -1125,7 +1364,11 @@ // DICTIONARY: GPUImageDataLayout const dictMembersGPUImageDataLayout = [ - { key: "offset", converter: webidl.converters["GPUSize64"] }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, { key: "bytesPerRow", converter: webidl.converters["GPUSize32"] }, { key: "rowsPerImage", converter: webidl.converters["GPUSize32"] }, ]; @@ -1158,9 +1401,21 @@ converter: webidl.converters["GPUTexture"], required: true, }, - { key: "mipLevel", converter: webidl.converters["GPUIntegerCoordinate"] }, - { key: "origin", converter: webidl.converters["GPUOrigin3D"] }, - { key: "aspect", converter: webidl.converters["GPUTextureAspect"] }, + { + key: "mipLevel", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "origin", + converter: webidl.converters["GPUOrigin3D"], + defaultValue: {}, + }, + { + key: "aspect", + converter: webidl.converters["GPUTextureAspect"], + defaultValue: "all", + }, ]; webidl.converters["GPUImageCopyTexture"] = webidl.createDictionaryConverter( "GPUImageCopyTexture", @@ -1194,6 +1449,27 @@ "clear", ]); + // DICTIONARY: GPURenderPassColorAttachment + const dictMembersGPURenderPassColorAttachment = [ + { + key: "view", + converter: webidl.converters["GPUTextureView"], + required: true, + }, + { key: "resolveTarget", converter: webidl.converters["GPUTextureView"] }, + { key: "loadValue", converter: webidl.converters.any, required: true }, + { + key: "storeOp", + converter: webidl.converters["GPUStoreOp"], + defaultValue: "store", + }, + ]; + webidl.converters["GPURenderPassColorAttachment"] = webidl + .createDictionaryConverter( + "GPURenderPassColorAttachment", + dictMembersGPURenderPassColorAttachment, + ); + // DICTIONARY: GPURenderPassDepthStencilAttachment const dictMembersGPURenderPassDepthStencilAttachment = [ { @@ -1207,7 +1483,11 @@ converter: webidl.converters["GPUStoreOp"], required: true, }, - { key: "depthReadOnly", converter: webidl.converters["boolean"] }, + { + key: "depthReadOnly", + converter: webidl.converters["boolean"], + defaultValue: false, + }, { key: "stencilLoadValue", converter: webidl.converters.any, @@ -1218,7 +1498,11 @@ converter: webidl.converters["GPUStoreOp"], required: true, }, - { key: "stencilReadOnly", converter: webidl.converters["boolean"] }, + { + key: "stencilReadOnly", + converter: webidl.converters["boolean"], + defaultValue: false, + }, ]; webidl.converters["GPURenderPassDepthStencilAttachment"] = webidl .createDictionaryConverter( @@ -1236,7 +1520,9 @@ const dictMembersGPURenderPassDescriptor = [ { key: "colorAttachments", - converter: webidl.converters.any, + converter: webidl.createSequenceConverter( + webidl.converters["GPURenderPassColorAttachment"], + ), required: true, }, { @@ -1252,23 +1538,6 @@ dictMembersGPURenderPassDescriptor, ); - // DICTIONARY: GPURenderPassColorAttachment - const dictMembersGPURenderPassColorAttachment = [ - { - key: "view", - converter: webidl.converters["GPUTextureView"], - required: true, - }, - { key: "resolveTarget", converter: webidl.converters["GPUTextureView"] }, - { key: "loadValue", converter: webidl.converters.any, required: true }, - { key: "storeOp", converter: webidl.converters["GPUStoreOp"] }, - ]; - webidl.converters["GPURenderPassColorAttachment"] = webidl - .createDictionaryConverter( - "GPURenderPassColorAttachment", - dictMembersGPURenderPassColorAttachment, - ); - // ENUM: GPULoadOp webidl.converters["GPULoadOp"] = webidl.createEnumConverter("GPULoadOp", [ "load", @@ -1297,12 +1566,22 @@ // DICTIONARY: GPURenderBundleEncoderDescriptor const dictMembersGPURenderBundleEncoderDescriptor = [ - { key: "colorFormats", converter: webidl.converters.any, required: true }, + { + key: "colorFormats", + converter: webidl.createSequenceConverter( + webidl.converters["GPUTextureFormat"], + ), + required: true, + }, { key: "depthStencilFormat", converter: webidl.converters["GPUTextureFormat"], }, - { key: "sampleCount", converter: webidl.converters["GPUSize32"] }, + { + key: "sampleCount", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, + }, ]; webidl.converters["GPURenderBundleEncoderDescriptor"] = webidl .createDictionaryConverter( @@ -1327,6 +1606,18 @@ ], ); + // ENUM: GPUPipelineStatisticName + webidl.converters["GPUPipelineStatisticName"] = webidl.createEnumConverter( + "GPUPipelineStatisticName", + [ + "vertex-shader-invocations", + "clipper-invocations", + "clipper-primitives-out", + "fragment-shader-invocations", + "compute-shader-invocations", + ], + ); + // DICTIONARY: GPUQuerySetDescriptor const dictMembersGPUQuerySetDescriptor = [ { @@ -1335,7 +1626,13 @@ required: true, }, { key: "count", converter: webidl.converters["GPUSize32"], required: true }, - { key: "pipelineStatistics", converter: webidl.converters.any }, + { + key: "pipelineStatistics", + converter: webidl.createSequenceConverter( + webidl.converters["GPUPipelineStatisticName"], + ), + defaultValue: [], + }, ]; webidl.converters["GPUQuerySetDescriptor"] = webidl.createDictionaryConverter( "GPUQuerySetDescriptor", @@ -1343,18 +1640,6 @@ dictMembersGPUQuerySetDescriptor, ); - // ENUM: GPUPipelineStatisticName - webidl.converters["GPUPipelineStatisticName"] = webidl.createEnumConverter( - "GPUPipelineStatisticName", - [ - "vertex-shader-invocations", - "clipper-invocations", - "clipper-primitives-out", - "fragment-shader-invocations", - "compute-shader-invocations", - ], - ); - // ENUM: GPUDeviceLostReason webidl.converters["GPUDeviceLostReason"] = webidl.createEnumConverter( "GPUDeviceLostReason", @@ -1406,6 +1691,7 @@ webidl.converters["GPUUncapturedErrorEventInit"] = webidl .createDictionaryConverter( "GPUUncapturedErrorEventInit", + // dictMembersEventInit, dictMembersGPUUncapturedErrorEventInit, ); @@ -1437,8 +1723,16 @@ // DICTIONARY: GPUOrigin2DDict const dictMembersGPUOrigin2DDict = [ - { key: "x", converter: webidl.converters["GPUIntegerCoordinate"] }, - { key: "y", converter: webidl.converters["GPUIntegerCoordinate"] }, + { + key: "x", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, ]; webidl.converters["GPUOrigin2DDict"] = webidl.createDictionaryConverter( "GPUOrigin2DDict", @@ -1450,9 +1744,21 @@ // DICTIONARY: GPUOrigin3DDict const dictMembersGPUOrigin3DDict = [ - { key: "x", converter: webidl.converters["GPUIntegerCoordinate"] }, - { key: "y", converter: webidl.converters["GPUIntegerCoordinate"] }, - { key: "z", converter: webidl.converters["GPUIntegerCoordinate"] }, + { + key: "x", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "z", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, ]; webidl.converters["GPUOrigin3DDict"] = webidl.createDictionaryConverter( "GPUOrigin3DDict", @@ -1461,11 +1767,20 @@ // DICTIONARY: GPUExtent3DDict const dictMembersGPUExtent3DDict = [ - { key: "width", converter: webidl.converters["GPUIntegerCoordinate"] }, - { key: "height", converter: webidl.converters["GPUIntegerCoordinate"] }, + { + key: "width", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, + { + key: "height", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, { key: "depthOrArrayLayers", converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, }, ]; webidl.converters["GPUExtent3DDict"] = webidl.createDictionaryConverter( From 55f7d1f5cda6cfe2bc63f4c4670fcb6c953ff632 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 14:29:59 +0100 Subject: [PATCH 113/144] fmt --- op_crates/web/internal.d.ts | 14 +++++------ op_crates/webgpu/lib.deno_webgpu.d.ts | 34 +++++++++++++-------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 5d2eb91f77eb9c..8be80c8a520752 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -158,7 +158,7 @@ declare namespace globalThis { */ Uint8ClampedArray( v: any, - opts?: BufferConverterOpts + opts?: BufferConverterOpts, ): Uint8ClampedArray; /** * Convert a value into a `Float32Array` (Float32Array). @@ -177,7 +177,7 @@ declare namespace globalThis { */ BufferSource( v: any, - opts?: BufferConverterOpts + opts?: BufferConverterOpts, ): ArrayBuffer | ArrayBufferView; /** * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long @@ -201,7 +201,7 @@ declare namespace globalThis { declare function requiredArguments( length: number, required: number, - opts: ConverterOpts + opts: ConverterOpts, ): void; declare type Dictionary = DictionaryMember[]; declare interface DictionaryMember { @@ -224,21 +224,21 @@ declare namespace globalThis { */ declare function createEnumConverter( name: string, - values: string[] + values: string[], ): (v: any, opts: ValueConverterOpts) => string; /** * Create a converter that makes the contained type nullable. */ declare function createNullableConverter( - converter: (v: any, opts: ValueConverterOpts) => T + converter: (v: any, opts: ValueConverterOpts) => T, ): (v: any, opts: ValueConverterOpts) => T | null; /** * Create a converter that converts a sequence of the inner type. */ declare function createSequenceConverter( - converter: (v: any, opts: ValueConverterOpts) => T + converter: (v: any, opts: ValueConverterOpts) => T, ): (v: any, opts: ValueConverterOpts) => T[]; /** @@ -266,7 +266,7 @@ declare namespace globalThis { */ declare function createInterfaceConverter( name: string, - prototype: any + prototype: any, ): (v: any, opts: ValueConverterOpts) => any; } diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index f464d1bfc22ccb..914ac867452e41 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -157,22 +157,22 @@ declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase { declare type GPUBufferUsageFlags = number; declare class GPUBufferUsage { - static MAP_READ: 0x0001; - static MAP_WRITE: 0x0002; - static COPY_SRC: 0x0004; - static COPY_DST: 0x0008; - static INDEX: 0x0010; - static VERTEX: 0x0020; - static UNIFORM: 0x0040; - static STORAGE: 0x0080; - static INDIRECT: 0x0100; - static QUERY_RESOLVE: 0x0200; + static MAP_READ: 0x0001; + static MAP_WRITE: 0x0002; + static COPY_SRC: 0x0004; + static COPY_DST: 0x0008; + static INDEX: 0x0010; + static VERTEX: 0x0020; + static UNIFORM: 0x0040; + static STORAGE: 0x0080; + static INDIRECT: 0x0100; + static QUERY_RESOLVE: 0x0200; } declare type GPUMapModeFlags = number; declare class GPUMapMode { - static READ: 0x0001; - static WRITE: 0x0002; + static READ: 0x0001; + static WRITE: 0x0002; } declare interface GPUTexture extends GPUObjectBase { @@ -193,11 +193,11 @@ declare type GPUTextureDimension = "1d" | "2d" | "3d"; declare type GPUTextureUsageFlags = number; declare class GPUTextureUsage { - static COPY_SRC: 0x01; - static COPY_DST: 0x02; - static SAMPLED: 0x04; - static STORAGE: 0x08; - static RENDER_ATTACHMENT: 0x10; + static COPY_SRC: 0x01; + static COPY_DST: 0x02; + static SAMPLED: 0x04; + static STORAGE: 0x08; + static RENDER_ATTACHMENT: 0x10; } declare interface GPUTextureView extends GPUObjectBase {} From e73396b2ab8979215a5225b5c5cbcdc36b31cff4 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 15:51:55 +0100 Subject: [PATCH 114/144] more validation --- op_crates/webgpu/01_webgpu.js | 39 ++++++++++++++++++++------------ op_crates/webgpu/02_idl_types.js | 8 +++++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 21173becb175f6..6f03ddf813b9c3 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -141,16 +141,29 @@ */ async requestDevice(descriptor = {}) { webidl.assertBranded(this, GPUAdapter); + const prefix = "Failed to execute 'requestDevice' on 'GPUAdapter'"; descriptor = webidl.converters.GPUDeviceDescriptor(descriptor, { - prefix: "Failed to execute 'requestDevice' on 'GPUAdapter'", + prefix, context: "Argument 1", }); + const nonGuaranteedFeatures = descriptor.nonGuaranteedFeatures ?? []; + for (const feature of nonGuaranteedFeatures) { + if (!this[_adapter].features.has(feature)) { + throw new TypeError( + `${prefix}: nonGuaranteedFeatures must be a subset of the adapter features.`, + ); + } + } + const nonGuaranteedLimits = descriptor.nonGuaranteedLimits ?? []; + // TODO(lucacasonato): validate nonGuaranteedLimits const { rid, features, limits } = await core.jsonOpAsync( "op_webgpu_request_device", { adapterRid: this[_adapter].rid, - ...descriptor, + labe: descriptor.label, + nonGuaranteedFeatures, + nonGuaranteedLimits, }, ); @@ -363,10 +376,6 @@ return device; } - webidl.converters["UVString?"] = webidl.createNullableConverter( - webidl.converters.USVString, - ); - // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging class GPUDevice extends eventTarget.EventTarget { /** @type {InnerGPUDevice} */ @@ -772,11 +781,14 @@ */ submit(commandBuffers) { webidl.assertBranded(this, GPUQueue); + const prefix = "Failed to execute 'submit' on 'GPUQueue'"; webidl.requiredArguments(arguments.length, 1, { - prefix: "Failed to execute 'submit' on 'GPUQueue'", + prefix, }); - // TODO(lucacasonato): should be real converter - commandBuffers = webidl.converters.any(commandBuffers); + commandBuffers = webidl.converters["sequence"]( + commandBuffers, + { prefix, context: "Argument 1" }, + ); core.jsonOpSync("op_webgpu_queue_submit", { queueRid: this[_device], commandBuffers: commandBuffers.map((buffer) => buffer[_rid]), @@ -2232,11 +2244,10 @@ const prefix = "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - // TODO(lucacasonato): missing sequence - // bundles = webidl.converters.any(bundles, { - // prefix, - // context: "Argument 1", - // }); + bundles = webidl.converters["sequence"](bundles, { + prefix, + context: "Argument 1", + }); core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { renderPassRid: this[_rid], bundles: bundles.map((bundle) => bundle[_rid]), diff --git a/op_crates/webgpu/02_idl_types.js b/op_crates/webgpu/02_idl_types.js index 5de8852bf26434..eb3c07a3624e65 100644 --- a/op_crates/webgpu/02_idl_types.js +++ b/op_crates/webgpu/02_idl_types.js @@ -1787,4 +1787,12 @@ "GPUExtent3DDict", dictMembersGPUExtent3DDict, ); + + webidl.converters["sequence"] = webidl + .createSequenceConverter(webidl.converters["GPURenderBundle"]); + webidl.converters["sequence"] = webidl + .createSequenceConverter(webidl.converters["GPUCommandBuffer"]); + webidl.converters["UVString?"] = webidl.createNullableConverter( + webidl.converters.USVString, + ); })(this); From ff0616a4b085de2745fcd5e33f77a64ebf28c133 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 17:19:12 +0100 Subject: [PATCH 115/144] add descriptor slot to queryset --- op_crates/webgpu/01_webgpu.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 6f03ddf813b9c3..e00f76cc44ba87 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -747,7 +747,7 @@ ...descriptor, }); - return createGPUQuerySet(descriptor.label ?? null, rid); + return createGPUQuerySet(descriptor.label ?? null, rid, descriptor); } } GPUObjectBaseMixin("GPUDevice", GPUDevice); @@ -966,9 +966,9 @@ } /** - * @param {number} mode - * @param {number} offset - * @param {number} [size] + * @param {number} mode + * @param {number} offset + * @param {number} [size] */ async mapAsync(mode, offset = 0, size) { webidl.assertBranded(this, GPUBuffer); @@ -1059,8 +1059,8 @@ } /** - * @param {number} offset - * @param {number} size + * @param {number} offset + * @param {number} size */ getMappedRange(offset = 0, size) { webidl.assertBranded(this, GPUBuffer); @@ -3165,22 +3165,27 @@ } GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); + const _descriptor = symbol("[[descriptor]]"); + /** * @param {string | null} label * @param {number} rid * @returns {GPUQuerySet} */ - function createGPUQuerySet(label, rid) { + function createGPUQuerySet(label, rid, descriptor) { /** @type {GPUQuerySet} */ const queue = webidl.createBranded(GPUQuerySet); queue[_label] = label; queue[_rid] = rid; + queue[_descriptor] = descriptor; return queue; } class GPUQuerySet { /** @type {number} */ [_rid]; + /** @type {GPUQuerySetDescriptor} */ + [_descriptor]; constructor() { webidl.illegalConstructor(); From c2b0cb6f9822a3cb520fa96d2c7b3cb47d541d6b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 18:57:28 +0100 Subject: [PATCH 116/144] add consumable logic --- op_crates/webgpu/01_webgpu.js | 246 +++++++++++++++++++++++++++- op_crates/webgpu/command_encoder.rs | 4 +- op_crates/webgpu/compute_pass.rs | 4 +- op_crates/webgpu/render_pass.rs | 4 +- 4 files changed, 247 insertions(+), 11 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index e00f76cc44ba87..5286a316b2fa3b 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1606,7 +1606,7 @@ } class GPUCommandEncoder { - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; constructor() { @@ -1618,6 +1618,10 @@ * @return {GPURenderPassEncoder} */ beginRenderPass(descriptor) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; @@ -1700,6 +1704,10 @@ * @param {GPUComputePassDescriptor} descriptor */ beginComputePass(descriptor = {}) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; @@ -1737,6 +1745,10 @@ destinationOffset, size, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; @@ -1780,6 +1792,10 @@ * @param {GPUExtent3D} copySize */ copyBufferToTexture(source, destination, copySize) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; @@ -1822,6 +1838,10 @@ * @param {GPUExtent3D} copySize */ copyTextureToBuffer(source, destination, copySize) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; @@ -1862,6 +1882,10 @@ * @param {GPUExtent3D} copySize */ copyTextureToTexture(source, destination, copySize) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; @@ -1902,6 +1926,10 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; @@ -1917,6 +1945,10 @@ } popDebugGroup() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { commandEncoderRid: this[_rid], @@ -1927,6 +1959,10 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; @@ -1946,6 +1982,10 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; @@ -1979,6 +2019,10 @@ destination, destinationOffset, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; @@ -2018,6 +2062,10 @@ * @returns {GPUCommandBuffer} */ finish(descriptor = {}) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'finish' on 'GPUCommandEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { @@ -2028,6 +2076,7 @@ commandEncoderRid: this[_rid], ...descriptor, }); + this[_rid] = undefined; return createGPUCommandBuffer(descriptor.label ?? null, rid); } @@ -2054,7 +2103,7 @@ class GPURenderPassEncoder { /** @type {number} */ [_encoder]; - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; constructor() { @@ -2070,6 +2119,10 @@ * @param {number} maxDepth */ setViewport(x, y, width, height, minDepth, maxDepth) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setViewport' on 'GPUComputePassEncoder'"; @@ -2108,6 +2161,10 @@ * @param {number} height */ setScissorRect(x, y, width, height) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setScissorRect' on 'GPUComputePassEncoder'"; @@ -2141,6 +2198,11 @@ * @param {GPUColor} color */ setBlendColor(color) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setBlendColor' on 'GPUComputePassEncoder'"; @@ -2159,6 +2221,11 @@ * @param {number} reference */ setStencilReference(reference) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; @@ -2174,10 +2241,20 @@ } beginOcclusionQuery(_queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'beginOcclusionQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + + throw new Error("Not yet implemented"); } endOcclusionQuery() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'endOcclusionQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + + throw new Error("Not yet implemented"); } @@ -2186,6 +2263,10 @@ * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; @@ -2206,6 +2287,10 @@ } endPipelineStatisticsQuery() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_end_pipeline_statistics_query", { renderPassRid: this[_rid], @@ -2217,6 +2302,10 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder'"; @@ -2240,6 +2329,10 @@ * @param {GPURenderBundle[]} bundles */ executeBundles(bundles) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; @@ -2255,10 +2348,15 @@ } endPass() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'endPass' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + core.jsonOpSync("op_webgpu_render_pass_end_pass", { commandEncoderRid: this[_encoder], renderPassRid: this[_rid], }); + this[_rid] = undefined; } // TODO(lucacasonato): has an overload @@ -2269,6 +2367,10 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setBindGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( @@ -2299,6 +2401,10 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder'"; @@ -2314,6 +2420,10 @@ } popDebugGroup() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { renderPassRid: this[_rid], @@ -2324,6 +2434,10 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder'"; @@ -2342,6 +2456,10 @@ * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPURenderPassEncoder'"; @@ -2363,6 +2481,10 @@ * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder'"; @@ -2399,6 +2521,10 @@ * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder'"; @@ -2435,6 +2561,10 @@ * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'draw' on 'GPURenderPassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); @@ -2477,6 +2607,10 @@ baseVertex = 0, firstInstance = 0, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder'"; @@ -2516,6 +2650,10 @@ * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; @@ -2540,6 +2678,10 @@ * @param {number} indirectOffset */ drawIndexedIndirect(indirectBuffer, indirectOffset) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; @@ -2580,7 +2722,7 @@ /** @type {number} */ [_encoder]; - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; constructor() { @@ -2591,6 +2733,10 @@ * @param {GPUComputePipeline} pipeline */ setPipeline(pipeline) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPUComputePassEncoder'"; @@ -2611,6 +2757,10 @@ * @param {number} z */ dispatch(x, y = 1, z = 1) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'dispatch' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); @@ -2630,6 +2780,10 @@ * @param {number} indirectOffset */ dispatchIndirect(indirectBuffer, indirectOffset) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder'"; @@ -2654,6 +2808,10 @@ * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; @@ -2677,6 +2835,10 @@ } endPipelineStatisticsQuery() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { computePassRid: this[_rid], @@ -2688,6 +2850,10 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder'"; @@ -2708,11 +2874,16 @@ } endPass() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'endPass' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pass", { commandEncoderRid: this[_encoder], computePassRid: this[_rid], }); + this[_rid] = undefined; } // TODO(lucacasonato): has an overload @@ -2723,6 +2894,10 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( @@ -2753,6 +2928,10 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; @@ -2768,6 +2947,10 @@ } popDebugGroup() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { computePassRid: this[_rid], @@ -2778,6 +2961,10 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; @@ -2835,7 +3022,7 @@ } class GPURenderBundleEncoder { - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; constructor() { @@ -2846,6 +3033,10 @@ * @param {GPURenderBundleDescriptor} descriptor */ finish(descriptor = {}) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'finish' on 'GPURenderBundleEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { prefix: "Failed to execute 'finish' on 'GPURenderBundleEncoder'", @@ -2858,6 +3049,7 @@ ...descriptor, }, ); + this[_rid] = undefined; return createGPURenderBundle(descriptor.label ?? null, rid); } @@ -2870,6 +3062,10 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + const bind = bindGroup[_rid]; if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( @@ -2900,6 +3096,10 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; @@ -2915,6 +3115,10 @@ } popDebugGroup() { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); core.jsonOpSync("op_webgpu_render_bundle_encoder_pop_debug_group", { renderBundleEncoderRid: this[_rid], @@ -2925,6 +3129,10 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; @@ -2943,6 +3151,10 @@ * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'"; @@ -2964,6 +3176,10 @@ * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'"; @@ -3000,6 +3216,10 @@ * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'"; @@ -3036,6 +3256,10 @@ * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); @@ -3078,6 +3302,10 @@ baseVertex = 0, firstInstance = 0, ) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; @@ -3117,6 +3345,10 @@ * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'"; @@ -3137,6 +3369,10 @@ } drawIndexedIndirect(_indirectBuffer, _indirectOffset) { + if (this[_rid] === undefined) { + throw new DOMException("Failed to execute 'drawIndexedIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + } + throw new Error("Not yet implemented"); } } @@ -3165,7 +3401,7 @@ } GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); - const _descriptor = symbol("[[descriptor]]"); + const _descriptor = Symbol("[[descriptor]]"); /** * @param {string | null} label diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index cf02d57369d075..58f2f506ec232e 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -699,12 +699,12 @@ pub fn op_webgpu_command_encoder_finish( args: CommandEncoderFinishArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let instance = state.borrow::(); let command_encoder_resource = state .resource_table - .get::(args.command_encoder_rid) + .take::(args.command_encoder_rid) .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; + let instance = state.borrow::(); let descriptor = wgpu_types::CommandBufferDescriptor { label: args.label.map(Cow::from), diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index 6ebaafa16c0fc8..da43c092f3112f 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -211,7 +211,6 @@ pub fn op_webgpu_compute_pass_end_pass( args: ComputePassEndPassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::( @@ -221,9 +220,10 @@ pub fn op_webgpu_compute_pass_end_pass( let command_encoder = command_encoder_resource.0; let compute_pass_resource = state .resource_table - .get::(args.compute_pass_rid) + .take::(args.compute_pass_rid) .ok_or_else(bad_resource_id)?; let compute_pass = &compute_pass_resource.0.borrow(); + let instance = state.borrow::(); gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( command_encoder, diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 3861df1485e6a7..796a82210a2b45 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -290,7 +290,6 @@ pub fn op_webgpu_render_pass_end_pass( args: RenderPassEndPassArgs, _zero_copy: &mut [ZeroCopyBuf], ) -> Result { - let instance = state.borrow::(); let command_encoder_resource = state .resource_table .get::( @@ -300,9 +299,10 @@ pub fn op_webgpu_render_pass_end_pass( let command_encoder = command_encoder_resource.0; let render_pass_resource = state .resource_table - .get::(args.render_pass_rid) + .take::(args.render_pass_rid) .ok_or_else(bad_resource_id)?; let render_pass = &render_pass_resource.0.borrow(); + let instance = state.borrow::(); gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; From b2694bb999db38d75ac1d8851184c73a8df40c43 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 20:58:40 +0100 Subject: [PATCH 117/144] initial inspect stuff --- op_crates/webgpu/01_webgpu.js | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 5286a316b2fa3b..27f403b762e200 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -178,6 +178,14 @@ }, ); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + name: this.name, + features: this.features, + limits: this.limits, + })}`; + } } const _limits = Symbol("[[limits]]"); @@ -268,6 +276,10 @@ get maxVertexBufferArrayStride() { throw new TypeError("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect(this[_limits])}`; + } } const _features = Symbol("[[features]]"); @@ -302,7 +314,7 @@ return this[_features].has(value); } - /** @return {string[]} */ + /** @return {IterableIterator} */ keys() { return this[_features].keys(); } @@ -320,6 +332,10 @@ [Symbol.iterator]() { return this[_features][Symbol.iterator](); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect([...this.values()])}`; + } } const _label = Symbol("[[label]]"); @@ -749,6 +765,16 @@ return createGPUQuerySet(descriptor.label ?? null, rid, descriptor); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + adapter: this.adapter, + features: this.features, + label: this.label, + limits: this.limits, + queue: this.queue, + })}`; + } } GPUObjectBaseMixin("GPUDevice", GPUDevice); @@ -893,6 +919,12 @@ copyImageBitmapToTexture(_source, _destination, _copySize) { throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUQueue", GPUQueue); From 8cdd3676dbc773c3363cb29c2def7375cdc11a85 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 18 Feb 2021 22:54:19 +0100 Subject: [PATCH 118/144] first cleanup --- op_crates/webgpu/01_webgpu.js | 52 ++++++++++++++++++++++++++++++-- op_crates/webgpu/02_idl_types.js | 22 ++++++++------ runtime/js/99_main.js | 2 ++ 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 6f03ddf813b9c3..305a735a655390 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -50,6 +50,25 @@ } } + class GPUOutOfMemoryError extends Error { + constructor() { + super(); + } + } + + class GPUValidationError extends Error { + /** @param {string} message */ + constructor(message) { + const prefix = "Failed to construct 'GPUValidationError'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + message = webidl.converters.DOMString(message, { + prefix, + context: "Argument 1", + }); + super(message); + } + } + class GPU { [webidl.brand] = webidl.brand; @@ -84,6 +103,7 @@ const _name = Symbol("[[name]]"); const _adapter = Symbol("[[adapter]]"); + const _cleanup = Symbol("[[cleanup]]"); /** * @typedef InnerGPUAdapter @@ -409,6 +429,7 @@ /** * @param {GPUBufferDescriptor} descriptor + * @returns {GPUBuffer} */ createBuffer(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -2700,6 +2721,11 @@ prefix, context: "Argument 2", }); + const querySetRid = querySet[_rid]; + if (querySetRid === undefined) { + throw new GPUValidationError(`${prefix}: GPUQuerySet is not valid.`); + } + core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { computePassRid: this[_rid], querySet: querySet[_rid], @@ -3156,9 +3182,18 @@ } class GPURenderBundle { - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -3179,16 +3214,25 @@ } class GPUQuerySet { - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } destroy() { webidl.assertBranded(this, GPUQuerySet); - throw new Error("Not yet implemented"); + this[_cleanup](); } } GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); @@ -3223,5 +3267,7 @@ GPURenderBundleEncoder, GPURenderBundle, GPUQuerySet, + GPUOutOfMemoryError, + GPUValidationError, }; })(this); diff --git a/op_crates/webgpu/02_idl_types.js b/op_crates/webgpu/02_idl_types.js index eb3c07a3624e65..68c3e324751dd8 100644 --- a/op_crates/webgpu/02_idl_types.js +++ b/op_crates/webgpu/02_idl_types.js @@ -36,6 +36,8 @@ GPURenderBundleEncoder, GPURenderBundle, GPUQuerySet, + GPUOutOfMemoryError, + GPUValidationError, } = window.__bootstrap.webgpu; // This needs to be initalized after all of the base classes are implmented, @@ -1663,17 +1665,17 @@ ], ); - // // INTERFACE: GPUOutOfMemoryError - // webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( - // "GPUOutOfMemoryError", - // GPUOutOfMemoryError, - // ); + // INTERFACE: GPUOutOfMemoryError + webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( + "GPUOutOfMemoryError", + GPUOutOfMemoryError, + ); - // // INTERFACE: GPUValidationError - // webidl.converters.GPUValidationError = webidl.createInterfaceConverter( - // "GPUValidationError", - // GPUValidationError, - // ); + // INTERFACE: GPUValidationError + webidl.converters.GPUValidationError = webidl.createInterfaceConverter( + "GPUValidationError", + GPUValidationError, + ); // TYPEDEF: GPUError webidl.converters["GPUError"] = webidl.converters.any; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 4e28a11777e1a4..47d4508aeb8c1c 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -279,6 +279,8 @@ delete Object.prototype.__proto__; GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder), GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), + GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), + GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), }; // The console seems to be the only one that should be writable and non-enumerable From c5d3b1b3a4ffc3eee1b8c3e5f649713b3a10375f Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 23:14:01 +0100 Subject: [PATCH 119/144] add inspect for all classes --- op_crates/webgpu/01_webgpu.js | 105 +++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 27f403b762e200..2073e83b6be9d9 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1237,6 +1237,12 @@ destroy() { throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } class GPUBufferUsage { @@ -1333,6 +1339,12 @@ destroy() { throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUTexture", GPUTexture); @@ -1377,6 +1389,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUTextureView", GPUTextureView); @@ -1399,6 +1417,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUSampler", GPUSampler); @@ -1421,6 +1445,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUBindGroupLayout", GPUBindGroupLayout); @@ -1443,6 +1473,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUPipelineLayout", GPUPipelineLayout); @@ -1465,6 +1501,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUBindGroup", GPUBindGroup); @@ -1491,6 +1533,12 @@ compilationInfo() { throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); @@ -1554,6 +1602,12 @@ return createGPUBindGroupLayout(label, rid); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); @@ -1599,6 +1653,12 @@ return createGPUBindGroupLayout(label, rid); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); @@ -2112,6 +2172,12 @@ return createGPUCommandBuffer(descriptor.label ?? null, rid); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); @@ -2732,6 +2798,12 @@ indirectOffset, }); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPURenderPassEncoder", GPURenderPassEncoder); @@ -3010,6 +3082,12 @@ markerLabel, }); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUComputePassEncoder", GPUComputePassEncoder); @@ -3034,9 +3112,16 @@ webidl.illegalConstructor(); } - get executionTime() { + async get executionTime() { throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + // TODO: executionTime + })}`; + } } GPUObjectBaseMixin("GPUCommandBuffer", GPUCommandBuffer); @@ -3407,6 +3492,12 @@ throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder); @@ -3430,6 +3521,12 @@ constructor() { webidl.illegalConstructor(); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); @@ -3463,6 +3560,12 @@ webidl.assertBranded(this, GPUQuerySet); throw new Error("Not yet implemented"); } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({ + label: this.label, + })}`; + } } GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); From 60ad162332f8cdec06c11b8daf309ee3d8d347e8 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 23:30:25 +0100 Subject: [PATCH 120/144] add createPipelineAsync polyfills --- op_crates/webgpu/01_webgpu.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 2073e83b6be9d9..b0858cc6f2cdd0 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -692,12 +692,12 @@ return createGPURenderPipeline(descriptor.label ?? null, rid); } - createComputePipelineAsync(_descriptor) { - throw new Error("Not yet implemented"); // easy polyfill + async createComputePipelineAsync(descriptor) { + return this.createComputePipeline(descriptor); } - createRenderPipelineAsync(_descriptor) { - throw new Error("Not yet implemented"); // easy polyfill + async createRenderPipelineAsync(descriptor) { + return this.createRenderPipeline(descriptor); } /** From aaa382c47dff5d71a3a852f7f525e43e3c775ce1 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Thu, 18 Feb 2021 23:34:11 +0100 Subject: [PATCH 121/144] fix async get --- op_crates/webgpu/01_webgpu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index b0858cc6f2cdd0..4ab42964483859 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -3112,7 +3112,7 @@ webidl.illegalConstructor(); } - async get executionTime() { + get executionTime() { throw new Error("Not yet implemented"); } From 4224a2a942bbe2a8aa159a310835b37963b83377 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 01:36:48 +0100 Subject: [PATCH 122/144] resource cleanup --- op_crates/webgpu/01_webgpu.js | 872 +++++++++++++++++++++++++++------- 1 file changed, 699 insertions(+), 173 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 9ccbf9da3ae5e2..a1e3e734951304 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -187,24 +187,29 @@ }, ); + /** @type {InnerGPUDevice} */ + const inner = { + rid, + adapter: this, + features: Object.freeze(features), + limits: Object.freeze(limits), + resources: [], + }; return createGPUDevice( descriptor.label ?? null, - { - rid, - adapter: this, - features: Object.freeze(features), - limits: Object.freeze(limits), - queue: createGPUQueue(descriptor.label ?? null, rid), - }, + inner, + createGPUQueue(descriptor.label ?? null, inner), ); } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - name: this.name, - features: this.features, - limits: this.limits, - })}`; + return `${this.constructor.name} ${ + inspect({ + name: this.name, + features: this.features, + limits: this.limits, + }) + }`; } } @@ -389,26 +394,29 @@ } const _device = Symbol("[[device]]"); + const _queue = Symbol("[[queue]]"); /** * @typedef InnerGPUDevice * @property {GPUAdapter} adapter - * @property {number} rid + * @property {number | undefined} rid * @property {GPUFeatureName[]} features * @property {object} limits - * @property {GPUQueue} queue + * @property {WeakRef[]} resources */ /** * @param {string | null} label * @param {InnerGPUDevice} inner + * @param {GPUQueue} queue * @returns {GPUDevice} */ - function createGPUDevice(label, inner) { + function createGPUDevice(label, inner, queue) { /** @type {GPUDevice} */ const device = webidl.createBranded(GPUDevice); device[_label] = label; device[_device] = inner; + device[_queue] = queue; return device; } @@ -417,6 +425,26 @@ /** @type {InnerGPUDevice} */ [_device]; + /** @type {GPUQueue} */ + [_queue]; + + [_cleanup]() { + const device = this[_device]; + const resources = device.resources; + while (resources.length > 0) { + const resource = resources.pop()?.deref(); + if (resource) { + resource[_cleanup](); + } + } + const rid = device.rid; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + device.rid = undefined; + } + } + get adapter() { webidl.assertBranded(this, GPUDevice); return this[_device].adapter; @@ -431,7 +459,7 @@ } get queue() { webidl.assertBranded(this, GPUDevice); - return this[_device].queue; + return this[_queue]; } constructor() { @@ -440,7 +468,8 @@ } destroy() { - throw new Error("Not yet implemented"); + webidl.assertBranded(this, GPUDevice); + this[_cleanup](); } /** @@ -476,18 +505,21 @@ state: "unmapped", }; } - return createGPUBuffer( + const buffer = createGPUBuffer( descriptor.label ?? null, - this[_device].rid, + this[_device], rid, descriptor.size, descriptor.usage, options, ); + this[_device].resources.push(new WeakRef(buffer)); + return buffer; } /** * @param {GPUTextureDescriptor} descriptor + * @returns {GPUTexture} */ createTexture(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -503,16 +535,22 @@ size: normalizeGPUExtent3D(descriptor.size), }); - return createGPUTexture(descriptor.label ?? null, rid); + const texture = createGPUTexture( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(texture)); + return texture; } /** * @param {GPUSamplerDescriptor} descriptor + * @returns {GPUSampler} */ createSampler(descriptor = {}) { webidl.assertBranded(this, GPUDevice); const prefix = "Failed to execute 'createSampler' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); descriptor = webidl.converters.GPUSamplerDescriptor(descriptor, { prefix, context: "Argument 1", @@ -522,11 +560,18 @@ ...descriptor, }); - return createGPUSampler(descriptor.label ?? null, rid); + const sampler = createGPUSampler( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(sampler)); + return sampler; } /** * @param {GPUBindGroupLayoutDescriptor} descriptor + * @returns {GPUBindGroupLayout} */ createBindGroupLayout(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -553,11 +598,18 @@ ...descriptor, }); - return createGPUBindGroupLayout(descriptor.label ?? null, rid); + const bindGroupLayout = createGPUBindGroupLayout( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(bindGroupLayout)); + return bindGroupLayout; } /** * @param {GPUPipelineLayoutDescriptor} descriptor + * @returns {GPUPipelineLayout} */ createPipelineLayout(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -575,11 +627,18 @@ ), }); - return createGPUPipelineLayout(descriptor.label ?? null, rid); + const pipelineLayout = createGPUPipelineLayout( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(pipelineLayout)); + return pipelineLayout; } /** * @param {GPUBindGroupDescriptor} descriptor + * @returns {GPUBindGroup} */ createBindGroup(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -618,7 +677,13 @@ }), }); - return createGPUBindGroup(descriptor.label ?? null, rid); + const bindGroup = createGPUBindGroup( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(bindGroup)); + return bindGroup; } /** @@ -647,11 +712,18 @@ : []), ); - return createGPUShaderModule(descriptor.label ?? null, rid); + const shaderModule = createGPUShaderModule( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(shaderModule)); + return shaderModule; } /** * @param {GPUComputePipelineDescriptor} descriptor + * @returns {GPUComputePipeline} */ createComputePipeline(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -671,11 +743,18 @@ }, }); - return createGPUComputePipeline(descriptor.label ?? null, rid); + const computePipeline = createGPUComputePipeline( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(computePipeline)); + return computePipeline; } /** * @param {GPURenderPipelineDescriptor} descriptor + * @returns {GPURenderPipeline} */ createRenderPipeline(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -710,7 +789,13 @@ ...d, }); - return createGPURenderPipeline(descriptor.label ?? null, rid); + const renderPipeline = createGPURenderPipeline( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(renderPipeline)); + return renderPipeline; } createComputePipelineAsync(_descriptor) { @@ -723,6 +808,7 @@ /** * @param {GPUCommandEncoderDescriptor} descriptor + * @returns {GPUCommandEncoder} */ createCommandEncoder(descriptor = {}) { webidl.assertBranded(this, GPUDevice); @@ -736,11 +822,18 @@ ...descriptor, }); - return createGPUCommandEncoder(descriptor.label ?? null, rid); + const commandEncoder = createGPUCommandEncoder( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(commandEncoder)); + return commandEncoder; } /** * @param {GPURenderBundleEncoderDescriptor} descriptor + * @returns {GPURenderBundleEncoder} */ createRenderBundleEncoder(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -762,11 +855,18 @@ }, ); - return createGPURenderBundleEncoder(descriptor.label ?? null, rid); + const renderBundleEncoder = createGPURenderBundleEncoder( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(renderBundleEncoder)); + return renderBundleEncoder; } /** * @param {GPUQuerySetDescriptor} descriptor + * @returns {GPUQuerySet} */ createQuerySet(descriptor) { webidl.assertBranded(this, GPUDevice); @@ -784,39 +884,45 @@ ...descriptor, }); - return createGPUQuerySet(descriptor.label ?? null, rid, descriptor); + const querySet = createGPUQuerySet( + descriptor.label ?? null, + this[_device], + rid, + descriptor, + ); + this[_device].resources.push(new WeakRef(querySet)); + return querySet; } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - adapter: this.adapter, - features: this.features, - label: this.label, - limits: this.limits, - queue: this.queue, - })}`; + return `${this.constructor.name} ${ + inspect({ + adapter: this.adapter, + features: this.features, + label: this.label, + limits: this.limits, + queue: this.queue, + }) + }`; } } GPUObjectBaseMixin("GPUDevice", GPUDevice); /** * @param {string | null} label - * @param {number} rid + * @param {InnerGPUDevice} device * @returns {GPUQueue} */ - function createGPUQueue(label, rid) { + function createGPUQueue(label, device) { /** @type {GPUQueue} */ const queue = webidl.createBranded(GPUQueue); queue[_label] = label; - queue[_device] = rid; + queue[_device] = device; return queue; } class GPUQueue { - /** - * The rid of the related device. - * @type {number} - */ + /** @type {InnerGPUDevice} */ [_device]; constructor() { @@ -883,7 +989,7 @@ core.jsonOpSync( "op_webgpu_write_buffer", { - queueRid: this[_device], + queueRid: this[_device].rid, buffer: buffer[_rid], bufferOffset, dataOffset, @@ -923,7 +1029,7 @@ core.jsonOpSync( "op_webgpu_write_texture", { - queueRid: this[_device], + queueRid: this[_device].rid, destination: { texture: destination.texture[_rid], mipLevel: destination.mipLevel, @@ -942,9 +1048,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUQueue", GPUQueue); @@ -968,18 +1076,18 @@ /** * @param {string | null} label - * @param {number} deviceRid + * @param {InnerGPUDevice} device * @param {number} rid * @param {number} size * @param {number} usage * @param {CreateGPUBufferOptions} options * @returns {GPUBuffer} */ - function createGPUBuffer(label, deviceRid, rid, size, usage, options) { + function createGPUBuffer(label, device, rid, size, usage, options) { /** @type {GPUBuffer} */ const buffer = webidl.createBranded(GPUBuffer); buffer[_label] = label; - buffer[_device] = deviceRid; + buffer[_device] = device; buffer[_rid] = rid; buffer[_size] = size; buffer[_usage] = usage; @@ -990,7 +1098,7 @@ } class GPUBuffer { - /** @type {number} */ + /** @type {InnerGPUDevice} */ [_device]; /** @type {number} */ @@ -1014,6 +1122,15 @@ /** @type {number} */ [_mapMode]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1099,7 +1216,7 @@ "op_webgpu_buffer_get_map_async", { bufferRid: this[_rid], - deviceRid: this[_device], + deviceRid: this[_device].rid, mode, offset, size: rangeSize, @@ -1256,9 +1373,11 @@ } destroy() { - throw new Error("Not yet implemented"); + webidl.assertBranded(this, GPUBuffer); + this[_cleanup](); } } + GPUObjectBaseMixin("GPUBuffer", GPUBuffer); class GPUBufferUsage { constructor() { @@ -1310,22 +1429,46 @@ } } + const _views = Symbol("[[views]]"); + /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUTexture} */ - function createGPUTexture(label, rid) { + function createGPUTexture(label, device, rid) { /** @type {GPUTexture} */ const texture = webidl.createBranded(GPUTexture); texture[_label] = label; + texture[_device] = device; texture[_rid] = rid; return texture; } class GPUTexture { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + /** @type {WeakRef[]} */ + [_views] = []; + + [_cleanup]() { + const views = this[_views]; + while (views.length > 0) { + const view = views.pop()?.deref(); + if (view) { + view[_cleanup](); + } + } + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } constructor() { webidl.illegalConstructor(); @@ -1348,11 +1491,18 @@ ...descriptor, }); - return createGPUTextureView(descriptor.label ?? null, rid); + const textureView = createGPUTextureView( + descriptor.label ?? null, + this, + rid, + ); + this[_views].push(new WeakRef(textureView)); + return textureView; } destroy() { - throw new Error("Not yet implemented"); + webidl.assertBranded(this, GPUTexture); + this[_cleanup](); } } GPUObjectBaseMixin("GPUTexture", GPUTexture); @@ -1379,22 +1529,37 @@ } } + const _texture = Symbol("[[texture]]"); + /** * @param {string | null} label + * @param {GPUTexture} texture * @param {number} rid * @returns {GPUTextureView} */ - function createGPUTextureView(label, rid) { + function createGPUTextureView(label, texture, rid) { /** @type {GPUTextureView} */ const textureView = webidl.createBranded(GPUTextureView); textureView[_label] = label; + textureView[_texture] = texture; textureView[_rid] = rid; return textureView; } class GPUTextureView { - /** @type {number} */ + /** @type {GPUTexture} */ + [_texture]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1403,20 +1568,33 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUSampler} */ - function createGPUSampler(label, rid) { + function createGPUSampler(label, device, rid) { /** @type {GPUSampler} */ const sampler = webidl.createBranded(GPUSampler); sampler[_label] = label; + sampler[_device] = device; sampler[_rid] = rid; return sampler; } class GPUSampler { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1425,20 +1603,33 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUBindGroupLayout} */ - function createGPUBindGroupLayout(label, rid) { + function createGPUBindGroupLayout(label, device, rid) { /** @type {GPUBindGroupLayout} */ const bindGroupLayout = webidl.createBranded(GPUBindGroupLayout); bindGroupLayout[_label] = label; + bindGroupLayout[_device] = device; bindGroupLayout[_rid] = rid; return bindGroupLayout; } class GPUBindGroupLayout { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1447,20 +1638,33 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUPipelineLayout} */ - function createGPUPipelineLayout(label, rid) { + function createGPUPipelineLayout(label, device, rid) { /** @type {GPUPipelineLayout} */ const pipelineLayout = webidl.createBranded(GPUPipelineLayout); pipelineLayout[_label] = label; + pipelineLayout[_device] = device; pipelineLayout[_rid] = rid; return pipelineLayout; } class GPUPipelineLayout { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1469,20 +1673,31 @@ /** * @param {string | null} label - * @param {number} rid + * @param {InnerGPUDevice} device + * @param {number} rid * @returns {GPUBindGroup} */ - function createGPUBindGroup(label, rid) { + function createGPUBindGroup(label, device, rid) { /** @type {GPUBindGroup} */ const bindGroup = webidl.createBranded(GPUBindGroup); bindGroup[_label] = label; + bindGroup[_device] = device; bindGroup[_rid] = rid; return bindGroup; } class GPUBindGroup { - /** @type {number} */ + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1491,20 +1706,33 @@ /** * @param {string | null} label - * @param {number} rid + * @param {InnerGPUDevice} device + * @param {number} rid * @returns {GPUShaderModule} */ - function createGPUShaderModule(label, rid) { + function createGPUShaderModule(label, device, rid) { /** @type {GPUShaderModule} */ const bindGroup = webidl.createBranded(GPUShaderModule); bindGroup[_label] = label; + bindGroup[_device] = device; bindGroup[_rid] = rid; return bindGroup; } class GPUShaderModule { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1535,26 +1763,40 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUComputePipeline} */ - function createGPUComputePipeline(label, rid) { + function createGPUComputePipeline(label, device, rid) { /** @type {GPUComputePipeline} */ const pipeline = webidl.createBranded(GPUComputePipeline); pipeline[_label] = label; + pipeline[_device] = device; pipeline[_rid] = rid; return pipeline; } class GPUComputePipeline { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } /** * @param {number} index + * @returns {GPUBindGroupLayout} */ getBindGroupLayout(index) { webidl.assertBranded(this, GPURenderPipeline); @@ -1573,27 +1815,46 @@ }, ); - return createGPUBindGroupLayout(label, rid); + const bindGroupLayout = createGPUBindGroupLayout( + label, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(bindGroupLayout)); + return bindGroupLayout; } } GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPURenderPipeline} */ - function createGPURenderPipeline(label, rid) { + function createGPURenderPipeline(label, device, rid) { /** @type {GPURenderPipeline} */ const pipeline = webidl.createBranded(GPURenderPipeline); pipeline[_label] = label; + pipeline[_device] = device; pipeline[_rid] = rid; return pipeline; } class GPURenderPipeline { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -1618,7 +1879,13 @@ }, ); - return createGPUBindGroupLayout(label, rid); + const bindGroupLayout = createGPUBindGroupLayout( + label, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(bindGroupLayout)); + return bindGroupLayout; } } GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); @@ -1645,22 +1912,45 @@ } } + const _encoders = Symbol("[[encoders]]"); + /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUCommandEncoder} */ - function createGPUCommandEncoder(label, rid) { + function createGPUCommandEncoder(label, device, rid) { /** @type {GPUCommandEncoder} */ const encoder = webidl.createBranded(GPUCommandEncoder); encoder[_label] = label; + encoder[_device] = device; encoder[_rid] = rid; return encoder; } - class GPUCommandEncoder { + /** @type {InnerGPUDevice} */ + [_device]; /** @type {number | undefined} */ [_rid]; + /** @type {WeakRef[]} */ + [_encoders] = []; + + [_cleanup]() { + const encoders = this[_encoders]; + while (encoders.length > 0) { + const encoder = encoders.pop()?.deref(); + if (encoder) { + encoder[_cleanup](); + } + } + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } constructor() { webidl.illegalConstructor(); @@ -1672,7 +1962,10 @@ */ beginRenderPass(descriptor) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1746,11 +2039,13 @@ }, ); - return createGPURenderPassEncoder( + const renderPassEncoder = createGPURenderPassEncoder( descriptor.label ?? null, - this[_rid], + this, rid, ); + this[_encoders].push(new WeakRef(renderPassEncoder)); + return renderPassEncoder; } /** @@ -1758,7 +2053,10 @@ */ beginComputePass(descriptor = {}) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1777,11 +2075,13 @@ }, ); - return createGPUComputePassEncoder( + const computePassEncoder = createGPUComputePassEncoder( descriptor.label ?? null, this[_rid], rid, ); + this[_encoders].push(new WeakRef(computePassEncoder)); + return computePassEncoder; } /** @@ -1799,7 +2099,10 @@ size, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1846,7 +2149,10 @@ */ copyBufferToTexture(source, destination, copySize) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1892,7 +2198,10 @@ */ copyTextureToBuffer(source, destination, copySize) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1936,7 +2245,10 @@ */ copyTextureToTexture(source, destination, copySize) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1980,7 +2292,10 @@ */ pushDebugGroup(groupLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -1999,7 +2314,10 @@ popDebugGroup() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -2013,7 +2331,10 @@ */ insertDebugMarker(markerLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -2036,7 +2357,10 @@ */ writeTimestamp(querySet, queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -2073,7 +2397,10 @@ destinationOffset, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -2116,7 +2443,10 @@ */ finish(descriptor = {}) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'finish' on 'GPUCommandEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'finish' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUCommandEncoder); @@ -2129,9 +2459,16 @@ commandEncoderRid: this[_rid], ...descriptor, }); + /** @type {number | undefined} */ this[_rid] = undefined; - return createGPUCommandBuffer(descriptor.label ?? null, rid); + const commandBuffer = createGPUCommandBuffer( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(commandBuffer)); + return commandBuffer; } } GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); @@ -2140,25 +2477,34 @@ /** * @param {string | null} label - * @param {number} encoderRid + * @param {GPUCommandEncoder} encoder * @param {number} rid * @returns {GPURenderPassEncoder} */ - function createGPURenderPassEncoder(label, encoderRid, rid) { + function createGPURenderPassEncoder(label, encoder, rid) { /** @type {GPURenderPassEncoder} */ - const encoder = webidl.createBranded(GPURenderPassEncoder); - encoder[_label] = label; - encoder[_encoder] = encoderRid; - encoder[_rid] = rid; - return encoder; + const passEncoder = webidl.createBranded(GPURenderPassEncoder); + passEncoder[_label] = label; + passEncoder[_encoder] = encoder; + passEncoder[_rid] = rid; + return passEncoder; } class GPURenderPassEncoder { - /** @type {number} */ + /** @type {GPUCommandEncoder} */ [_encoder]; /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -2173,7 +2519,10 @@ */ setViewport(x, y, width, height, minDepth, maxDepth) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2215,7 +2564,10 @@ */ setScissorRect(x, y, width, height) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2252,10 +2604,12 @@ */ setBlendColor(color) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setBlendColor' on 'GPUComputePassEncoder'"; @@ -2275,10 +2629,12 @@ */ setStencilReference(reference) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; @@ -2295,19 +2651,23 @@ beginOcclusionQuery(_queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'beginOcclusionQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'beginOcclusionQuery' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } - throw new Error("Not yet implemented"); } endOcclusionQuery() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'endOcclusionQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'endOcclusionQuery' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } - throw new Error("Not yet implemented"); } @@ -2317,7 +2677,10 @@ */ beginPipelineStatisticsQuery(querySet, queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2341,7 +2704,10 @@ endPipelineStatisticsQuery() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2356,7 +2722,10 @@ */ writeTimestamp(querySet, queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2383,7 +2752,10 @@ */ executeBundles(bundles) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2402,7 +2774,10 @@ endPass() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'endPass' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'endPass' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } core.jsonOpSync("op_webgpu_render_pass_end_pass", { @@ -2421,7 +2796,10 @@ dynamicOffsetsDataLength, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setBindGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setBindGroup' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } const bind = bindGroup[_rid]; @@ -2455,7 +2833,10 @@ */ pushDebugGroup(groupLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2474,7 +2855,10 @@ popDebugGroup() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2488,7 +2872,10 @@ */ insertDebugMarker(markerLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2510,7 +2897,10 @@ */ setPipeline(pipeline) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2535,7 +2925,10 @@ */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2575,7 +2968,10 @@ */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2615,7 +3011,10 @@ */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2661,7 +3060,10 @@ firstInstance = 0, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2704,7 +3106,10 @@ */ drawIndirect(indirectBuffer, indirectOffset) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2732,7 +3137,10 @@ */ drawIndexedIndirect(indirectBuffer, indirectOffset) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderPassEncoder); @@ -2758,26 +3166,35 @@ /** * @param {string | null} label - * @param {number} encoderRid + * @param {GPUCommandEncoder} encoder * @param {number} rid * @returns {GPUComputePassEncoder} */ - function createGPUComputePassEncoder(label, encoderRid, rid) { + function createGPUComputePassEncoder(label, encoder, rid) { /** @type {GPUComputePassEncoder} */ - const commandBuffer = webidl.createBranded(GPUComputePassEncoder); - commandBuffer[_label] = label; - commandBuffer[_encoder] = encoderRid; - commandBuffer[_rid] = rid; - return commandBuffer; + const computePassEncoder = webidl.createBranded(GPUComputePassEncoder); + computePassEncoder[_label] = label; + computePassEncoder[_encoder] = encoder; + computePassEncoder[_rid] = rid; + return computePassEncoder; } class GPUComputePassEncoder { - /** @type {number} */ + /** @type {GPUCommandEncoder} */ [_encoder]; /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -2787,7 +3204,10 @@ */ setPipeline(pipeline) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2811,7 +3231,10 @@ */ dispatch(x, y = 1, z = 1) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'dispatch' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'dispatch' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2834,7 +3257,10 @@ */ dispatchIndirect(indirectBuffer, indirectOffset) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2862,7 +3288,10 @@ */ beginPipelineStatisticsQuery(querySet, queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2889,7 +3318,10 @@ endPipelineStatisticsQuery() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2904,7 +3336,10 @@ */ writeTimestamp(querySet, queryIndex) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2933,7 +3368,10 @@ endPass() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'endPass' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'endPass' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -2953,7 +3391,10 @@ dynamicOffsetsDataLength, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } const bind = bindGroup[_rid]; @@ -2987,7 +3428,10 @@ */ pushDebugGroup(groupLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -3006,7 +3450,10 @@ popDebugGroup() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -3020,7 +3467,10 @@ */ insertDebugMarker(markerLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPUComputePassEncoder); @@ -3041,21 +3491,34 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUCommandBuffer} */ - function createGPUCommandBuffer(label, rid) { + function createGPUCommandBuffer(label, device, rid) { /** @type {GPUCommandBuffer} */ const commandBuffer = webidl.createBranded(GPUCommandBuffer); commandBuffer[_label] = label; + commandBuffer[_device] = device; commandBuffer[_rid] = rid; return commandBuffer; } class GPUCommandBuffer { - /** @type {number} */ + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -3068,21 +3531,34 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPURenderBundleEncoder} */ - function createGPURenderBundleEncoder(label, rid) { + function createGPURenderBundleEncoder(label, device, rid) { /** @type {GPURenderBundleEncoder} */ - const bundle = webidl.createBranded(GPURenderBundleEncoder); - bundle[_label] = label; - bundle[_rid] = rid; - return bundle; + const bundleEncoder = webidl.createBranded(GPURenderBundleEncoder); + bundleEncoder[_label] = label; + bundleEncoder[_device] = device; + bundleEncoder[_rid] = rid; + return bundleEncoder; } class GPURenderBundleEncoder { + /** @type {InnerGPUDevice} */ + [_device]; /** @type {number | undefined} */ [_rid]; + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + constructor() { webidl.illegalConstructor(); } @@ -3092,7 +3568,10 @@ */ finish(descriptor = {}) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'finish' on 'GPURenderBundleEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'finish' on 'GPURenderBundleEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3109,7 +3588,13 @@ ); this[_rid] = undefined; - return createGPURenderBundle(descriptor.label ?? null, rid); + const renderBundle = createGPURenderBundle( + descriptor.label ?? null, + this[_device], + rid, + ); + this[_device].resources.push(new WeakRef(renderBundle)); + return renderBundle; } // TODO(lucacasonato): has an overload @@ -3121,7 +3606,10 @@ dynamicOffsetsDataLength, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } const bind = bindGroup[_rid]; @@ -3155,7 +3643,10 @@ */ pushDebugGroup(groupLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3174,7 +3665,10 @@ popDebugGroup() { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3188,7 +3682,10 @@ */ insertDebugMarker(markerLabel) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3210,7 +3707,10 @@ */ setPipeline(pipeline) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3235,7 +3735,10 @@ */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3275,7 +3778,10 @@ */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3315,7 +3821,10 @@ */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3361,7 +3870,10 @@ firstInstance = 0, ) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3404,7 +3916,10 @@ */ drawIndirect(indirectBuffer, indirectOffset) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } webidl.assertBranded(this, GPURenderBundleEncoder); @@ -3428,7 +3943,10 @@ drawIndexedIndirect(_indirectBuffer, _indirectOffset) { if (this[_rid] === undefined) { - throw new DOMException("Failed to execute 'drawIndexedIndirect' on 'GPUComputePassEncoder': already consumed", "OperationError"); + throw new DOMException( + "Failed to execute 'drawIndexedIndirect' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); } throw new Error("Not yet implemented"); @@ -3438,18 +3956,22 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPURenderBundle} */ - function createGPURenderBundle(label, rid) { + function createGPURenderBundle(label, device, rid) { /** @type {GPURenderBundle} */ const bundle = webidl.createBranded(GPURenderBundle); bundle[_label] = label; + bundle[_device] = device; bundle[_rid] = rid; return bundle; } class GPURenderBundle { + /** @type {InnerGPUDevice} */ + [_device]; /** @type {number | undefined} */ [_rid]; @@ -3472,19 +3994,23 @@ /** * @param {string | null} label + * @param {InnerGPUDevice} device * @param {number} rid * @returns {GPUQuerySet} */ - function createGPUQuerySet(label, rid, descriptor) { + function createGPUQuerySet(label, device, rid, descriptor) { /** @type {GPUQuerySet} */ const queue = webidl.createBranded(GPUQuerySet); queue[_label] = label; + queue[_device] = device; queue[_rid] = rid; queue[_descriptor] = descriptor; return queue; } class GPUQuerySet { + /** @type {InnerGPUDevice} */ + [_device]; /** @type {number | undefined} */ [_rid]; /** @type {GPUQuerySetDescriptor} */ From c70f02982ff039bcce6b37ed99b170987053676b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 02:17:55 +0100 Subject: [PATCH 123/144] fmt --- op_crates/webgpu/01_webgpu.js | 138 +++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 52 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 2917ae098bd740..4c44fcba89fd15 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1378,9 +1378,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUBuffer", GPUBuffer); @@ -1512,9 +1514,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUTexture", GPUTexture); @@ -1577,9 +1581,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUTextureView", GPUTextureView); @@ -1618,9 +1624,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUSampler", GPUSampler); @@ -1659,9 +1667,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUBindGroupLayout", GPUBindGroupLayout); @@ -1700,9 +1710,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUPipelineLayout", GPUPipelineLayout); @@ -1739,9 +1751,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUBindGroup", GPUBindGroup); @@ -1784,9 +1798,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); @@ -1873,9 +1889,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); @@ -1943,9 +1961,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); @@ -2532,9 +2552,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); @@ -3229,9 +3251,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPURenderPassEncoder", GPURenderPassEncoder); @@ -3560,9 +3584,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUComputePassEncoder", GPUComputePassEncoder); @@ -3606,10 +3632,12 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - // TODO: executionTime - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + // TODO: executionTime + }) + }`; } } GPUObjectBaseMixin("GPUCommandBuffer", GPUCommandBuffer); @@ -4038,9 +4066,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder); @@ -4080,9 +4110,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); @@ -4132,9 +4164,11 @@ } [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({ - label: this.label, - })}`; + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; } } GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); From 13a73e9e8222e49c4d40f301a46079817f64610c Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 02:19:08 +0100 Subject: [PATCH 124/144] fmt + lint --- op_crates/webgpu/01_webgpu.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 4c44fcba89fd15..7d2fabd62743ab 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -798,12 +798,14 @@ return renderPipeline; } - async createComputePipelineAsync(descriptor) { - return this.createComputePipeline(descriptor); + createComputePipelineAsync(descriptor) { + // TODO(lucacasonato): this should be real async + return Promise.resolve(this.createComputePipeline(descriptor)); } - async createRenderPipelineAsync(descriptor) { - return this.createRenderPipeline(descriptor); + createRenderPipelineAsync(descriptor) { + // TODO(lucacasonato): this should be real async + return Promise.resolve(this.createRenderPipeline(descriptor)); } /** @@ -3635,7 +3637,7 @@ return `${this.constructor.name} ${ inspect({ label: this.label, - // TODO: executionTime + // TODO(crowlKats): executionTime }) }`; } From 1b1f9be2f20edd29a429610d4b3168ba6ed78323 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 02:43:23 +0100 Subject: [PATCH 125/144] unit test passes --- op_crates/webgpu/01_webgpu.js | 18 +++++++++++++++--- op_crates/webgpu/buffer.rs | 8 ++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7d2fabd62743ab..5b74080f3d1b1c 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -945,7 +945,7 @@ { prefix, context: "Argument 1" }, ); core.jsonOpSync("op_webgpu_queue_submit", { - queueRid: this[_device], + queueRid: this[_device].rid, commandBuffers: commandBuffers.map((buffer) => buffer[_rid]), }); } @@ -1125,12 +1125,22 @@ [_mapMode]; [_cleanup]() { + const mappedRanges = this[_mappedRanges]; + if (mappedRanges) { + while (mappedRanges.length > 0) { + const mappedRange = mappedRanges.pop(); + if (mappedRange !== undefined) { + core.close(mappedRange[1]); + } + } + } const rid = this[_rid]; if (rid !== undefined) { core.close(rid); /** @type {number | undefined} */ this[_rid] = undefined; } + this[_state] = "destroy"; } constructor() { @@ -1453,6 +1463,7 @@ texture[_label] = label; texture[_device] = device; texture[_rid] = rid; + texture[_views] = []; return texture; } @@ -1462,7 +1473,7 @@ /** @type {number | undefined} */ [_rid]; /** @type {WeakRef[]} */ - [_views] = []; + [_views]; [_cleanup]() { const views = this[_views]; @@ -2008,6 +2019,7 @@ encoder[_label] = label; encoder[_device] = device; encoder[_rid] = rid; + encoder[_encoders] = []; return encoder; } class GPUCommandEncoder { @@ -2016,7 +2028,7 @@ /** @type {number | undefined} */ [_rid]; /** @type {WeakRef[]} */ - [_encoders] = []; + [_encoders]; [_cleanup]() { const encoders = this[_encoders]; diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index 2d1899b10c6624..c14cd4409e3990 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -212,16 +212,16 @@ pub fn op_webgpu_buffer_unmap( args: BufferUnmapArgs, zero_copy: &mut [ZeroCopyBuf], ) -> Result { + let mapped_resource = state + .resource_table + .take::(args.mapped_rid) + .ok_or_else(bad_resource_id)?; let instance = state.borrow::(); let buffer_resource = state .resource_table .get::(args.buffer_rid) .ok_or_else(bad_resource_id)?; let buffer = buffer_resource.0; - let mapped_resource = state - .resource_table - .get::(args.mapped_rid) - .ok_or_else(bad_resource_id)?; let slice_pointer = mapped_resource.0; let size = mapped_resource.1; From 08745f8235b6c8176fc335cf6e662b64e413ddf2 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 19 Feb 2021 07:15:44 +0100 Subject: [PATCH 126/144] add custominspect for GPU --- op_crates/webgpu/01_webgpu.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 5b74080f3d1b1c..6bd4d33109e7a5 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -99,6 +99,10 @@ return createGPUAdapter(data.name, data); } } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${inspect({})}`; + } } const _name = Symbol("[[name]]"); From cab9e744dfb417ae29063d71e40208dc62350919 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 13:16:51 +0100 Subject: [PATCH 127/144] fix tests --- cli/tests/error_009_op_crates_error.js.out | 2 +- cli/tests/unit/webgpu_test.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cli/tests/error_009_op_crates_error.js.out b/cli/tests/error_009_op_crates_error.js.out index b46ba3c16896ed..6efc2ff5381163 100644 --- a/cli/tests/error_009_op_crates_error.js.out +++ b/cli/tests/error_009_op_crates_error.js.out @@ -1,3 +1,3 @@ -[WILDCARD]error: Uncaught TypeError: Failed to construct 'Event': 1 argument, but only 0 present.[WILDCARD] +[WILDCARD]error: Uncaught TypeError: Failed to construct 'Event': 1 argument required, but only 0 present.[WILDCARD] at new Event (deno:op_crates/web/[WILDCARD]) at [WILDCARD] diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index 5289eb8334eede..4750a490790934 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -7,8 +7,6 @@ try { isCI = true; } -// TODO(lucacasonato): remove when navigator is added to deno-lint -// deno-lint-ignore no-undef const adapter = await navigator.gpu.requestAdapter(); assert(adapter); From 6212dd11d188640dda472a8183773f4557a90c9d Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 13:17:06 +0100 Subject: [PATCH 128/144] change adapter in tests --- cli/tests/unit/webgpu_test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index 4750a490790934..521986edffd5c0 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -7,15 +7,15 @@ try { isCI = true; } -const adapter = await navigator.gpu.requestAdapter(); -assert(adapter); - // Skip this test on linux CI, because the vulkan emulator is not good enough // yet, and skip on macOS because these do not have virtual GPUs. unitTest({ perms: { read: true, env: true }, ignore: (Deno.build.os === "linux" || Deno.build.os === "darwin") && isCI, }, async function webgpuComputePass() { + const adapter = await navigator.gpu.requestAdapter(); + assert(adapter); + const numbers = [1, 4, 3, 295]; const device = await adapter.requestDevice(); @@ -106,4 +106,9 @@ unitTest({ stagingBuffer.unmap(); device.destroy(); + + // TODO(lucacasonato): webgpu spec should add a explicit destroy method for + // adapters. + const resources = Object.keys(Deno.resources()); + Deno.close(Number(resources[resources.length - 1])); }); From 4015f1645c1c6efca06e5c32b7bfdd5d7a3541e7 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 19 Feb 2021 22:39:23 +0100 Subject: [PATCH 129/144] more jsdoc + webidl --- op_crates/webgpu/01_webgpu.js | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 5b74080f3d1b1c..b3591980e8d0f6 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -13,6 +13,10 @@ const webidl = window.__bootstrap.webidl; const eventTarget = window.__bootstrap.eventTarget; + /** + * @param {number[] | GPUExtent3DDict} data + * @returns {GPUExtent3DDict} + */ function normalizeGPUExtent3D(data) { if (Array.isArray(data)) { return { @@ -25,6 +29,10 @@ } } + /** + * @param {number[] | GPUOrigin3DDict} data + * @returns {GPUOrigin3DDict} + */ function normalizeGPUOrigin3D(data) { if (Array.isArray(data)) { return { @@ -37,6 +45,10 @@ } } + /** + * @param {number[] | GPUColor} data + * @returns {GPUColor} + */ function normalizeGPUColor(data) { if (Array.isArray(data)) { return { @@ -88,9 +100,7 @@ const { error, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", - { - ...options, - }, + { ...options }, ); if (error) { @@ -263,30 +273,39 @@ throw new TypeError("Not yet implemented"); } get maxBindGroups() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxBindGroups; } get maxDynamicUniformBuffersPerPipelineLayout() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxDynamicUniformBuffersPerPipelineLayout; } get maxDynamicStorageBuffersPerPipelineLayout() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxDynamicStorageBuffersPerPipelineLayout; } get maxSampledTexturesPerShaderStage() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxSampledTexturesPerShaderStage; } get maxSamplersPerShaderStage() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxSamplersPerShaderStage; } get maxStorageBuffersPerShaderStage() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxStorageBuffersPerShaderStage; } get maxStorageTexturesPerShaderStage() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxStorageTexturesPerShaderStage; } get maxUniformBuffersPerShaderStage() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxUniformBuffersPerShaderStage; } get maxUniformBufferBindingSize() { + webidl.assertBranded(this, GPUAdapterLimits); return this[_limits].maxUniformBufferBindingSize; } get maxStorageBufferBindingSize() { @@ -326,35 +345,42 @@ /** @return {IterableIterator<[string, string]>} */ entries() { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features].entries(); } /** @return {void} */ forEach(callbackfn, thisArg) { + webidl.assertBranded(this, GPUAdapterFeatures); this[_features].forEach(callbackfn, thisArg); } /** @return {boolean} */ has(value) { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features].has(value); } /** @return {IterableIterator} */ keys() { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features].keys(); } /** @return {IterableIterator} */ values() { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features].values(); } /** @return {number} */ get size() { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features].size; } [Symbol.iterator]() { + webidl.assertBranded(this, GPUAdapterFeatures); return this[_features][Symbol.iterator](); } @@ -2962,7 +2988,6 @@ "OperationError", ); } - webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { renderPassRid: this[_rid], From 3ab1a7994c59204d70893be3ff66853b92fdc7f5 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sat, 20 Feb 2021 01:07:33 +0100 Subject: [PATCH 130/144] move consumed chheck after webidl checks --- op_crates/webgpu/01_webgpu.js | 666 ++++++++++++++++++---------------- 1 file changed, 356 insertions(+), 310 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7a8cbe40eb89c9..ebcc7fb8433a9f 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -15,7 +15,7 @@ /** * @param {number[] | GPUExtent3DDict} data - * @returns {GPUExtent3DDict} + * @returns {GPUExtent3DDict} */ function normalizeGPUExtent3D(data) { if (Array.isArray(data)) { @@ -31,7 +31,7 @@ /** * @param {number[] | GPUOrigin3DDict} data - * @returns {GPUOrigin3DDict} + * @returns {GPUOrigin3DDict} */ function normalizeGPUOrigin3D(data) { if (Array.isArray(data)) { @@ -47,7 +47,7 @@ /** * @param {number[] | GPUColor} data - * @returns {GPUColor} + * @returns {GPUColor} */ function normalizeGPUColor(data) { if (Array.isArray(data)) { @@ -2085,13 +2085,6 @@ * @return {GPURenderPassEncoder} */ beginRenderPass(descriptor) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; @@ -2101,6 +2094,13 @@ context: "Argument 1", }); + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + let depthStencilAttachment; if (descriptor.depthStencilAttachment) { depthStencilAttachment = { @@ -2176,13 +2176,6 @@ * @param {GPUComputePassDescriptor} descriptor */ beginComputePass(descriptor = {}) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; @@ -2191,6 +2184,13 @@ context: "Argument 1", }); + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_compute_pass", { @@ -2222,13 +2222,6 @@ destinationOffset, size, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; @@ -2253,6 +2246,14 @@ prefix, context: "Argument 5", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_buffer", { @@ -2272,13 +2273,6 @@ * @param {GPUExtent3D} copySize */ copyBufferToTexture(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; @@ -2296,6 +2290,13 @@ context: "Argument 3", }); + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_texture", { @@ -2321,13 +2322,6 @@ * @param {GPUExtent3D} copySize */ copyTextureToBuffer(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; @@ -2344,6 +2338,14 @@ prefix, context: "Argument 3", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { @@ -2368,13 +2370,6 @@ * @param {GPUExtent3D} copySize */ copyTextureToTexture(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; @@ -2391,6 +2386,14 @@ prefix, context: "Argument 3", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { @@ -2415,13 +2418,6 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; @@ -2430,6 +2426,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { commandEncoderRid: this[_rid], groupLabel, @@ -2437,6 +2441,8 @@ } popDebugGroup() { + webidl.assertBranded(this, GPUCommandEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder': already consumed", @@ -2444,7 +2450,6 @@ ); } - webidl.assertBranded(this, GPUCommandEncoder); core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { commandEncoderRid: this[_rid], }); @@ -2454,13 +2459,6 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; @@ -2469,6 +2467,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { commandEncoderRid: this[_rid], markerLabel, @@ -2480,13 +2486,6 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; @@ -2499,6 +2498,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { commandEncoderRid: this[_rid], querySet: querySet[_rid], @@ -2520,13 +2527,6 @@ destination, destinationOffset, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; @@ -2551,6 +2551,14 @@ prefix, context: "Argument 5", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { commandEncoderRid: this[_rid], querySet: querySet[_rid], @@ -2566,6 +2574,13 @@ * @returns {GPUCommandBuffer} */ finish(descriptor = {}) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; + descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'finish' on 'GPUCommandEncoder': already consumed", @@ -2573,12 +2588,6 @@ ); } - webidl.assertBranded(this, GPUCommandEncoder); - const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; - descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { commandEncoderRid: this[_rid], ...descriptor, @@ -2650,13 +2659,6 @@ * @param {number} maxDepth */ setViewport(x, y, width, height, minDepth, maxDepth) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setViewport' on 'GPUComputePassEncoder'"; @@ -2676,6 +2678,14 @@ prefix, context: "Argument 6", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_viewport", { renderPassRid: this[_rid], x, @@ -2695,13 +2705,6 @@ * @param {number} height */ setScissorRect(x, y, width, height) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setScissorRect' on 'GPUComputePassEncoder'"; @@ -2722,6 +2725,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_scissor_rect", { renderPassRid: this[_rid], x, @@ -2735,13 +2746,6 @@ * @param {GPUColor} color */ setBlendColor(color) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setBlendColor' on 'GPUComputePassEncoder'"; @@ -2750,6 +2754,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_blend_color", { renderPassRid: this[_rid], color: normalizeGPUColor(color), @@ -2760,13 +2772,6 @@ * @param {number} reference */ setStencilReference(reference) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; @@ -2775,6 +2780,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_stencil_reference", { renderPassRid: this[_rid], reference, @@ -2808,13 +2821,6 @@ * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; @@ -2827,6 +2833,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { renderPassRid: this[_rid], querySet: querySet[_rid], @@ -2835,6 +2849,8 @@ } endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPURenderPassEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", @@ -2842,7 +2858,6 @@ ); } - webidl.assertBranded(this, GPURenderPassEncoder); core.jsonOpSync("op_webgpu_render_pass_end_pipeline_statistics_query", { renderPassRid: this[_rid], }); @@ -2853,13 +2868,6 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder'"; @@ -2872,6 +2880,13 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } core.jsonOpSync("op_webgpu_render_pass_write_timestamp", { renderPassRid: this[_rid], querySet: querySet[_rid], @@ -2883,13 +2898,6 @@ * @param {GPURenderBundle[]} bundles */ executeBundles(bundles) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; @@ -2898,6 +2906,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { renderPassRid: this[_rid], bundles: bundles.map((bundle) => bundle[_rid]), @@ -2964,13 +2980,6 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder'"; @@ -2979,6 +2988,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_push_debug_group", { renderPassRid: this[_rid], groupLabel, @@ -2986,13 +3003,15 @@ } popDebugGroup() { + webidl.assertBranded(this, GPURenderPassEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder': already consumed", "OperationError", ); } - webidl.assertBranded(this, GPURenderPassEncoder); + core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { renderPassRid: this[_rid], }); @@ -3002,13 +3021,6 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder'"; @@ -3017,6 +3029,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_insert_debug_marker", { renderPassRid: this[_rid], markerLabel, @@ -3027,13 +3047,6 @@ * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPURenderPassEncoder'"; @@ -3042,6 +3055,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_pipeline", { renderPassRid: this[_rid], pipeline: pipeline[_rid], @@ -3055,13 +3076,6 @@ * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder'"; @@ -3082,6 +3096,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_index_buffer", { renderPassRid: this[_rid], buffer: buffer[_rid], @@ -3098,13 +3120,6 @@ * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder'"; @@ -3125,6 +3140,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_set_vertex_buffer", { renderPassRid: this[_rid], slot, @@ -3141,13 +3164,6 @@ * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'draw' on 'GPURenderPassEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); @@ -3167,6 +3183,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_draw", { renderPassRid: this[_rid], vertexCount, @@ -3190,13 +3214,6 @@ baseVertex = 0, firstInstance = 0, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder'"; @@ -3221,6 +3238,14 @@ prefix, context: "Argument 5", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_draw_indexed", { renderPassRid: this[_rid], indexCount, @@ -3236,13 +3261,6 @@ * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; @@ -3255,6 +3273,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_draw_indirect", { renderPassRid: this[_rid], indirectBuffer: indirectBuffer[_rid], @@ -3264,16 +3290,9 @@ /** * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset - */ - drawIndexedIndirect(indirectBuffer, indirectOffset) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + * @param {number} indirectOffset + */ + drawIndexedIndirect(indirectBuffer, indirectOffset) { webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; @@ -3286,6 +3305,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_pass_draw_indexed_indirect", { renderPassRid: this[_rid], indirectBuffer: indirectBuffer[_rid], @@ -3342,13 +3369,6 @@ * @param {GPUComputePipeline} pipeline */ setPipeline(pipeline) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPUComputePassEncoder'"; @@ -3357,6 +3377,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { computePassRid: this[_rid], pipeline: pipeline[_rid], @@ -3369,6 +3397,13 @@ * @param {number} z */ dispatch(x, y = 1, z = 1) { + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); + y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); + z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'dispatch' on 'GPUComputePassEncoder': already consumed", @@ -3376,12 +3411,6 @@ ); } - webidl.assertBranded(this, GPUComputePassEncoder); - const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); - y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); - z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); core.jsonOpSync("op_webgpu_compute_pass_dispatch", { computePassRid: this[_rid], x, @@ -3395,13 +3424,6 @@ * @param {number} indirectOffset */ dispatchIndirect(indirectBuffer, indirectOffset) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder'"; @@ -3414,6 +3436,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { computePassRid: this[_rid], indirectBuffer: indirectBuffer[_rid], @@ -3426,13 +3456,6 @@ * @param {number} queryIndex */ beginPipelineStatisticsQuery(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; @@ -3445,6 +3468,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync( "op_webgpu_compute_pass_begin_pipeline_statistics_query", { @@ -3456,6 +3487,8 @@ } endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPUComputePassEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", @@ -3463,7 +3496,6 @@ ); } - webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { computePassRid: this[_rid], }); @@ -3474,13 +3506,6 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder'"; @@ -3498,6 +3523,13 @@ throw new GPUValidationError(`${prefix}: GPUQuerySet is not valid.`); } + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { computePassRid: this[_rid], querySet: querySet[_rid], @@ -3506,6 +3538,8 @@ } endPass() { + webidl.assertBranded(this, GPUComputePassEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'endPass' on 'GPUComputePassEncoder': already consumed", @@ -3513,7 +3547,6 @@ ); } - webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_end_pass", { commandEncoderRid: this[_encoder], computePassRid: this[_rid], @@ -3566,13 +3599,6 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; @@ -3581,6 +3607,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_compute_pass_push_debug_group", { computePassRid: this[_rid], groupLabel, @@ -3588,6 +3622,8 @@ } popDebugGroup() { + webidl.assertBranded(this, GPUComputePassEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", @@ -3595,7 +3631,6 @@ ); } - webidl.assertBranded(this, GPUComputePassEncoder); core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { computePassRid: this[_rid], }); @@ -3605,13 +3640,6 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; @@ -3620,6 +3648,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_compute_pass_insert_debug_marker", { computePassRid: this[_rid], markerLabel, @@ -3723,6 +3759,12 @@ * @param {GPURenderBundleDescriptor} descriptor */ finish(descriptor = {}) { + webidl.assertBranded(this, GPURenderBundleEncoder); + descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { + prefix: "Failed to execute 'finish' on 'GPURenderBundleEncoder'", + context: "Argument 1", + }); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'finish' on 'GPURenderBundleEncoder': already consumed", @@ -3730,11 +3772,6 @@ ); } - webidl.assertBranded(this, GPURenderBundleEncoder); - descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { - prefix: "Failed to execute 'finish' on 'GPURenderBundleEncoder'", - context: "Argument 1", - }); const { rid } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { @@ -3798,13 +3835,6 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; @@ -3813,6 +3843,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { renderBundleEncoderRid: this[_rid], groupLabel, @@ -3820,6 +3858,8 @@ } popDebugGroup() { + webidl.assertBranded(this, GPURenderBundleEncoder); + if (this[_rid] === undefined) { throw new DOMException( "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", @@ -3827,7 +3867,6 @@ ); } - webidl.assertBranded(this, GPURenderBundleEncoder); core.jsonOpSync("op_webgpu_render_bundle_encoder_pop_debug_group", { renderBundleEncoderRid: this[_rid], }); @@ -3837,13 +3876,6 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; @@ -3852,6 +3884,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { renderBundleEncoderRid: this[_rid], markerLabel, @@ -3862,13 +3902,6 @@ * @param {GPURenderPipeline} pipeline */ setPipeline(pipeline) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'"; @@ -3877,6 +3910,14 @@ prefix, context: "Argument 1", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { renderBundleEncoderRid: this[_rid], pipeline: pipeline[_rid], @@ -3890,13 +3931,6 @@ * @param {number} size */ setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'"; @@ -3917,6 +3951,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { renderBundleEncoderRid: this[_rid], buffer: buffer[_rid], @@ -3933,13 +3975,6 @@ * @param {number} size */ setVertexBuffer(slot, buffer, offset = 0, size = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'"; @@ -3960,6 +3995,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { renderBundleEncoderRid: this[_rid], slot, @@ -3976,13 +4019,6 @@ * @param {number} firstInstance */ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; webidl.requiredArguments(arguments.length, 1, { prefix }); @@ -4002,6 +4038,14 @@ prefix, context: "Argument 4", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw", { renderBundleEncoderRid: this[_rid], vertexCount, @@ -4025,13 +4069,6 @@ baseVertex = 0, firstInstance = 0, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; @@ -4056,6 +4093,14 @@ prefix, context: "Argument 5", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indexed", { renderBundleEncoderRid: this[_rid], indexCount, @@ -4071,13 +4116,6 @@ * @param {number} indirectOffset */ drawIndirect(indirectBuffer, indirectOffset) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPURenderBundleEncoder); const prefix = "Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'"; @@ -4090,6 +4128,14 @@ prefix, context: "Argument 2", }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", + "OperationError", + ); + } + core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { renderBundleEncoderRid: this[_rid], indirectBuffer: indirectBuffer[_rid], From 952e816dba0370644ddb619f45e3a64f643daf9b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Sun, 21 Feb 2021 13:26:51 +0100 Subject: [PATCH 131/144] assertDevice + assertDeviceMatch + assertResource --- op_crates/webgpu/01_webgpu.js | 828 ++++++++++++++++++++++++---------- 1 file changed, 589 insertions(+), 239 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 7a8cbe40eb89c9..475cf3af58ed77 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -13,6 +13,63 @@ const webidl = window.__bootstrap.webidl; const eventTarget = window.__bootstrap.eventTarget; + /** + * @param {any} self + * @param {{prefix: string, context: string}} opts + * @returns {InnerGPUDevice & {rid: number}} + */ + function assertDevice(self, { prefix, context }) { + const device = self[_device]; + const deviceRid = device?.rid; + if (deviceRid === undefined) { + throw new DOMException( + `${prefix}: ${context} references an invalid or destroyed device.`, + "OperationError", + ); + } + return { ...device, rid: deviceRid }; + } + + /** + * @param {InnerGPUDevice} self + * @param {any} resource + * @param {{prefix: string, resourceContext: string, selfContext: string}} opts + * @returns {InnerGPUDevice & {rid: number}} + */ + function assertDeviceMatch( + self, + resource, + { prefix, resourceContext, selfContext }, + ) { + const resourceDevice = assertDevice(resource, { + prefix, + context: resourceContext, + }); + if (resourceDevice.rid !== self.rid) { + throw new DOMException( + `${prefix}: ${resourceContext} belongs to a diffent device than ${selfContext}.`, + "OperationError", + ); + } + return { ...resourceDevice, rid: resourceDevice.rid }; + } + + /** + * @param {any} self + * @param {{prefix: string, context: string}} opts + * @returns {number} + */ + function assertResource(self, { prefix, context }) { + const rid = self[_rid]; + if (rid === undefined) { + throw new DOMException( + `${prefix}: ${context} an invalid or destroyed resource.`, + "OperationError", + ); + } + return rid; + } + /** * @param {number[] | GPUExtent3DDict} data * @returns {GPUExtent3DDict} @@ -514,8 +571,9 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }); /** @type {CreateGPUBufferOptions} */ @@ -537,13 +595,13 @@ } const buffer = createGPUBuffer( descriptor.label ?? null, - this[_device], + device, rid, descriptor.size, descriptor.usage, options, ); - this[_device].resources.push(new WeakRef(buffer)); + device.resources.push(new WeakRef(buffer)); return buffer; } @@ -559,18 +617,19 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_texture", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, size: normalizeGPUExtent3D(descriptor.size), }); const texture = createGPUTexture( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(texture)); + device.resources.push(new WeakRef(texture)); return texture; } @@ -585,17 +644,18 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }); const sampler = createGPUSampler( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(sampler)); + device.resources.push(new WeakRef(sampler)); return sampler; } @@ -611,6 +671,7 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); for (const entry of descriptor.entries) { let i = 0; if (entry.buffer) i++; @@ -624,16 +685,16 @@ } const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }); const bindGroupLayout = createGPUBindGroupLayout( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(bindGroupLayout)); + device.resources.push(new WeakRef(bindGroupLayout)); return bindGroupLayout; } @@ -649,20 +710,31 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const bindGroupLayouts = descriptor.bindGroupLayouts.map( + (layout, i) => { + const context = `bind group layout ${i + 1}`; + const rid = assertResource(layout, { prefix, context }); + assertDeviceMatch(device, layout, { + prefix, + selfContext: "this", + resourceContext: context, + }); + return rid; + }, + ); const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { - deviceRid: this[_device].rid, + deviceRid: device.rid, label: descriptor.label, - bindGroupLayouts: descriptor.bindGroupLayouts.map((bindGroupLayout) => - bindGroupLayout[_rid] - ), + bindGroupLayouts, }); const pipelineLayout = createGPUPipelineLayout( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(pipelineLayout)); + device.resources.push(new WeakRef(pipelineLayout)); return pipelineLayout; } @@ -678,41 +750,79 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const layout = assertResource(descriptor.layout, { + prefix, + context: "layout", + }); + assertDeviceMatch(device, descriptor.layout, { + prefix, + resourceContext: "layout", + selfContext: "this", + }); + const entries = descriptor.entries.map((entry, i) => { + const context = `entry ${i + 1}`; + const resource = entry.resource; + if (resource instanceof GPUSampler) { + const rid = assertResource(resource, { + prefix, + context, + }); + assertDeviceMatch(device, resource, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return { + binding: entry.binding, + kind: "GPUSampler", + resource: rid, + }; + } else if (resource instanceof GPUTextureView) { + const rid = assertResource(resource, { + prefix, + context, + }); + assertDeviceMatch(device, resource, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return { + binding: entry.binding, + kind: "GPUTextureView", + resource: rid, + }; + } else { + const rid = assertDevice(resource.buffer, { prefix, context }); + assertDeviceMatch(device, resource.buffer, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return { + binding: entry.binding, + kind: "GPUBufferBinding", + resource: rid, + offset: entry.resource.offset, + size: entry.resource.size, + }; + } + }); + const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { deviceRid: this[_device].rid, label: descriptor.label, - layout: descriptor.layout[_rid], - entries: descriptor.entries.map((entry) => { - if (entry.resource instanceof GPUSampler) { - return { - binding: entry.binding, - kind: "GPUSampler", - resource: entry.resource[_rid], - }; - } else if (entry.resource instanceof GPUTextureView) { - return { - binding: entry.binding, - kind: "GPUTextureView", - resource: entry.resource[_rid], - }; - } else { - return { - binding: entry.binding, - kind: "GPUBufferBinding", - resource: entry.resource.buffer[_rid], - offset: entry.resource.offset, - size: entry.resource.size, - }; - } - }), + layout, + entries, }); const bindGroup = createGPUBindGroup( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(bindGroup)); + device.resources.push(new WeakRef(bindGroup)); return bindGroup; } @@ -727,10 +837,11 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync( "op_webgpu_create_shader_module", { - deviceRid: this[_device].rid, + deviceRid: device.rid, label: descriptor.label, code: (typeof descriptor.code === "string") ? descriptor.code @@ -744,10 +855,10 @@ const shaderModule = createGPUShaderModule( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(shaderModule)); + device.resources.push(new WeakRef(shaderModule)); return shaderModule; } @@ -763,22 +874,43 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + let layout = undefined; + if (descriptor.layout) { + const context = "layout"; + layout = assertDevice(descriptor.layout, { prefix, context }); + assertDeviceMatch(device, descriptor.layout, { + prefix, + resourceContext: context, + selfContext: "this", + }); + } + const module = assertDevice(descriptor.compute.module, { + prefix, + context: "compute shader module", + }); + assertDeviceMatch(device, descriptor.compute.module, { + prefix, + resourceContext: "compute shader module", + selfContext: "this", + }); + const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { - deviceRid: this[_device].rid, + deviceRid: device.rid, label: descriptor.label, - layout: descriptor.layout ? descriptor.layout[_rid] : undefined, + layout, compute: { - module: descriptor.compute.module[_rid], + module, entryPoint: descriptor.compute.entryPoint, }, }); const computePipeline = createGPUComputePipeline( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(computePipeline)); + device.resources.push(new WeakRef(computePipeline)); return computePipeline; } @@ -794,37 +926,65 @@ prefix, context: "Argument 1", }); - const d = { + const device = assertDevice(this, { prefix, context: "this" }); + let layout = undefined; + if (descriptor.layout) { + const context = "layout"; + layout = assertDevice(descriptor.layout, { prefix, context }); + assertDeviceMatch(device, descriptor.layout, { + prefix, + resourceContext: context, + selfContext: "this", + }); + } + const module = assertDevice(descriptor.vertex.module, { + prefix, + context: "vertex shader module", + }); + assertDeviceMatch(device, descriptor.vertex.module, { + prefix, + resourceContext: "vertex shader module", + selfContext: "this", + }); + let fragment = undefined; + if (descriptor.fragment) { + const module = assertDevice(descriptor.fragment.module, { + prefix, + context: "fragment shader module", + }); + assertDeviceMatch(device, descriptor.fragment.module, { + prefix, + resourceContext: "fragment shader module", + selfContext: "this", + }); + fragment = { + module, + entryPoint: descriptor.fragment.entryPoint, + targets: descriptor.fragment.targets, + }; + } + + const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { + deviceRid: device.rid, label: descriptor.label, - layout: descriptor.layout?.[_rid], + layout, vertex: { - module: descriptor.vertex.module[_rid], + module, entryPoint: descriptor.vertex.entryPoint, buffers: descriptor.vertex.buffers, }, primitive: descriptor.primitive, depthStencil: descriptor.depthStencil, multisample: descriptor.multisample, - fragment: descriptor.fragment - ? { - module: descriptor.fragment.module[_rid], - entryPoint: descriptor.fragment.entryPoint, - targets: descriptor.fragment.targets, - } - : undefined, - }; - - const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { - deviceRid: this[_device].rid, - ...d, + fragment, }); const renderPipeline = createGPURenderPipeline( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(renderPipeline)); + device.resources.push(new WeakRef(renderPipeline)); return renderPipeline; } @@ -849,17 +1009,18 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }); const commandEncoder = createGPUCommandEncoder( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(commandEncoder)); + device.resources.push(new WeakRef(commandEncoder)); return commandEncoder; } @@ -879,20 +1040,21 @@ context: "Argument 1", }, ); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }, ); const renderBundleEncoder = createGPURenderBundleEncoder( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(renderBundleEncoder)); + device.resources.push(new WeakRef(renderBundleEncoder)); return renderBundleEncoder; } @@ -911,18 +1073,19 @@ context: "Argument 1", }, ); + const device = assertDevice(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { - deviceRid: this[_device].rid, + deviceRid: device.rid, ...descriptor, }); const querySet = createGPUQuerySet( descriptor.label ?? null, - this[_device], + device, rid, descriptor, ); - this[_device].resources.push(new WeakRef(querySet)); + device.resources.push(new WeakRef(querySet)); return querySet; } @@ -974,9 +1137,20 @@ commandBuffers, { prefix, context: "Argument 1" }, ); + const device = assertDevice(this, { prefix, context: "this" }); + const commandBufferRids = commandBuffers.map((buffer, i) => { + const context = `command buffer ${i + 1}`; + const rid = assertResource(buffer, { prefix, context }); + assertDeviceMatch(device, buffer, { + prefix, + selfContext: "this", + resourceContext: context, + }); + return rid; + }); core.jsonOpSync("op_webgpu_queue_submit", { - queueRid: this[_device].rid, - commandBuffers: commandBuffers.map((buffer) => buffer[_rid]), + queueRid: device.rid, + commandBuffers: commandBufferRids, }); } @@ -1018,11 +1192,21 @@ prefix, context: "Argument 5", }); + const device = assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + selfContext: "this", + resourceContext: "Argument 1", + }); core.jsonOpSync( "op_webgpu_write_buffer", { - queueRid: this[_device].rid, - buffer: buffer[_rid], + queueRid: device.rid, + buffer: bufferRid, bufferOffset, dataOffset, size, @@ -1057,16 +1241,26 @@ prefix, context: "Argument 4", }); - + const device = assertDevice(this, { prefix, context: "this" }); + const textureRid = assertResource(destination.texture, { + prefix, + context: "texture", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + selfContext: "this", + resourceContext: "texture", + }); core.jsonOpSync( "op_webgpu_write_texture", { - queueRid: this[_device].rid, + queueRid: device.rid, destination: { - texture: destination.texture[_rid], + texture: textureRid, mipLevel: destination.mipLevel, - origin: destination.origin ?? - normalizeGPUOrigin3D(destination.origin), + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, }, dataLayout, size: normalizeGPUExtent3D(size), @@ -1200,6 +1394,8 @@ prefix, context: "Argument 3", }); + const device = assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); /** @type {number} */ let rangeSize; if (size === undefined) { @@ -1257,8 +1453,8 @@ await core.jsonOpAsync( "op_webgpu_buffer_get_map_async", { - bufferRid: this[_rid], - deviceRid: this[_device].rid, + bufferRid, + deviceRid: device.rid, mode, offset, size: rangeSize, @@ -1287,6 +1483,8 @@ prefix, context: "Argument 2", }); + assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); /** @type {number} */ let rangeSize; if (size === undefined) { @@ -1350,7 +1548,7 @@ const { rid } = core.jsonOpSync( "op_webgpu_buffer_get_mapped_range", { - bufferRid: this[_rid], + bufferRid, offset: offset - mappingRange[0], size: rangeSize, }, @@ -1365,6 +1563,8 @@ unmap() { webidl.assertBranded(this, GPUBuffer); const prefix = "Failed to execute 'unmap' on 'GPUBuffer'"; + assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); if (this[_state] === "unmapped" || this[_state] === "destroyed") { throw new DOMException( `${prefix}: buffer is not ready to be unmapped.`, @@ -1401,10 +1601,10 @@ if (!mappedRanges) { throw new DOMException(`${prefix}: invalid state.`, "OperationError"); } - for (const [buffer, rid] of mappedRanges) { + for (const [buffer, mappedRid] of mappedRanges) { core.jsonOpSync("op_webgpu_buffer_unmap", { - bufferRid: this[_rid], - mappedRid: rid, + bufferRid, + mappedRid, }, ...(write ? [new Uint8Array(buffer)] : [])); } this[_mappingRange] = null; @@ -1536,9 +1736,10 @@ prefix, context: "Argument 1", }); - + assertDevice(this, { prefix, context: "this" }); + const textureRid = assertResource(this, { prefix, context: "this" }); const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { - textureRid: this[_rid], + textureRid, ...descriptor, }); @@ -1914,20 +2115,22 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const computePipelineRid = assertResource(this, { + prefix, + context: "this", + }); const { rid, label } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", - { - computePipelineRid: this[_rid], - index, - }, + { computePipelineRid, index }, ); const bindGroupLayout = createGPUBindGroupLayout( label, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(bindGroupLayout)); + device.resources.push(new WeakRef(bindGroupLayout)); return bindGroupLayout; } @@ -1986,20 +2189,22 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderPipelineRid = assertResource(this, { + prefix, + context: "this", + }); const { rid, label } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", - { - renderPipelineRid: this[_rid], - index, - }, + { renderPipelineRid, index }, ); const bindGroupLayout = createGPUBindGroupLayout( label, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(bindGroupLayout)); + device.resources.push(new WeakRef(bindGroupLayout)); return bindGroupLayout; } @@ -2085,13 +2290,6 @@ * @return {GPURenderPassEncoder} */ beginRenderPass(descriptor) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; @@ -2100,12 +2298,31 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); let depthStencilAttachment; if (descriptor.depthStencilAttachment) { + const view = assertResource(descriptor.depthStencilAttachment.view, { + prefix, + context: "texture view for depth stencil attachment", + }); + assertDeviceMatch( + device, + descriptor.depthStencilAttachment.view[_texture], + { + prefix, + resourceContext: "texture view for depth stencil attachment", + selfContext: "this", + }, + ); + depthStencilAttachment = { ...descriptor.depthStencilAttachment, - view: descriptor.depthStencilAttachment.view[_rid], + view, }; if ( @@ -2131,34 +2348,75 @@ descriptor.depthStencilAttachment.stencilLoadValue; } } + const colorAttachments = descriptor.colorAttachments.map( + (colorAttachment, i) => { + const context = `color attachment ${i + 1}`; + const view = assertResource(colorAttachment.view, { + prefix, + context: `texture view for ${context}`, + }); + assertResource(colorAttachment.view[_texture], { + prefix, + context: `texture backing texture view for ${context}`, + }); + assertDeviceMatch( + device, + colorAttachment.view[_texture], + { + prefix, + resourceContext: `texture view for ${context}`, + selfContext: "this", + }, + ); + let resolveTarget; + if (colorAttachment.resolveTarget) { + resolveTarget = assertResource( + colorAttachment.resolveTarget, + { + prefix, + context: `resolve target texture view for ${context}`, + }, + ); + assertResource(colorAttachment.resolveTarget[_texture], { + prefix, + context: + `texture backing resolve target texture view for ${context}`, + }); + assertDeviceMatch( + device, + colorAttachment.resolveTarget[_texture], + { + prefix, + resourceContext: `resolve target texture view for ${context}`, + selfContext: "this", + }, + ); + } + const attachment = { + view: view, + resolveTarget, + storeOp: colorAttachment.storeOp, + }; + + if (typeof colorAttachment.loadValue === "string") { + attachment.loadOp = colorAttachment.loadValue; + } else { + attachment.loadOp = "clear"; + attachment.loadValue = normalizeGPUColor( + colorAttachment.loadValue, + ); + } + + return attachment; + }, + ); const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_render_pass", { - commandEncoderRid: this[_rid], + commandEncoderRid, ...descriptor, - colorAttachments: descriptor.colorAttachments.map( - (colorAttachment) => { - const attachment = { - view: colorAttachment.view[_rid], - resolveTarget: colorAttachment.resolveTarget - ? colorAttachment.resolveTarget[_rid] - : undefined, - storeOp: colorAttachment.storeOp, - }; - - if (typeof colorAttachment.loadValue === "string") { - attachment.loadOp = colorAttachment.loadValue; - } else { - attachment.loadOp = "clear"; - attachment.loadValue = normalizeGPUColor( - colorAttachment.loadValue, - ); - } - - return attachment; - }, - ), + colorAttachments, depthStencilAttachment, }, ); @@ -2176,13 +2434,6 @@ * @param {GPUComputePassDescriptor} descriptor */ beginComputePass(descriptor = {}) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginComputePass' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; @@ -2191,17 +2442,23 @@ context: "Argument 1", }); + assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { rid } = core.jsonOpSync( "op_webgpu_command_encoder_begin_compute_pass", { - commandEncoderRid: this[_rid], + commandEncoderRid, ...descriptor, }, ); const computePassEncoder = createGPUComputePassEncoder( descriptor.label ?? null, - this[_rid], + this, rid, ); this[_encoders].push(new WeakRef(computePassEncoder)); @@ -2222,13 +2479,6 @@ destinationOffset, size, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; @@ -2253,13 +2503,37 @@ prefix, context: "Argument 5", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceRid = assertResource(source, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, source, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + const destinationRid = assertResource(source, { + prefix, + context: "Argument 3", + }); + assertDeviceMatch(device, source, { + prefix, + resourceContext: "Argument 3", + selfContext: "this", + }); + core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_buffer", { - commandEncoderRid: this[_rid], - source: source[_rid], + commandEncoderRid, + source: sourceRid, sourceOffset, - destination: destination[_rid], + destination: destinationRid, destinationOffset, size, }, @@ -2272,13 +2546,6 @@ * @param {GPUExtent3D} copySize */ copyBufferToTexture(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; @@ -2295,20 +2562,43 @@ prefix, context: "Argument 3", }); - + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceBufferRid = assertResource(source.buffer, { + prefix, + context: "source in Argument 1", + }); + assertDeviceMatch(device, source.buffer, { + prefix, + resourceContext: "source in Argument 1", + selfContext: "this", + }); + const destinationTextureRid = assertResource(destination.texture, { + prefix, + context: "texture in Argument 2", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + resourceContext: "texture in Argument 2", + selfContext: "this", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_texture", { - commandEncoderRid: this[_rid], + commandEncoderRid, source: { ...source, - buffer: source.buffer[_rid], + buffer: sourceBufferRid, }, destination: { - texture: destination.texture[_rid], + texture: destinationTextureRid, mipLevel: destination.mipLevel, - origin: destination.origin ?? - normalizeGPUOrigin3D(destination.origin), + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, }, copySize: normalizeGPUExtent3D(copySize), }, @@ -2321,13 +2611,6 @@ * @param {GPUExtent3D} copySize */ copyTextureToBuffer(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; @@ -2344,18 +2627,43 @@ prefix, context: "Argument 3", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceTextureRid = assertResource(source.texture, { + prefix, + context: "texture in Argument 1", + }); + assertDeviceMatch(device, source.texture, { + prefix, + resourceContext: "texture in Argument 1", + selfContext: "this", + }); + const destinationBufferRid = assertResource(destination.buffer, { + prefix, + context: "buffer in Argument 2", + }); + assertDeviceMatch(device, destination.buffer, { + prefix, + resourceContext: "buffer in Argument 2", + selfContext: "this", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { commandEncoderRid: this[_rid], source: { - texture: source.texture[_rid], + texture: sourceTextureRid, mipLevel: source.mipLevel, - origin: source.origin ?? normalizeGPUOrigin3D(source.origin), + origin: source.origin + ? normalizeGPUOrigin3D(source.origin) + : undefined, }, destination: { ...destination, - buffer: destination.buffer[_rid], + buffer: destinationBufferRid, }, copySize: normalizeGPUExtent3D(copySize), }, @@ -2368,13 +2676,6 @@ * @param {GPUExtent3D} copySize */ copyTextureToTexture(source, destination, copySize) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; @@ -2391,20 +2692,46 @@ prefix, context: "Argument 3", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceTextureRid = assertResource(source.texture, { + prefix, + context: "texture in Argument 1", + }); + assertDeviceMatch(device, source.texture, { + prefix, + resourceContext: "texture in Argument 1", + selfContext: "this", + }); + const destinationTextureRid = assertResource(destination.texture, { + prefix, + context: "texture in Argument 2", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + resourceContext: "texture in Argument 2", + selfContext: "this", + }); core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { - commandEncoderRid: this[_rid], + commandEncoderRid, source: { - texture: source.texture[_rid], + texture: sourceTextureRid, mipLevel: source.mipLevel, - origin: source.origin ?? normalizeGPUOrigin3D(source.origin), + origin: source.origin + ? normalizeGPUOrigin3D(source.origin) + : undefined, }, destination: { - texture: destination.texture[_rid], + texture: destinationTextureRid, mipLevel: destination.mipLevel, - origin: destination.origin ?? - normalizeGPUOrigin3D(destination.origin), + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, }, copySize: normalizeGPUExtent3D(copySize), }, @@ -2415,13 +2742,6 @@ * @param {string} groupLabel */ pushDebugGroup(groupLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; @@ -2430,23 +2750,27 @@ prefix, context: "Argument 1", }); + assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { - commandEncoderRid: this[_rid], + commandEncoderRid, groupLabel, }); } popDebugGroup() { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); + const prefix = "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder'"; + assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { - commandEncoderRid: this[_rid], + commandEncoderRid, }); } @@ -2454,13 +2778,6 @@ * @param {string} markerLabel */ insertDebugMarker(markerLabel) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; @@ -2469,8 +2786,13 @@ prefix, context: "Argument 1", }); + assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { - commandEncoderRid: this[_rid], + commandEncoderRid, markerLabel, }); } @@ -2480,13 +2802,6 @@ * @param {number} queryIndex */ writeTimestamp(querySet, queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; @@ -2499,9 +2814,23 @@ prefix, context: "Argument 2", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { - commandEncoderRid: this[_rid], - querySet: querySet[_rid], + commandEncoderRid, + querySet: querySetRid, queryIndex, }); } @@ -2520,13 +2849,6 @@ destination, destinationOffset, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; @@ -2551,12 +2873,35 @@ prefix, context: "Argument 5", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + const destinationRid = assertResource(destination, { + prefix, + context: "Argument 3", + }); + assertDeviceMatch(device, destination, { + prefix, + resourceContext: "Argument 3", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { - commandEncoderRid: this[_rid], - querySet: querySet[_rid], + commandEncoderRid, + querySet: querySetRid, firstQuery, queryCount, - destination: destination[_rid], + destination: destinationRid, destinationOffset, }); } @@ -2579,8 +2924,13 @@ prefix, context: "Argument 1", }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { - commandEncoderRid: this[_rid], + commandEncoderRid, ...descriptor, }); /** @type {number | undefined} */ @@ -2588,10 +2938,10 @@ const commandBuffer = createGPUCommandBuffer( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(commandBuffer)); + device.resources.push(new WeakRef(commandBuffer)); return commandBuffer; } From be599088612211e3e61f3ca2afb70bf42a8f6e33 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Sun, 21 Feb 2021 14:06:49 +0100 Subject: [PATCH 132/144] fix --- op_crates/webgpu/01_webgpu.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index a2a164702e0ba8..3db5ef57f4fbd8 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -783,7 +783,11 @@ prefix, context, }); - assertDeviceMatch(device, resource, { + assertResource(resource[_texture], { + prefix, + context, + }); + assertDeviceMatch(device, resource[_texture], { prefix, resourceContext: context, selfContext: "this", @@ -794,7 +798,7 @@ resource: rid, }; } else { - const rid = assertDevice(resource.buffer, { prefix, context }); + const rid = assertResource(resource.buffer, { prefix, context }); assertDeviceMatch(device, resource.buffer, { prefix, resourceContext: context, @@ -811,7 +815,7 @@ }); const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { - deviceRid: this[_device].rid, + deviceRid: device.rid, label: descriptor.label, layout, entries, @@ -878,14 +882,14 @@ let layout = undefined; if (descriptor.layout) { const context = "layout"; - layout = assertDevice(descriptor.layout, { prefix, context }); + layout = assertResource(descriptor.layout, { prefix, context }); assertDeviceMatch(device, descriptor.layout, { prefix, resourceContext: context, selfContext: "this", }); } - const module = assertDevice(descriptor.compute.module, { + const module = assertResource(descriptor.compute.module, { prefix, context: "compute shader module", }); @@ -930,14 +934,14 @@ let layout = undefined; if (descriptor.layout) { const context = "layout"; - layout = assertDevice(descriptor.layout, { prefix, context }); + layout = assertResource(descriptor.layout, { prefix, context }); assertDeviceMatch(device, descriptor.layout, { prefix, resourceContext: context, selfContext: "this", }); } - const module = assertDevice(descriptor.vertex.module, { + const module = assertResource(descriptor.vertex.module, { prefix, context: "vertex shader module", }); @@ -948,7 +952,7 @@ }); let fragment = undefined; if (descriptor.fragment) { - const module = assertDevice(descriptor.fragment.module, { + const module = assertResource(descriptor.fragment.module, { prefix, context: "fragment shader module", }); @@ -2524,11 +2528,11 @@ resourceContext: "Argument 1", selfContext: "this", }); - const destinationRid = assertResource(source, { + const destinationRid = assertResource(destination, { prefix, context: "Argument 3", }); - assertDeviceMatch(device, source, { + assertDeviceMatch(device, destination, { prefix, resourceContext: "Argument 3", selfContext: "this", @@ -2661,7 +2665,7 @@ core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { - commandEncoderRid: this[_rid], + commandEncoderRid, source: { texture: sourceTextureRid, mipLevel: source.mipLevel, @@ -3271,7 +3275,7 @@ } core.jsonOpSync("op_webgpu_render_pass_end_pass", { - commandEncoderRid: this[_encoder], + commandEncoderRid: this[_encoder][_rid], renderPassRid: this[_rid], }); this[_rid] = undefined; @@ -3890,7 +3894,7 @@ } core.jsonOpSync("op_webgpu_compute_pass_end_pass", { - commandEncoderRid: this[_encoder], + commandEncoderRid: this[_encoder][_rid], computePassRid: this[_rid], }); this[_rid] = undefined; From 0c37c2916e6b4c8ce226ee3c5a857b641da19bef Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 22 Feb 2021 13:41:43 +0100 Subject: [PATCH 133/144] assert device for GPURenderPassEncoder --- op_crates/webgpu/01_webgpu.js | 508 ++++++++++++++++++++-------------- 1 file changed, 304 insertions(+), 204 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 3db5ef57f4fbd8..73a822db12467a 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1982,6 +1982,8 @@ return bindGroup; } class GPUBindGroup { + /** @type {InnerGPUDevice} */ + [_device]; /** @type {number | undefined} */ [_rid]; @@ -3024,16 +3026,17 @@ prefix, context: "Argument 6", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setViewport' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_set_viewport", { - renderPassRid: this[_rid], + renderPassRid, x, y, width, @@ -3071,16 +3074,17 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setScissorRect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_set_scissor_rect", { - renderPassRid: this[_rid], + renderPassRid, x, y, width, @@ -3100,16 +3104,17 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setBlendColor' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_set_blend_color", { - renderPassRid: this[_rid], + renderPassRid, color: normalizeGPUColor(color), }); } @@ -3126,39 +3131,26 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setStencilReference' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_set_stencil_reference", { - renderPassRid: this[_rid], + renderPassRid, reference, }); } beginOcclusionQuery(_queryIndex) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginOcclusionQuery' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - throw new Error("Not yet implemented"); } endOcclusionQuery() { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'endOcclusionQuery' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - throw new Error("Not yet implemented"); } @@ -3179,33 +3171,46 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { - renderPassRid: this[_rid], - querySet: querySet[_rid], + renderPassRid, + querySet: querySetRid, queryIndex, }); } endPipelineStatisticsQuery() { webidl.assertBranded(this, GPURenderPassEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = + "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_end_pipeline_statistics_query", { - renderPassRid: this[_rid], + renderPassRid, }); } @@ -3226,16 +3231,27 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_write_timestamp", { - renderPassRid: this[_rid], - querySet: querySet[_rid], + renderPassRid, + querySet: querySetRid, queryIndex, }); } @@ -3252,31 +3268,46 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'executeBundles' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bundleRids = bundles.map((bundle, i) => { + const context = `bundle ${i + 1}`; + const rid = assertResource(bundle, { prefix, context }); + assertDeviceMatch(device, bundle, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return rid; + }); core.jsonOpSync("op_webgpu_render_pass_execute_bundles", { - renderPassRid: this[_rid], - bundles: bundles.map((bundle) => bundle[_rid]), + renderPassRid, + bundles: bundleRids, }); } endPass() { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'endPass' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const commandEncoderRid = assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_end_pass", { - commandEncoderRid: this[_encoder][_rid], - renderPassRid: this[_rid], + commandEncoderRid, + renderPassRid, }); this[_rid] = undefined; } @@ -3289,21 +3320,33 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setBindGroup' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - - const bind = bindGroup[_rid]; + webidl.assertBranded(this, GPURenderPassEncoder); + const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_pass_set_bind_group", { - renderPassRid: this[_rid], + renderPassRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsDataStart, dynamicOffsetsDataLength, }, @@ -3312,9 +3355,9 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_render_pass_set_bind_group", { - renderPassRid: this[_rid], + renderPassRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsData, dynamicOffsetsDataStart: 0, dynamicOffsetsDataLength: dynamicOffsetsData.length, @@ -3334,32 +3377,36 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_push_debug_group", { - renderPassRid: this[_rid], + renderPassRid, groupLabel, }); } popDebugGroup() { webidl.assertBranded(this, GPURenderPassEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = + "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_pop_debug_group", { - renderPassRid: this[_rid], + renderPassRid, }); } @@ -3375,16 +3422,17 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_insert_debug_marker", { - renderPassRid: this[_rid], + renderPassRid, markerLabel, }); } @@ -3401,17 +3449,27 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_set_pipeline", { - renderPassRid: this[_rid], - pipeline: pipeline[_rid], + renderPassRid, + pipeline: pipelineRid, }); } @@ -3442,17 +3500,27 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_set_index_buffer", { - renderPassRid: this[_rid], - buffer: buffer[_rid], + renderPassRid, + buffer: bufferRid, indexFormat, offset, size, @@ -3486,18 +3554,28 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_set_vertex_buffer", { - renderPassRid: this[_rid], + renderPassRid, slot, - buffer: buffer[_rid], + buffer: bufferRid, offset, size, }); @@ -3529,16 +3607,17 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'draw' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_draw", { - renderPassRid: this[_rid], + renderPassRid, vertexCount, instanceCount, firstVertex, @@ -3584,16 +3663,17 @@ prefix, context: "Argument 5", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_render_pass_draw_indexed", { - renderPassRid: this[_rid], + renderPassRid, indexCount, instanceCount, firstIndex, @@ -3619,17 +3699,27 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_draw_indirect", { - renderPassRid: this[_rid], - indirectBuffer: indirectBuffer[_rid], + renderPassRid, + indirectBuffer: indirectBufferRid, indirectOffset, }); } @@ -3651,17 +3741,27 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexedIndirect' on 'GPURenderPassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_pass_draw_indexed_indirect", { - renderPassRid: this[_rid], - indirectBuffer: indirectBuffer[_rid], + renderPassRid, + indirectBuffer: indirectBufferRid, indirectOffset, }); } From 55c39edb4ab5ee48c2a28b53aa0391f22587f078 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 22 Feb 2021 13:47:59 +0100 Subject: [PATCH 134/144] assert device for GPUComputePassEncoder --- op_crates/webgpu/01_webgpu.js | 285 +++++++++++++++++++++------------- 1 file changed, 173 insertions(+), 112 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 73a822db12467a..a0332adbdab7fe 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -3321,7 +3321,8 @@ dynamicOffsetsDataLength, ) { webidl.assertBranded(this, GPURenderPassEncoder); - const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; + const prefix = + "Failed to execute 'setBindGroup' on 'GPURenderPassEncoder'"; const device = assertDevice(this[_encoder], { prefix, context: "encoder referenced by this", @@ -3823,17 +3824,27 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_compute_pass_set_pipeline", { - computePassRid: this[_rid], - pipeline: pipeline[_rid], + computePassRid, + pipeline: pipelineRid, }); } @@ -3849,16 +3860,17 @@ x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'dispatch' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_dispatch", { - computePassRid: this[_rid], + computePassRid, x, y, z, @@ -3882,17 +3894,27 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_compute_pass_dispatch_indirect", { - computePassRid: this[_rid], - indirectBuffer: indirectBuffer[_rid], + computePassRid: computePassRid, + indirectBuffer: indirectBufferRid, indirectOffset, }); } @@ -3914,19 +3936,29 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync( "op_webgpu_compute_pass_begin_pipeline_statistics_query", { - computePassRid: this[_rid], - querySet: querySet[_rid], + computePassRid, + querySet: querySetRid, queryIndex, }, ); @@ -3934,16 +3966,19 @@ endPipelineStatisticsQuery() { webidl.assertBranded(this, GPUComputePassEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = + "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { - computePassRid: this[_rid], + computePassRid, }); } @@ -3964,38 +3999,46 @@ prefix, context: "Argument 2", }); - const querySetRid = querySet[_rid]; - if (querySetRid === undefined) { - throw new GPUValidationError(`${prefix}: GPUQuerySet is not valid.`); - } - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_compute_pass_write_timestamp", { - computePassRid: this[_rid], - querySet: querySet[_rid], + computePassRid, + querySet: querySetRid, queryIndex, }); } endPass() { webidl.assertBranded(this, GPUComputePassEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'endPass' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = "Failed to execute 'endPass' on 'GPUComputePassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const commandEncoderRid = assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_end_pass", { - commandEncoderRid: this[_encoder][_rid], - computePassRid: this[_rid], + commandEncoderRid, + computePassRid, }); this[_rid] = undefined; } @@ -4008,21 +4051,34 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - - const bind = bindGroup[_rid]; + webidl.assertBranded(this, GPUComputePassEncoder); + const prefix = + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_compute_pass_set_bind_group", { - computePassRid: this[_rid], + computePassRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsDataStart, dynamicOffsetsDataLength, }, @@ -4031,9 +4087,9 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_compute_pass_set_bind_group", { - computePassRid: this[_rid], + computePassRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsData, dynamicOffsetsDataStart: 0, dynamicOffsetsDataLength: dynamicOffsetsData.length, @@ -4053,32 +4109,36 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_push_debug_group", { - computePassRid: this[_rid], + computePassRid, groupLabel, }); } popDebugGroup() { webidl.assertBranded(this, GPUComputePassEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = + "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_pop_debug_group", { - computePassRid: this[_rid], + computePassRid, }); } @@ -4094,16 +4154,17 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); core.jsonOpSync("op_webgpu_compute_pass_insert_debug_marker", { - computePassRid: this[_rid], + computePassRid, markerLabel, }); } From 21a5e82c70af3c25c284aa9f2d08e0661083364b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 22 Feb 2021 13:58:29 +0100 Subject: [PATCH 135/144] assert device for GPURenderBundleEncoder --- op_crates/webgpu/01_webgpu.js | 243 ++++++++++++++++++---------------- 1 file changed, 127 insertions(+), 116 deletions(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index a0332adbdab7fe..2f28107c17c9e5 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -4267,22 +4267,20 @@ */ finish(descriptor = {}) { webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'"; descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { - prefix: "Failed to execute 'finish' on 'GPURenderBundleEncoder'", + prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'finish' on 'GPURenderBundleEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); const { rid } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, ...descriptor, }, ); @@ -4290,10 +4288,10 @@ const renderBundle = createGPURenderBundle( descriptor.label ?? null, - this[_device], + device, rid, ); - this[_device].resources.push(new WeakRef(renderBundle)); + device.resources.push(new WeakRef(renderBundle)); return renderBundle; } @@ -4305,21 +4303,30 @@ dynamicOffsetsDataStart, dynamicOffsetsDataLength, ) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - - const bind = bindGroup[_rid]; + webidl.assertBranded(this, GPURenderBundleEncoder); + const prefix = + "Failed to execute 'setBindGroup' on 'GPURenderBundleEncoder'"; + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); if (dynamicOffsetsData instanceof Uint32Array) { core.jsonOpSync( "op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsDataStart, dynamicOffsetsDataLength, }, @@ -4328,9 +4335,9 @@ } else { dynamicOffsetsData ??= []; core.jsonOpSync("op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, index, - bindGroup: bind, + bindGroup: bindGroupRid, dynamicOffsetsData, dynamicOffsetsDataStart: 0, dynamicOffsetsDataLength: dynamicOffsetsData.length, @@ -4350,32 +4357,28 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, groupLabel, }); } popDebugGroup() { webidl.assertBranded(this, GPURenderBundleEncoder); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const prefix = + "Failed to execute 'popDebugGroup' on 'GPURenderBundleEncoder'"; + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_pop_debug_group", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, }); } @@ -4391,16 +4394,13 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, markerLabel, }); } @@ -4417,17 +4417,23 @@ prefix, context: "Argument 1", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setPipeline' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_pipeline", { - renderBundleEncoderRid: this[_rid], - pipeline: pipeline[_rid], + renderBundleEncoderRid, + pipeline: pipelineRid, }); } @@ -4458,17 +4464,23 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setIndexBuffer' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_index_buffer", { - renderBundleEncoderRid: this[_rid], - buffer: buffer[_rid], + renderBundleEncoderRid, + buffer: bufferRid, indexFormat, offset, size, @@ -4502,18 +4514,24 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'setVertexBuffer' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, slot, - buffer: buffer[_rid], + buffer: bufferRid, offset, size, }); @@ -4545,16 +4563,13 @@ prefix, context: "Argument 4", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'draw' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, vertexCount, instanceCount, firstVertex, @@ -4600,16 +4615,13 @@ prefix, context: "Argument 5", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexed' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indexed", { - renderBundleEncoderRid: this[_rid], + renderBundleEncoderRid, indexCount, instanceCount, firstIndex, @@ -4635,29 +4647,28 @@ prefix, context: "Argument 2", }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndirect' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); core.jsonOpSync("op_webgpu_render_bundle_encoder_draw_indirect", { - renderBundleEncoderRid: this[_rid], - indirectBuffer: indirectBuffer[_rid], + renderBundleEncoderRid, + indirectBuffer: indirectBufferRid, indirectOffset, }); } drawIndexedIndirect(_indirectBuffer, _indirectOffset) { - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'drawIndexedIndirect' on 'GPUComputePassEncoder': already consumed", - "OperationError", - ); - } - throw new Error("Not yet implemented"); } From 2e5f2b3060ec8b9a88fb68377b098cb6a1295832 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 25 Feb 2021 18:02:50 +0100 Subject: [PATCH 136/144] chore(core): optional args for registerErrorClass --- cli/tests/059_fs_relative_path_perm.ts.out | 2 +- cli/tsc/compiler.d.ts | 7 ++++++- core/core.js | 14 +++++++------- runtime/js/10_dispatch_minimal.js | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/cli/tests/059_fs_relative_path_perm.ts.out b/cli/tests/059_fs_relative_path_perm.ts.out index 92d6b5966ca4e9..833db78bf93d0b 100644 --- a/cli/tests/059_fs_relative_path_perm.ts.out +++ b/cli/tests/059_fs_relative_path_perm.ts.out @@ -1,4 +1,4 @@ [WILDCARD]error: Uncaught PermissionDenied: read access to "non-existent", run again with the --allow-read flag - throw new ErrorClass(res.err.message); + throw new ErrorClass(res.err.message, ...args); ^ at [WILDCARD] diff --git a/cli/tsc/compiler.d.ts b/cli/tsc/compiler.d.ts index 7d102eb564898b..d37b56c0608a80 100644 --- a/cli/tsc/compiler.d.ts +++ b/cli/tsc/compiler.d.ts @@ -37,7 +37,12 @@ declare global { jsonOpSync(name: string, params: T): any; ops(): void; print(msg: string, code?: number): void; - registerErrorClass(name: string, Ctor: typeof Error): void; + registerErrorClass( + name: string, + Ctor: typeof Error, + // deno-lint-ignore no-explicit-any + ...args: any[] + ): void; } type LanguageServerRequest = diff --git a/core/core.js b/core/core.js index a96ce81d743905..642abbdd716d85 100644 --- a/core/core.js +++ b/core/core.js @@ -175,15 +175,15 @@ SharedQueue Binary Layout return send(opsCache[opName], control, ...zeroCopy); } - function registerErrorClass(errorName, className) { + function registerErrorClass(errorName, className, args) { if (typeof errorMap[errorName] !== "undefined") { throw new TypeError(`Error class for "${errorName}" already registered`); } - errorMap[errorName] = className; + errorMap[errorName] = [className, args ?? []]; } - function getErrorClass(errorName) { - return errorMap[errorName]; + function getErrorClassAndArgs(errorName) { + return errorMap[errorName] ?? [undefined, []]; } // Returns Uint8Array @@ -204,13 +204,13 @@ SharedQueue Binary Layout if ("ok" in res) { return res.ok; } - const ErrorClass = getErrorClass(res.err.className); + const [ErrorClass, args] = getErrorClassAndArgs(res.err.className); if (!ErrorClass) { throw new Error( `Unregistered error class: "${res.err.className}"\n ${res.err.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`, ); } - throw new ErrorClass(res.err.message); + throw new ErrorClass(res.err.message, ...args); } async function jsonOpAsync(opName, args = null, ...zeroCopy) { @@ -263,7 +263,7 @@ SharedQueue Binary Layout close, resources, registerErrorClass, - getErrorClass, + getErrorClassAndArgs, sharedQueueInit: init, // sharedQueue is private but exposed for testing. sharedQueue: { diff --git a/runtime/js/10_dispatch_minimal.js b/runtime/js/10_dispatch_minimal.js index 4d6af6fc374331..e74f8c3934ff19 100644 --- a/runtime/js/10_dispatch_minimal.js +++ b/runtime/js/10_dispatch_minimal.js @@ -51,13 +51,13 @@ function unwrapResponse(res) { if (res.err != null) { - const ErrorClass = core.getErrorClass(res.err.className); + const [ErrorClass, args] = core.getErrorClassAndArgs(res.err.className); if (!ErrorClass) { throw new Error( `Unregistered error class: "${res.err.className}"\n ${res.err.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`, ); } - throw new ErrorClass(res.err.message); + throw new ErrorClass(res.err.message, ...args); } return res.result; } From cf076ec95226631ce810aecae0ccc63c597c8a4e Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 25 Feb 2021 22:35:03 +0100 Subject: [PATCH 137/144] error handling --- Cargo.lock | 4 +- op_crates/webgpu/01_webgpu.js | 419 +++++++++++++++++++++------- op_crates/webgpu/binding.rs | 17 +- op_crates/webgpu/buffer.rs | 16 +- op_crates/webgpu/bundle.rs | 19 +- op_crates/webgpu/command_encoder.rs | 87 +++--- op_crates/webgpu/compute_pass.rs | 14 +- op_crates/webgpu/error.rs | 252 +++++++++++++++++ op_crates/webgpu/lib.rs | 46 ++- op_crates/webgpu/pipeline.rs | 22 +- op_crates/webgpu/queue.rs | 21 +- op_crates/webgpu/render_pass.rs | 6 +- op_crates/webgpu/sampler.rs | 7 +- op_crates/webgpu/shader.rs | 7 +- op_crates/webgpu/texture.rs | 11 +- runtime/errors.rs | 1 + runtime/js/99_main.js | 1 + 17 files changed, 740 insertions(+), 210 deletions(-) create mode 100644 op_crates/webgpu/error.rs diff --git a/Cargo.lock b/Cargo.lock index a9053f378e12a1..6800e922bdaed0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3985,9 +3985,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b0acbc906c464cb75dac28062a8591ec9fe0ce61e271bb732c43196dc6aa1" +checksum = "c89fa2cc5d72236461ac09c5be967012663e29cb62f1a972654cbf35e49dffa8" dependencies = [ "arrayvec", "bitflags", diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index 2f28107c17c9e5..e4dac42425707c 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -27,7 +27,7 @@ "OperationError", ); } - return { ...device, rid: deviceRid }; + return device; } /** @@ -155,12 +155,12 @@ context: "Argument 1", }); - const { error, ...data } = await core.jsonOpAsync( + const { err, ...data } = await core.jsonOpAsync( "op_webgpu_request_adapter", { ...options }, ); - if (error) { + if (err) { return null; } else { return createGPUAdapter(data.name, data); @@ -258,14 +258,12 @@ }, ); - /** @type {InnerGPUDevice} */ - const inner = { + const inner = new InnerGPUDevice({ rid, adapter: this, features: Object.freeze(features), limits: Object.freeze(limits), - resources: [], - }; + }); return createGPUDevice( descriptor.label ?? null, inner, @@ -450,6 +448,49 @@ } } + const _reason = Symbol("[[reason]]"); + const _message = Symbol("[[message]]"); + + /** + * + * @param {string | undefined} reason + * @param {string} message + * @returns {GPUDeviceLostInfo} + */ + function createGPUDeviceLostInfo(reason, message) { + /** @type {GPUDeviceLostInfo} */ + const deviceLostInfo = webidl.createBranded(GPUDeviceLostInfo); + deviceLostInfo[_reason] = reason; + deviceLostInfo[_message] = message; + return deviceLostInfo; + } + + class GPUDeviceLostInfo { + /** @type {string | undefined} */ + [_reason]; + /** @type {string} */ + [_message]; + + constructor() { + webidl.illegalConstructor(); + } + + get reason() { + webidl.assertBranded(this, GPUDeviceLostInfo); + return this[_reason]; + } + get message() { + webidl.assertBranded(this, GPUDeviceLostInfo); + return this[_message]; + } + + [Symbol.for("Deno.customInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ reason: this[_reason], message: this[_message] }) + }`; + } + } + const _label = Symbol("[[label]]"); /** @@ -483,15 +524,103 @@ const _device = Symbol("[[device]]"); const _queue = Symbol("[[queue]]"); + /** + * @typedef ErrorScope + * @property {string} filter + * @property {GPUError | undefined} error + */ + /** - * @typedef InnerGPUDevice + * @typedef InnerGPUDeviceOptions * @property {GPUAdapter} adapter * @property {number | undefined} rid * @property {GPUFeatureName[]} features * @property {object} limits - * @property {WeakRef[]} resources */ + class InnerGPUDevice { + /** @type {GPUAdapter} */ + adapter; + /** @type {number | undefined} */ + rid; + /** @type {GPUFeatureName[]} */ + features; + /** @type {object} */ + limits; + /** @type {WeakRef[]} */ + resources; + /** @type {boolean} */ + isLost; + /** @type {Promise} */ + lost; + /** @type {(info: GPUDeviceLostInfo) => void} */ + resolveLost; + /** @type {ErrorScope[]} */ + errorScopeStack; + + /** + * @param {InnerGPUDeviceOptions} options + */ + constructor(options) { + this.adapter = options.adapter; + this.rid = options.rid; + this.features = options.features; + this.limits = options.limits; + this.resources = []; + this.isLost = false; + this.resolveLost = () => {}; + this.lost = new Promise((resolve) => { + this.resolveLost = resolve; + }); + this.errorScopeStack = []; + } + + /** @param {any} resource */ + trackResource(resource) { + this.resources.push(new WeakRef(resource)); + } + + /** @param {{ type: string, value: string | null } | undefined} err */ + pushError(err) { + if (err) { + switch (err.type) { + case "lost": + this.isLost = true; + this.resolveLost( + createGPUDeviceLostInfo(undefined, "device was lost"), + ); + break; + case "validation": + case "out-of-memory": + for ( + let i = this.errorScopeStack.length - 1; + i >= 0; + i-- + ) { + const scope = this.errorScopeStack[i]; + if (scope.filter == err.type) { + if (!scope.error) { + switch (err.type) { + case "validation": + scope.error = new GPUValidationError( + err.value ?? "validation error", + ); + break; + case "out-of-memory": + scope.error = new GPUOutOfMemoryError(); + break; + } + } + return; + } + } + // TODO(lucacasonato): emit a UncapturedErrorEvent + break; + } + } + } + } + /** * @param {string | null} label * @param {InnerGPUDevice} inner @@ -572,10 +701,11 @@ context: "Argument 1", }); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_buffer", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_buffer", { deviceRid: device.rid, ...descriptor, }); + device.pushError(err); /** @type {CreateGPUBufferOptions} */ let options; if (descriptor.mappedAtCreation) { @@ -601,7 +731,7 @@ descriptor.usage, options, ); - device.resources.push(new WeakRef(buffer)); + device.trackResource((buffer)); return buffer; } @@ -618,18 +748,19 @@ context: "Argument 1", }); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_texture", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_texture", { deviceRid: device.rid, ...descriptor, size: normalizeGPUExtent3D(descriptor.size), }); + device.pushError(err); const texture = createGPUTexture( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(texture)); + device.trackResource((texture)); return texture; } @@ -645,17 +776,18 @@ context: "Argument 1", }); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_sampler", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_sampler", { deviceRid: device.rid, ...descriptor, }); + device.pushError(err); const sampler = createGPUSampler( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(sampler)); + device.trackResource((sampler)); return sampler; } @@ -684,17 +816,21 @@ } } - const { rid } = core.jsonOpSync("op_webgpu_create_bind_group_layout", { - deviceRid: device.rid, - ...descriptor, - }); + const { rid, err } = core.jsonOpSync( + "op_webgpu_create_bind_group_layout", + { + deviceRid: device.rid, + ...descriptor, + }, + ); + device.pushError(err); const bindGroupLayout = createGPUBindGroupLayout( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(bindGroupLayout)); + device.trackResource((bindGroupLayout)); return bindGroupLayout; } @@ -723,18 +859,19 @@ return rid; }, ); - const { rid } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_pipeline_layout", { deviceRid: device.rid, label: descriptor.label, bindGroupLayouts, }); + device.pushError(err); const pipelineLayout = createGPUPipelineLayout( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(pipelineLayout)); + device.trackResource((pipelineLayout)); return pipelineLayout; } @@ -814,19 +951,20 @@ } }); - const { rid } = core.jsonOpSync("op_webgpu_create_bind_group", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_bind_group", { deviceRid: device.rid, label: descriptor.label, layout, entries, }); + device.pushError(err); const bindGroup = createGPUBindGroup( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(bindGroup)); + device.trackResource((bindGroup)); return bindGroup; } @@ -842,7 +980,7 @@ context: "Argument 1", }); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync( + const { rid, err } = core.jsonOpSync( "op_webgpu_create_shader_module", { deviceRid: device.rid, @@ -856,13 +994,14 @@ ? [new Uint8Array(descriptor.code.buffer)] : []), ); + device.pushError(err); const shaderModule = createGPUShaderModule( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(shaderModule)); + device.trackResource((shaderModule)); return shaderModule; } @@ -899,22 +1038,26 @@ selfContext: "this", }); - const { rid } = core.jsonOpSync("op_webgpu_create_compute_pipeline", { - deviceRid: device.rid, - label: descriptor.label, - layout, - compute: { - module, - entryPoint: descriptor.compute.entryPoint, + const { rid, err } = core.jsonOpSync( + "op_webgpu_create_compute_pipeline", + { + deviceRid: device.rid, + label: descriptor.label, + layout, + compute: { + module, + entryPoint: descriptor.compute.entryPoint, + }, }, - }); + ); + device.pushError(err); const computePipeline = createGPUComputePipeline( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(computePipeline)); + device.trackResource((computePipeline)); return computePipeline; } @@ -968,7 +1111,7 @@ }; } - const { rid } = core.jsonOpSync("op_webgpu_create_render_pipeline", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_render_pipeline", { deviceRid: device.rid, label: descriptor.label, layout, @@ -982,13 +1125,14 @@ multisample: descriptor.multisample, fragment, }); + device.pushError(err); const renderPipeline = createGPURenderPipeline( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(renderPipeline)); + device.trackResource((renderPipeline)); return renderPipeline; } @@ -1014,17 +1158,18 @@ context: "Argument 1", }); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_command_encoder", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_command_encoder", { deviceRid: device.rid, ...descriptor, }); + device.pushError(err); const commandEncoder = createGPUCommandEncoder( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(commandEncoder)); + device.trackResource((commandEncoder)); return commandEncoder; } @@ -1045,20 +1190,21 @@ }, ); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync( + const { rid, err } = core.jsonOpSync( "op_webgpu_create_render_bundle_encoder", { deviceRid: device.rid, ...descriptor, }, ); + device.pushError(err); const renderBundleEncoder = createGPURenderBundleEncoder( descriptor.label ?? null, device, rid, ); - device.resources.push(new WeakRef(renderBundleEncoder)); + device.trackResource((renderBundleEncoder)); return renderBundleEncoder; } @@ -1078,10 +1224,11 @@ }, ); const device = assertDevice(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_query_set", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_query_set", { deviceRid: device.rid, ...descriptor, }); + device.pushError(err); const querySet = createGPUQuerySet( descriptor.label ?? null, @@ -1089,10 +1236,57 @@ rid, descriptor, ); - device.resources.push(new WeakRef(querySet)); + device.trackResource((querySet)); return querySet; } + get lost() { + webidl.assertBranded(this, GPUDevice); + const device = this[_device]; + if (!device) { + return Promise.resolve(true); + } + if (device.rid === undefined) { + return Promise.resolve(true); + } + return device.lost; + } + + /** + * @param {GPUErrorFilter} filter + */ + pushErrorScope(filter) { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'pushErrorScope' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + filter = webidl.converters.GPUErrorFilter(filter, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + device.errorScopeStack.push({ filter, error: undefined }); + } + + /** + * @returns {Promise} + */ + async popErrorScope() { + webidl.assertBranded(this, GPUDevice); + const prefix = "Failed to execute 'pushErrorScope' on 'GPUDevice'"; + const device = assertDevice(this, { prefix, context: "this" }); + if (device.isLost) { + throw new DOMException("Device has been lost.", "OperationError"); + } + const scope = device.errorScopeStack.pop(); + if (!scope) { + throw new DOMException( + "There are no error scopes on that stack.", + "OperationError", + ); + } + return scope.error ?? null; + } + [Symbol.for("Deno.customInspect")](inspect) { return `${this.constructor.name} ${ inspect({ @@ -1152,10 +1346,11 @@ }); return rid; }); - core.jsonOpSync("op_webgpu_queue_submit", { + const { err } = core.jsonOpSync("op_webgpu_queue_submit", { queueRid: device.rid, commandBuffers: commandBufferRids, }); + device.pushError(err); } onSubmittedWorkDone() { @@ -1206,7 +1401,7 @@ selfContext: "this", resourceContext: "Argument 1", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_write_buffer", { queueRid: device.rid, @@ -1217,6 +1412,7 @@ }, new Uint8Array(ArrayBuffer.isView(data) ? data.buffer : data), ); + device.pushError(err); } /** @@ -1255,7 +1451,7 @@ selfContext: "this", resourceContext: "texture", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_write_texture", { queueRid: device.rid, @@ -1271,6 +1467,7 @@ }, new Uint8Array(ArrayBuffer.isView(data) ? data.buffer : data), ); + device.pushError(err); } copyImageBitmapToTexture(_source, _destination, _copySize) { @@ -1454,7 +1651,7 @@ this[_mapMode] = mode; this[_state] = "mapping pending"; - await core.jsonOpAsync( + const { err } = await core.jsonOpAsync( "op_webgpu_buffer_get_map_async", { bufferRid, @@ -1464,6 +1661,7 @@ size: rangeSize, }, ); + device.pushError(err); this[_state] = "mapped"; this[_mappingRange] = [offset, offset + rangeSize]; /** @type {[ArrayBuffer, number, number][] | null} */ @@ -1567,7 +1765,7 @@ unmap() { webidl.assertBranded(this, GPUBuffer); const prefix = "Failed to execute 'unmap' on 'GPUBuffer'"; - assertDevice(this, { prefix, context: "this" }); + const device = assertDevice(this, { prefix, context: "this" }); const bufferRid = assertResource(this, { prefix, context: "this" }); if (this[_state] === "unmapped" || this[_state] === "destroyed") { throw new DOMException( @@ -1606,10 +1804,12 @@ throw new DOMException(`${prefix}: invalid state.`, "OperationError"); } for (const [buffer, mappedRid] of mappedRanges) { - core.jsonOpSync("op_webgpu_buffer_unmap", { + const { err } = core.jsonOpSync("op_webgpu_buffer_unmap", { bufferRid, mappedRid, }, ...(write ? [new Uint8Array(buffer)] : [])); + device.pushError(err); + if (err) return; } this[_mappingRange] = null; this[_mappedRanges] = null; @@ -1740,12 +1940,13 @@ prefix, context: "Argument 1", }); - assertDevice(this, { prefix, context: "this" }); + const device = assertDevice(this, { prefix, context: "this" }); const textureRid = assertResource(this, { prefix, context: "this" }); - const { rid } = core.jsonOpSync("op_webgpu_create_texture_view", { + const { rid, err } = core.jsonOpSync("op_webgpu_create_texture_view", { textureRid, ...descriptor, }); + device.pushError(err); const textureView = createGPUTextureView( descriptor.label ?? null, @@ -2126,17 +2327,18 @@ prefix, context: "this", }); - const { rid, label } = core.jsonOpSync( + const { rid, label, err } = core.jsonOpSync( "op_webgpu_compute_pipeline_get_bind_group_layout", { computePipelineRid, index }, ); + device.pushError(err); const bindGroupLayout = createGPUBindGroupLayout( label, device, rid, ); - device.resources.push(new WeakRef(bindGroupLayout)); + device.trackResource((bindGroupLayout)); return bindGroupLayout; } @@ -2200,17 +2402,18 @@ prefix, context: "this", }); - const { rid, label } = core.jsonOpSync( + const { rid, label, err } = core.jsonOpSync( "op_webgpu_render_pipeline_get_bind_group_layout", { renderPipelineRid, index }, ); + device.pushError(err); const bindGroupLayout = createGPUBindGroupLayout( label, device, rid, ); - device.resources.push(new WeakRef(bindGroupLayout)); + device.trackResource((bindGroupLayout)); return bindGroupLayout; } @@ -2540,7 +2743,7 @@ selfContext: "this", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_buffer", { commandEncoderRid, @@ -2551,6 +2754,7 @@ size, }, ); + device.pushError(err); } /** @@ -2599,7 +2803,7 @@ selfContext: "this", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_command_encoder_copy_buffer_to_texture", { commandEncoderRid, @@ -2617,6 +2821,7 @@ copySize: normalizeGPUExtent3D(copySize), }, ); + device.pushError(err); } /** @@ -2664,7 +2869,7 @@ resourceContext: "buffer in Argument 2", selfContext: "this", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_buffer", { commandEncoderRid, @@ -2682,6 +2887,7 @@ copySize: normalizeGPUExtent3D(copySize), }, ); + device.pushError(err); } /** @@ -2729,7 +2935,7 @@ resourceContext: "texture in Argument 2", selfContext: "this", }); - core.jsonOpSync( + const { err } = core.jsonOpSync( "op_webgpu_command_encoder_copy_texture_to_texture", { commandEncoderRid, @@ -2750,6 +2956,7 @@ copySize: normalizeGPUExtent3D(copySize), }, ); + device.pushError(err); } /** @@ -2764,28 +2971,36 @@ prefix, context: "Argument 1", }); - assertDevice(this, { prefix, context: "this" }); + const device = assertDevice(this, { prefix, context: "this" }); const commandEncoderRid = assertResource(this, { prefix, context: "this", }); - core.jsonOpSync("op_webgpu_command_encoder_push_debug_group", { - commandEncoderRid, - groupLabel, - }); + const { err } = core.jsonOpSync( + "op_webgpu_command_encoder_push_debug_group", + { + commandEncoderRid, + groupLabel, + }, + ); + device.pushError(err); } popDebugGroup() { webidl.assertBranded(this, GPUCommandEncoder); const prefix = "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder'"; - assertDevice(this, { prefix, context: "this" }); + const device = assertDevice(this, { prefix, context: "this" }); const commandEncoderRid = assertResource(this, { prefix, context: "this", }); - core.jsonOpSync("op_webgpu_command_encoder_pop_debug_group", { - commandEncoderRid, - }); + const { err } = core.jsonOpSync( + "op_webgpu_command_encoder_pop_debug_group", + { + commandEncoderRid, + }, + ); + device.pushError(err); } /** @@ -2800,15 +3015,19 @@ prefix, context: "Argument 1", }); - assertDevice(this, { prefix, context: "this" }); + const device = assertDevice(this, { prefix, context: "this" }); const commandEncoderRid = assertResource(this, { prefix, context: "this", }); - core.jsonOpSync("op_webgpu_command_encoder_insert_debug_marker", { - commandEncoderRid, - markerLabel, - }); + const { err } = core.jsonOpSync( + "op_webgpu_command_encoder_insert_debug_marker", + { + commandEncoderRid, + markerLabel, + }, + ); + device.pushError(err); } /** @@ -2842,11 +3061,15 @@ resourceContext: "Argument 1", selfContext: "this", }); - core.jsonOpSync("op_webgpu_command_encoder_write_timestamp", { - commandEncoderRid, - querySet: querySetRid, - queryIndex, - }); + const { err } = core.jsonOpSync( + "op_webgpu_command_encoder_write_timestamp", + { + commandEncoderRid, + querySet: querySetRid, + queryIndex, + }, + ); + device.pushError(err); } /** @@ -2910,14 +3133,18 @@ resourceContext: "Argument 3", selfContext: "this", }); - core.jsonOpSync("op_webgpu_command_encoder_resolve_query_set", { - commandEncoderRid, - querySet: querySetRid, - firstQuery, - queryCount, - destination: destinationRid, - destinationOffset, - }); + const { err } = core.jsonOpSync( + "op_webgpu_command_encoder_resolve_query_set", + { + commandEncoderRid, + querySet: querySetRid, + firstQuery, + queryCount, + destination: destinationRid, + destinationOffset, + }, + ); + device.pushError(err); } /** @@ -2936,10 +3163,11 @@ prefix, context: "this", }); - const { rid } = core.jsonOpSync("op_webgpu_command_encoder_finish", { + const { rid, err } = core.jsonOpSync("op_webgpu_command_encoder_finish", { commandEncoderRid, ...descriptor, }); + device.pushError(err); /** @type {number | undefined} */ this[_rid] = undefined; @@ -2948,7 +3176,7 @@ device, rid, ); - device.resources.push(new WeakRef(commandBuffer)); + device.trackResource((commandBuffer)); return commandBuffer; } @@ -3296,7 +3524,7 @@ endPass() { webidl.assertBranded(this, GPURenderPassEncoder); const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; - assertDevice(this[_encoder], { + const device = assertDevice(this[_encoder], { prefix, context: "encoder referenced by this", }); @@ -3305,10 +3533,11 @@ context: "encoder referenced by this", }); const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.jsonOpSync("op_webgpu_render_pass_end_pass", { + const { err } = core.jsonOpSync("op_webgpu_render_pass_end_pass", { commandEncoderRid, renderPassRid, }); + device.pushError(err); this[_rid] = undefined; } @@ -4027,7 +4256,7 @@ endPass() { webidl.assertBranded(this, GPUComputePassEncoder); const prefix = "Failed to execute 'endPass' on 'GPUComputePassEncoder'"; - assertDevice(this[_encoder], { + const device = assertDevice(this[_encoder], { prefix, context: "encoder referenced by this", }); @@ -4036,10 +4265,11 @@ context: "encoder referenced by this", }); const computePassRid = assertResource(this, { prefix, context: "this" }); - core.jsonOpSync("op_webgpu_compute_pass_end_pass", { + const { err } = core.jsonOpSync("op_webgpu_compute_pass_end_pass", { commandEncoderRid, computePassRid, }); + device.pushError(err); this[_rid] = undefined; } @@ -4277,13 +4507,14 @@ prefix, context: "this", }); - const { rid } = core.jsonOpSync( + const { rid, err } = core.jsonOpSync( "op_webgpu_render_bundle_encoder_finish", { renderBundleEncoderRid, ...descriptor, }, ); + device.pushError(err); this[_rid] = undefined; const renderBundle = createGPURenderBundle( @@ -4291,7 +4522,7 @@ device, rid, ); - device.resources.push(new WeakRef(renderBundle)); + device.trackResource((renderBundle)); return renderBundle; } diff --git a/op_crates/webgpu/binding.rs b/op_crates/webgpu/binding.rs index 0602e3c73d7c7b..b93b223cf54d64 100644 --- a/op_crates/webgpu/binding.rs +++ b/op_crates/webgpu/binding.rs @@ -9,6 +9,8 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::error::WebGPUError; + pub(crate) struct WebGPUBindGroupLayout( pub(crate) wgpu_core::id::BindGroupLayoutId, ); @@ -194,11 +196,11 @@ pub fn op_webgpu_create_bind_group_layout( entries: Cow::from(entries), }; - let bind_group_layout = gfx_select_err!(device => instance.device_create_bind_group_layout( + let (bind_group_layout, maybe_err) = gfx_select!(device => instance.device_create_bind_group_layout( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -206,6 +208,7 @@ pub fn op_webgpu_create_bind_group_layout( Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } @@ -245,11 +248,11 @@ pub fn op_webgpu_create_pipeline_layout( push_constant_ranges: Default::default(), }; - let pipeline_layout = gfx_select_err!(device => instance.device_create_pipeline_layout( + let (pipeline_layout, maybe_err) = gfx_select!(device => instance.device_create_pipeline_layout( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -257,6 +260,7 @@ pub fn op_webgpu_create_pipeline_layout( Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } @@ -343,15 +347,16 @@ pub fn op_webgpu_create_bind_group( entries: Cow::from(entries), }; - let bind_group = gfx_select_err!(device => instance.device_create_bind_group( + let (bind_group, maybe_err) = gfx_select!(device => instance.device_create_bind_group( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUBindGroup(bind_group)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/buffer.rs b/op_crates/webgpu/buffer.rs index c14cd4409e3990..8ff9f311530c6d 100644 --- a/op_crates/webgpu/buffer.rs +++ b/op_crates/webgpu/buffer.rs @@ -14,6 +14,9 @@ use std::cell::RefCell; use std::rc::Rc; use std::time::Duration; +use super::error::DOMExceptionOperationError; +use super::error::WebGPUError; + pub(crate) struct WebGPUBuffer(pub(crate) wgpu_core::id::BufferId); impl Resource for WebGPUBuffer { fn name(&self) -> Cow { @@ -57,16 +60,17 @@ pub fn op_webgpu_create_buffer( mapped_at_creation: args.mapped_at_creation.unwrap_or(false), }; - let buffer = gfx_select_err!(device => instance.device_create_buffer( + let (buffer, maybe_err) = gfx_select!(device => instance.device_create_buffer( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUBuffer(buffer)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } @@ -119,6 +123,7 @@ pub async fn op_webgpu_buffer_get_map_async( .unwrap(); } + // TODO(lucacasonato): error handling gfx_select!(buffer => instance.buffer_map_async( buffer, args.offset..(args.offset + args.size), @@ -184,7 +189,8 @@ pub fn op_webgpu_buffer_get_mapped_range( buffer, args.offset, std::num::NonZeroU64::new(args.size) - ))?; + )) + .map_err(|e| DOMExceptionOperationError::new(&e.to_string()))?; let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, args.size as usize) @@ -231,7 +237,7 @@ pub fn op_webgpu_buffer_unmap( slice.copy_from_slice(&buffer); } - gfx_select!(buffer => instance.buffer_unmap(buffer))?; + let maybe_err = gfx_select!(buffer => instance.buffer_unmap(buffer)).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/bundle.rs b/op_crates/webgpu/bundle.rs index 424bb628edd186..7043b0a9e47327 100644 --- a/op_crates/webgpu/bundle.rs +++ b/op_crates/webgpu/bundle.rs @@ -11,6 +11,7 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; +use super::error::WebGPUError; use super::texture::serialize_texture_format; struct WebGPURenderBundleEncoder( @@ -65,8 +66,16 @@ pub fn op_webgpu_create_render_bundle_encoder( .transpose()?, sample_count: args.sample_count.unwrap_or(1), }; - let render_bundle_encoder = - wgpu_core::command::RenderBundleEncoder::new(&descriptor, device, None)?; + + let res = + wgpu_core::command::RenderBundleEncoder::new(&descriptor, device, None); + let (render_bundle_encoder, maybe_err) = match res { + Ok(encoder) => (encoder, None), + Err(e) => ( + wgpu_core::command::RenderBundleEncoder::dummy(device), + Some(e), + ), + }; let rid = state .resource_table @@ -76,6 +85,7 @@ pub fn op_webgpu_create_render_bundle_encoder( Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from), })) } @@ -102,18 +112,19 @@ pub fn op_webgpu_render_bundle_encoder_finish( .into_inner(); let instance = state.borrow::(); - let render_bundle = gfx_select_err!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + let (render_bundle, maybe_err) = gfx_select!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgpu_core::command::RenderBundleDescriptor { label: args.label.map(Cow::from), }, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPURenderBundle(render_bundle)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/command_encoder.rs b/op_crates/webgpu/command_encoder.rs index 58f2f506ec232e..b91f677ee8f185 100644 --- a/op_crates/webgpu/command_encoder.rs +++ b/op_crates/webgpu/command_encoder.rs @@ -10,6 +10,8 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; +use super::error::WebGPUError; + pub(crate) struct WebGPUCommandEncoder( pub(crate) wgpu_core::id::CommandEncoderId, ); @@ -60,11 +62,11 @@ pub fn op_webgpu_create_command_encoder( label: args.label.map(Cow::from), }; - let command_encoder = gfx_select_err!(device => instance.device_create_command_encoder( + let (command_encoder, maybe_err) = gfx_select!(device => instance.device_create_command_encoder( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state .resource_table @@ -72,6 +74,7 @@ pub fn op_webgpu_create_command_encoder( Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from), })) } @@ -307,16 +310,16 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .ok_or_else(bad_resource_id)?; let destination_buffer = destination_buffer_resource.0; - gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( command_encoder, source_buffer, args.source_offset, destination_buffer, args.destination_offset, args.size - ))?; + )).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -394,7 +397,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( z: origin.z.unwrap_or(0), }), }; - gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_texture( + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_copy_buffer_to_texture( command_encoder, &source, &destination, @@ -403,9 +406,9 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), } - ))?; + )).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -456,7 +459,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( rows_per_image: args.destination.rows_per_image.unwrap_or(0), }, }; - gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_buffer( + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_buffer( command_encoder, &source, &destination, @@ -465,9 +468,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), } - ))?; + )).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -522,7 +525,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( z: origin.z.unwrap_or(0), }), }; - gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_texture( + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_copy_texture_to_texture( command_encoder, &source, &destination, @@ -531,9 +534,9 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( height: args.copy_size.height.unwrap_or(1), depth: args.copy_size.depth.unwrap_or(1), } - ))?; + )).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -555,10 +558,11 @@ pub fn op_webgpu_command_encoder_push_debug_group( .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - gfx_select!(command_encoder => instance - .command_encoder_push_debug_group(command_encoder, &args.group_label))?; + let maybe_err = gfx_select!(command_encoder => instance + .command_encoder_push_debug_group(command_encoder, &args.group_label)) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -579,9 +583,9 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))?; + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder)).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -603,12 +607,12 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .ok_or_else(bad_resource_id)?; let command_encoder = command_encoder_resource.0; - gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, &args.marker_label - ))?; + )).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -635,13 +639,15 @@ pub fn op_webgpu_command_encoder_write_timestamp( .get::(args.query_set) .ok_or_else(bad_resource_id)?; - gfx_select!(command_encoder => instance.command_encoder_write_timestamp( - command_encoder, - query_set_resource.0, - args.query_index - ))?; + let maybe_err = + gfx_select!(command_encoder => instance.command_encoder_write_timestamp( + command_encoder, + query_set_resource.0, + args.query_index + )) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -675,16 +681,18 @@ pub fn op_webgpu_command_encoder_resolve_query_set( .get::(args.destination) .ok_or_else(bad_resource_id)?; - gfx_select!(command_encoder => instance.command_encoder_resolve_query_set( - command_encoder, - query_set_resource.0, - args.first_query, - args.query_count, - destination_resource.0, - args.destination_offset - ))?; + let maybe_err = + gfx_select!(command_encoder => instance.command_encoder_resolve_query_set( + command_encoder, + query_set_resource.0, + args.first_query, + args.query_count, + destination_resource.0, + args.destination_offset + )) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -710,10 +718,10 @@ pub fn op_webgpu_command_encoder_finish( label: args.label.map(Cow::from), }; - let command_buffer = gfx_select_err!(command_encoder => instance.command_encoder_finish( + let (command_buffer, maybe_err) = gfx_select!(command_encoder => instance.command_encoder_finish( command_encoder, &descriptor - ))?; + )); let rid = state .resource_table @@ -721,5 +729,6 @@ pub fn op_webgpu_command_encoder_finish( Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/compute_pass.rs b/op_crates/webgpu/compute_pass.rs index da43c092f3112f..711bdea97ad8d0 100644 --- a/op_crates/webgpu/compute_pass.rs +++ b/op_crates/webgpu/compute_pass.rs @@ -10,6 +10,8 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; +use super::error::WebGPUError; + pub(crate) struct WebGPUComputePass( pub(crate) RefCell, ); @@ -225,12 +227,14 @@ pub fn op_webgpu_compute_pass_end_pass( let compute_pass = &compute_pass_resource.0.borrow(); let instance = state.borrow::(); - gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( - command_encoder, - compute_pass - ))?; + let maybe_err = + gfx_select!(command_encoder => instance.command_encoder_run_compute_pass( + command_encoder, + compute_pass + )) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] diff --git a/op_crates/webgpu/error.rs b/op_crates/webgpu/error.rs new file mode 100644 index 00000000000000..e793dabfa3e7c7 --- /dev/null +++ b/op_crates/webgpu/error.rs @@ -0,0 +1,252 @@ +use deno_core::error::AnyError; +use serde::Serialize; +use std::fmt; +use wgpu_core::binding_model::CreateBindGroupError; +use wgpu_core::binding_model::CreateBindGroupLayoutError; +use wgpu_core::binding_model::CreatePipelineLayoutError; +use wgpu_core::binding_model::GetBindGroupLayoutError; +use wgpu_core::command::CommandAllocatorError; +use wgpu_core::command::CommandEncoderError; +use wgpu_core::command::ComputePassError; +use wgpu_core::command::CopyError; +use wgpu_core::command::CreateRenderBundleError; +use wgpu_core::command::QueryError; +use wgpu_core::command::RenderBundleError; +use wgpu_core::command::RenderPassError; +use wgpu_core::device::queue::QueueSubmitError; +use wgpu_core::device::queue::QueueWriteError; +use wgpu_core::device::DeviceError; +use wgpu_core::pipeline::CreateComputePipelineError; +use wgpu_core::pipeline::CreateRenderPipelineError; +use wgpu_core::pipeline::CreateShaderModuleError; +use wgpu_core::resource::BufferAccessError; +use wgpu_core::resource::CreateBufferError; +use wgpu_core::resource::CreateQuerySetError; +use wgpu_core::resource::CreateSamplerError; +use wgpu_core::resource::CreateTextureError; +use wgpu_core::resource::CreateTextureViewError; + +#[derive(Serialize)] +#[serde(tag = "type", content = "value")] +#[serde(rename_all = "kebab-case")] +pub enum WebGPUError { + Lost, + OutOfMemory, + Validation(String), +} + +impl From for WebGPUError { + fn from(err: CreateBufferError) -> Self { + match err { + CreateBufferError::Device(err) => err.into(), + CreateBufferError::AccessError(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: DeviceError) -> Self { + match err { + DeviceError::Lost => WebGPUError::Lost, + DeviceError::OutOfMemory => WebGPUError::OutOfMemory, + DeviceError::Invalid => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: BufferAccessError) -> Self { + match err { + BufferAccessError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreateBindGroupLayoutError) -> Self { + match err { + CreateBindGroupLayoutError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreatePipelineLayoutError) -> Self { + match err { + CreatePipelineLayoutError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreateBindGroupError) -> Self { + match err { + CreateBindGroupError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: RenderBundleError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CreateRenderBundleError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CommandAllocatorError) -> Self { + match err { + CommandAllocatorError::Device(err) => err.into(), + } + } +} + +impl From for WebGPUError { + fn from(err: CopyError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CommandEncoderError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: QueryError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: ComputePassError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CreateComputePipelineError) -> Self { + match err { + CreateComputePipelineError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: GetBindGroupLayoutError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CreateRenderPipelineError) -> Self { + match err { + CreateRenderPipelineError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: RenderPassError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CreateSamplerError) -> Self { + match err { + CreateSamplerError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreateShaderModuleError) -> Self { + match err { + CreateShaderModuleError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreateTextureError) -> Self { + match err { + CreateTextureError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: CreateTextureViewError) -> Self { + WebGPUError::Validation(err.to_string()) + } +} + +impl From for WebGPUError { + fn from(err: CreateQuerySetError) -> Self { + match err { + CreateQuerySetError::Device(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: QueueSubmitError) -> Self { + match err { + QueueSubmitError::Queue(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +impl From for WebGPUError { + fn from(err: QueueWriteError) -> Self { + match err { + QueueWriteError::Queue(err) => err.into(), + err => WebGPUError::Validation(err.to_string()), + } + } +} + +#[derive(Debug)] +pub struct DOMExceptionOperationError { + pub msg: String, +} + +impl DOMExceptionOperationError { + pub fn new(msg: &str) -> Self { + DOMExceptionOperationError { + msg: msg.to_string(), + } + } +} + +impl fmt::Display for DOMExceptionOperationError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad(&self.msg) + } +} + +impl std::error::Error for DOMExceptionOperationError {} + +pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { + e.downcast_ref::() + .map(|_| "DOMExceptionOperationError") +} diff --git a/op_crates/webgpu/lib.rs b/op_crates/webgpu/lib.rs index 830171a552c9ff..2f1769dafe88a9 100644 --- a/op_crates/webgpu/lib.rs +++ b/op_crates/webgpu/lib.rs @@ -17,6 +17,9 @@ use std::rc::Rc; pub use wgpu_core; pub use wgpu_types; +use error::DOMExceptionOperationError; +use error::WebGPUError; + #[macro_use] mod macros { macro_rules! gfx_select { @@ -36,19 +39,6 @@ mod macros { } }; } - - macro_rules! gfx_select_err { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { - { - let (data, err) = gfx_select!($id => $global.$method( $($param),* )); - if let Some(err) = err { - Err(err) - } else { - Ok(data) - } - } - }; - } } pub mod binding; @@ -56,6 +46,7 @@ pub mod buffer; pub mod bundle; pub mod command_encoder; pub mod compute_pass; +pub mod error; pub mod pipeline; pub mod queue; pub mod render_pass; @@ -219,7 +210,7 @@ pub async fn op_webgpu_request_adapter( }, compatible_surface: None, // windowless }; - let adapter = instance.request_adapter( + let res = instance.request_adapter( &descriptor, wgpu_core::instance::AdapterInputs::Mask( wgpu_types::BackendBit::PRIMARY, @@ -227,13 +218,14 @@ pub async fn op_webgpu_request_adapter( ), ); - if adapter.is_err() { - return Ok(json!({ - "error": true - })); - } - - let adapter = adapter.unwrap(); + let adapter = match res { + Ok(adapter) => adapter, + Err(err) => { + return Ok(json!({ + "err": err.to_string() + })) + } + }; let name = gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; let adapter_features = gfx_select!(adapter => instance.adapter_features(adapter))?; @@ -421,12 +413,15 @@ pub async fn op_webgpu_request_device( }), }; - let device = gfx_select_err!(adapter => instance.adapter_request_device( + let (device, maybe_err) = gfx_select!(adapter => instance.adapter_request_device( adapter, &descriptor, std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), std::marker::PhantomData - ))?; + )); + if let Some(err) = maybe_err { + return Err(DOMExceptionOperationError::new(&err.to_string()).into()); + } let device_features = gfx_select!(device => instance.device_features(device))?; @@ -531,15 +526,16 @@ pub fn op_webgpu_create_query_set( count: args.count, }; - let query_set = gfx_select_err!(device => instance.device_create_query_set( + let (query_set, maybe_err) = gfx_select!(device => instance.device_create_query_set( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUQuerySet(query_set)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from), })) } diff --git a/op_crates/webgpu/pipeline.rs b/op_crates/webgpu/pipeline.rs index 83342b2e8d4b7b..04493b18aac4f2 100644 --- a/op_crates/webgpu/pipeline.rs +++ b/op_crates/webgpu/pipeline.rs @@ -9,6 +9,8 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::error::WebGPUError; + pub(crate) struct WebGPUPipelineLayout( pub(crate) wgpu_core::id::PipelineLayoutId, ); @@ -199,23 +201,20 @@ pub fn op_webgpu_create_compute_pipeline( }), }; - let (compute_pipeline, _, err) = gfx_select!(device => instance.device_create_compute_pipeline( + let (compute_pipeline, _, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines )); - if let Some(err) = err { - return Err(err.into()); - } - let rid = state .resource_table .add(WebGPUComputePipeline(compute_pipeline)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from), })) } @@ -238,7 +237,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .ok_or_else(bad_resource_id)?; let compute_pipeline = compute_pipeline_resource.0; - let bind_group_layout = gfx_select_err!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData))?; + let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); @@ -249,6 +248,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( Ok(json!({ "rid": rid, "label": label, + "err": maybe_err.map(WebGPUError::from) })) } @@ -591,23 +591,20 @@ pub fn op_webgpu_create_render_pipeline( }), }; - let (render_pipeline, _, err) = gfx_select!(device => instance.device_create_render_pipeline( + let (render_pipeline, _, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline( device, &descriptor, std::marker::PhantomData, implicit_pipelines )); - if let Some(err) = err { - return Err(err.into()); - } - let rid = state .resource_table .add(WebGPURenderPipeline(render_pipeline)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } @@ -630,7 +627,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .ok_or_else(bad_resource_id)?; let render_pipeline = render_pipeline_resource.0; - let bind_group_layout = gfx_select_err!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData))?; + let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); @@ -641,5 +638,6 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( Ok(json!({ "rid": rid, "label": label, + "err": maybe_err.map(WebGPUError::from), })) } diff --git a/op_crates/webgpu/queue.rs b/op_crates/webgpu/queue.rs index b1c9eab6b2cb38..c141a3c455cd81 100644 --- a/op_crates/webgpu/queue.rs +++ b/op_crates/webgpu/queue.rs @@ -8,6 +8,8 @@ use deno_core::OpState; use deno_core::ZeroCopyBuf; use serde::Deserialize; +use super::error::WebGPUError; + type WebGPUQueue = super::WebGPUDevice; #[derive(Deserialize)] @@ -39,9 +41,10 @@ pub fn op_webgpu_queue_submit( ids.push(buffer_resource.0); } - gfx_select!(queue => instance.queue_submit(queue, &ids))?; + let maybe_err = + gfx_select!(queue => instance.queue_submit(queue, &ids)).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -83,14 +86,15 @@ pub fn op_webgpu_write_buffer( Some(size) => &zero_copy[0][args.data_offset..(args.data_offset + size)], None => &zero_copy[0][args.data_offset..], }; - gfx_select!(queue => instance.queue_write_buffer( + let maybe_err = gfx_select!(queue => instance.queue_write_buffer( queue, buffer, args.buffer_offset, data - ))?; + )) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] @@ -136,7 +140,7 @@ pub fn op_webgpu_write_texture( rows_per_image: args.data_layout.rows_per_image.unwrap_or(0), }; - gfx_select!(queue => instance.queue_write_texture( + let maybe_err = gfx_select!(queue => instance.queue_write_texture( queue, &destination, &*zero_copy[0], @@ -146,7 +150,8 @@ pub fn op_webgpu_write_texture( height: args.size.height.unwrap_or(1), depth: args.size.depth.unwrap_or(1), } - ))?; + )) + .err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/render_pass.rs b/op_crates/webgpu/render_pass.rs index 796a82210a2b45..c9018726b79dc0 100644 --- a/op_crates/webgpu/render_pass.rs +++ b/op_crates/webgpu/render_pass.rs @@ -10,6 +10,8 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; +use super::error::WebGPUError; + pub(crate) struct WebGPURenderPass( pub(crate) RefCell, ); @@ -304,9 +306,9 @@ pub fn op_webgpu_render_pass_end_pass( let render_pass = &render_pass_resource.0.borrow(); let instance = state.borrow::(); - gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass))?; + let maybe_err = gfx_select!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass)).err(); - Ok(json!({})) + Ok(json!({ "err": maybe_err.map(WebGPUError::from) })) } #[derive(Deserialize)] diff --git a/op_crates/webgpu/sampler.rs b/op_crates/webgpu/sampler.rs index d111526a6a346c..48974a3280179b 100644 --- a/op_crates/webgpu/sampler.rs +++ b/op_crates/webgpu/sampler.rs @@ -9,6 +9,8 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::error::WebGPUError; + pub(crate) struct WebGPUSampler(pub(crate) wgpu_core::id::SamplerId); impl Resource for WebGPUSampler { fn name(&self) -> Cow { @@ -112,15 +114,16 @@ pub fn op_webgpu_create_sampler( border_color: None, // native-only }; - let sampler = gfx_select_err!(device => instance.device_create_sampler( + let (sampler, maybe_err) = gfx_select!(device => instance.device_create_sampler( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUSampler(sampler)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/shader.rs b/op_crates/webgpu/shader.rs index da9749f7743761..25adf9b9596151 100644 --- a/op_crates/webgpu/shader.rs +++ b/op_crates/webgpu/shader.rs @@ -9,6 +9,8 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::error::WebGPUError; + pub(crate) struct WebGPUShaderModule(pub(crate) wgpu_core::id::ShaderModuleId); impl Resource for WebGPUShaderModule { fn name(&self) -> Cow { @@ -59,16 +61,17 @@ pub fn op_webgpu_create_shader_module( flags, }; - let shader_module = gfx_select_err!(device => instance.device_create_shader_module( + let (shader_module, maybe_err) = gfx_select!(device => instance.device_create_shader_module( device, &descriptor, source, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUShaderModule(shader_module)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/op_crates/webgpu/texture.rs b/op_crates/webgpu/texture.rs index c4ab76da5132cc..94de28fedd795a 100644 --- a/op_crates/webgpu/texture.rs +++ b/op_crates/webgpu/texture.rs @@ -9,6 +9,7 @@ use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; +use super::error::WebGPUError; pub(crate) struct WebGPUTexture(pub(crate) wgpu_core::id::TextureId); impl Resource for WebGPUTexture { fn name(&self) -> Cow { @@ -176,16 +177,17 @@ pub fn op_webgpu_create_texture( usage: wgpu_types::TextureUsage::from_bits(args.usage).unwrap(), }; - let texture = gfx_select_err!(device => instance.device_create_texture( + let (texture, maybe_err) = gfx_select!(device => instance.device_create_texture( device, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUTexture(texture)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } @@ -239,15 +241,16 @@ pub fn op_webgpu_create_texture_view( ), }; - let texture_view = gfx_select_err!(texture => instance.texture_create_view( + let (texture_view, maybe_err) = gfx_select!(texture => instance.texture_create_view( texture, &descriptor, std::marker::PhantomData - ))?; + )); let rid = state.resource_table.add(WebGPUTextureView(texture_view)); Ok(json!({ "rid": rid, + "err": maybe_err.map(WebGPUError::from) })) } diff --git a/runtime/errors.rs b/runtime/errors.rs index 7c497ef32fd32e..160c56725ccd72 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -164,6 +164,7 @@ fn get_nix_error_class(error: &nix::Error) -> &'static str { pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { deno_core::error::get_custom_error_class(e) + .or_else(|| deno_webgpu::error::get_error_class_name(e)) .or_else(|| { e.downcast_ref::() .map(get_dlopen_error_class) diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 47d4508aeb8c1c..f066a1784230d1 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -196,6 +196,7 @@ delete Object.prototype.__proto__; core.registerErrorClass("SyntaxError", SyntaxError); core.registerErrorClass("TypeError", TypeError); core.registerErrorClass("URIError", URIError); + core.registerErrorClass("DOMExceptionOperationError", DOMException, "OperationError"); } // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope From daa48a9f89f49fc0e7e12506f9c2f90ad57705b7 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 25 Feb 2021 23:12:14 +0100 Subject: [PATCH 138/144] fmt + lint --- op_crates/webgpu/01_webgpu.js | 1 + runtime/js/99_main.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/op_crates/webgpu/01_webgpu.js b/op_crates/webgpu/01_webgpu.js index e4dac42425707c..7a078619e019b7 100644 --- a/op_crates/webgpu/01_webgpu.js +++ b/op_crates/webgpu/01_webgpu.js @@ -1270,6 +1270,7 @@ /** * @returns {Promise} */ + // deno-lint-ignore require-await async popErrorScope() { webidl.assertBranded(this, GPUDevice); const prefix = "Failed to execute 'pushErrorScope' on 'GPUDevice'"; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index f066a1784230d1..811412049aa0bc 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -196,7 +196,11 @@ delete Object.prototype.__proto__; core.registerErrorClass("SyntaxError", SyntaxError); core.registerErrorClass("TypeError", TypeError); core.registerErrorClass("URIError", URIError); - core.registerErrorClass("DOMExceptionOperationError", DOMException, "OperationError"); + core.registerErrorClass( + "DOMExceptionOperationError", + DOMException, + "OperationError", + ); } // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope From 8b2eddc20f80853c2e75e661e7acfa2d5889730d Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 26 Feb 2021 16:48:34 +0100 Subject: [PATCH 139/144] add readme --- op_crates/webgpu/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 op_crates/webgpu/README.md diff --git a/op_crates/webgpu/README.md b/op_crates/webgpu/README.md new file mode 100644 index 00000000000000..f045141a1ea957 --- /dev/null +++ b/op_crates/webgpu/README.md @@ -0,0 +1,23 @@ +# deno_webgpu + +This op crate implements the WebGPU API as defined in +https://gpuweb.github.io/gpuweb/ in Deno. The implementation targets the spec +draft as of February 22, 2021. The spec is still very much in flux. This op +crate tries to stay up to date with the spec, but is constrained by the features +implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu). + +The spec is still very bare bones, and is still missing many details. As the +spec becomes more concrete, we will implement to follow the spec more closely. + +For testing this op crate will make use of the WebGPU conformance tests suite, +running through our WPT runner. This will be used to validate implementation +conformance. + +## Links + +Specification: https://gpuweb.github.io/gpuweb/ Design documents: +https://github.com/gpuweb/gpuweb/tree/main/design Conformance tests suite: +https://github.com/gpuweb/cts WebGPU examples for Deno: +https://github.com/crowlKats/webgpu-examples Guide for using wgpu in Rust: +https://sotrh.github.io/learn-wgpu/ wgpu-users matrix channel: +https://matrix.to/#/#wgpu-users:matrix.org From 0524f712b3b49a757be255e5707701f0f0710c9b Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 28 Feb 2021 02:03:09 +0100 Subject: [PATCH 140/144] add DENO_WEBGPU_TRACE env var & CI information --- op_crates/webgpu/README.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/op_crates/webgpu/README.md b/op_crates/webgpu/README.md index f045141a1ea957..9d313a65fe648c 100644 --- a/op_crates/webgpu/README.md +++ b/op_crates/webgpu/README.md @@ -9,15 +9,27 @@ implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu). The spec is still very bare bones, and is still missing many details. As the spec becomes more concrete, we will implement to follow the spec more closely. +In addition, setting the `DENO_WEBGPU_TRACE` environmental variable will +output a +[wgpu trace](https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications#tracing-infrastructure) +to the specified directory. + For testing this op crate will make use of the WebGPU conformance tests suite, running through our WPT runner. This will be used to validate implementation conformance. +GitHub CI doesn't run with GPUs, so testing relies on software like DX WARP & +Vulkan lavapipe. Currently only using DX WARP works, so tests are only run on +Windows. + ## Links -Specification: https://gpuweb.github.io/gpuweb/ Design documents: -https://github.com/gpuweb/gpuweb/tree/main/design Conformance tests suite: -https://github.com/gpuweb/cts WebGPU examples for Deno: -https://github.com/crowlKats/webgpu-examples Guide for using wgpu in Rust: -https://sotrh.github.io/learn-wgpu/ wgpu-users matrix channel: -https://matrix.to/#/#wgpu-users:matrix.org +Specification: https://gpuweb.github.io/gpuweb/ + +Design documents: https://github.com/gpuweb/gpuweb/tree/main/design + +Conformance tests suite: https://github.com/gpuweb/cts + +WebGPU examples for Deno: https://github.com/crowlKats/webgpu-examples + +wgpu-users matrix channel: https://matrix.to/#/#wgpu-users:matrix.org From 465a832fc39f1c91900eceb62ec30b9f9049f6cc Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Sun, 28 Feb 2021 02:23:59 +0100 Subject: [PATCH 141/144] add hello-triangle example as test --- cli/tests/unit/webgpu_test.ts | 110 +++++++++++++++++- ...er.wgsl => webgpu_computepass_shader.wgsl} | 0 cli/tests/webgpu_hellotriangle.out | Bin 0 -> 204800 bytes cli/tests/webgpu_hellotriangle_shader.wgsl | 19 +++ op_crates/webgpu/README.md | 4 +- 5 files changed, 130 insertions(+), 3 deletions(-) rename cli/tests/{shader.wgsl => webgpu_computepass_shader.wgsl} (100%) create mode 100644 cli/tests/webgpu_hellotriangle.out create mode 100644 cli/tests/webgpu_hellotriangle_shader.wgsl diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index 521986edffd5c0..d40851dfa4d70c 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -21,7 +21,9 @@ unitTest({ const device = await adapter.requestDevice(); assert(device); - const shaderCode = await Deno.readTextFile("cli/tests/shader.wgsl"); + const shaderCode = await Deno.readTextFile( + "cli/tests/webgpu_computepass_shader.wgsl", + ); const shaderModule = device.createShaderModule({ code: shaderCode, @@ -112,3 +114,109 @@ unitTest({ const resources = Object.keys(Deno.resources()); Deno.close(Number(resources[resources.length - 1])); }); + +// Skip this test on linux CI, because the vulkan emulator is not good enough +// yet, and skip on macOS because these do not have virtual GPUs. +unitTest({ + perms: { read: true, env: true }, + ignore: (Deno.build.os === "linux" || Deno.build.os === "darwin") && isCI, +}, async function webgpuHelloTriangle() { + const adapter = await navigator.gpu.requestAdapter(); + assert(adapter); + + const device = await adapter.requestDevice(); + assert(device); + + const shaderCode = await Deno.readTextFile( + "cli/tests/webgpu_hellotriangle_shader.wgsl", + ); + + const shaderModule = device.createShaderModule({ + code: shaderCode, + }); + + const pipelineLayout = device.createPipelineLayout({ + bindGroupLayouts: [], + }); + + const renderPipeline = device.createRenderPipeline({ + layout: pipelineLayout, + vertex: { + module: shaderModule, + entryPoint: "vs_main", + }, + fragment: { + module: shaderModule, + entryPoint: "fs_main", + targets: [ + { + format: "rgba8unorm-srgb", + }, + ], + }, + }); + + const dimensions = { + width: 200, + height: 200, + }; + const unpaddedBytesPerRow = dimensions.width * 4; + const align = 256; + const paddedBytesPerRowPadding = (align - unpaddedBytesPerRow % align) % + align; + const paddedBytesPerRow = unpaddedBytesPerRow + paddedBytesPerRowPadding; + + const outputBuffer = device.createBuffer({ + label: "Capture", + size: paddedBytesPerRow * dimensions.height, + usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, + }); + const texture = device.createTexture({ + label: "Capture", + size: dimensions, + format: "rgba8unorm-srgb", + usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + }); + + const encoder = device.createCommandEncoder(); + const renderPass = encoder.beginRenderPass({ + colorAttachments: [ + { + view: texture.createView(), + storeOp: "store", + loadValue: [0, 1, 0, 1], + }, + ], + }); + renderPass.setPipeline(renderPipeline); + renderPass.draw(3, 1); + renderPass.endPass(); + + encoder.copyTextureToBuffer( + { + texture, + }, + { + buffer: outputBuffer, + bytesPerRow: paddedBytesPerRow, + rowsPerImage: 0, + }, + dimensions, + ); + + device.queue.submit([encoder.finish()]); + + await outputBuffer.mapAsync(1); + const data = new Uint8Array(outputBuffer.getMappedRange()); + + assertEquals(data, await Deno.readFile("cli/tests/webgpu_hellotriangle.out")); + + outputBuffer.unmap(); + + device.destroy(); + + // TODO(lucacasonato): webgpu spec should add a explicit destroy method for + // adapters. + const resources = Object.keys(Deno.resources()); + Deno.close(Number(resources[resources.length - 1])); +}); diff --git a/cli/tests/shader.wgsl b/cli/tests/webgpu_computepass_shader.wgsl similarity index 100% rename from cli/tests/shader.wgsl rename to cli/tests/webgpu_computepass_shader.wgsl diff --git a/cli/tests/webgpu_hellotriangle.out b/cli/tests/webgpu_hellotriangle.out new file mode 100644 index 0000000000000000000000000000000000000000..91454dbfc665ef3d9240d080d8a22438bc585759 GIT binary patch literal 204800 zcmeI2i;`P82t?=qe>$6N!XzHs%)OF8&^npgQpWf}14qre^6}$?A1Xiv-c{g3{Leex zJf2>GA0Hn-e*MQ!p$drOU#QZ@&prGXoJRORp397>H1_Sx_)I?ILIvO-{u3%-+}n9! zG83{Q3w8YI@cs%I^Iy;XnUMkfGXv2T_{zQg9{stz|Ah*uUjS^8TPt9!zdJ8X=+^w@ z^MilpE3g9ZxVOjU`3kJw!RD%MR1N><_C7%QDEIcdjU)tAqk$Uu zKeO)vs*T~R{&jk}S;;K-_WDgEY_8rW)$o62-xsSkc2}L7Xjoj81}fnH zyq*UrUd6q=PXlrSs<=Tl{A=`aqY7ho^|^tDjaA&F7XHuc`C`SZxwrS*M8x9i6juTN zXZ3rrT4OcpEKbkjYHm;q|NVQoQ9%^<_P!g4*jUXCYT^H^elJvOj7Faus90E~;@QLh zIlW%2G@5&R|KbEKu4=Mc`0w4nP1zfpS!Xg8o2t4&CH$Y$>xD|QxVO*QK*qvq70w?1 z&*<|)mBwWDS(u`Q)lF6j|9yM6Df4XZ?emh!*i_wQmGFN?pBJe#7I&S=bS$b`;jH0b zzsCy|?&97)w=hWytDLA3{(JUqL)OON?lX~&4OLE72mks#UZik0_xAb8gep8CT)n@<=3PL$wpt!M}EY7pODls-20HEU049Y~f$G zw~Lfjx~0CQ*`H^+Z+huiM)N%Bpg2c_osvpqd4LBRRX+<-wV?V*s^Gs*uaYyZ&b{TAL`rh?lT^XKW?v^&8CzY>Bw8k`S};ra*X!v5 zMP0bJJPVSwpbH7A;J-(o60x}6EMBz7T54gBl%bW%|_?k(RWVkWCwEKB&;>gS{y zW2x&|jIPOUB&dP^`aMd_uq*eLcLFhq-AGUa|62W=P-6^rKNF~#sB*FF;9sYglS;aC zZ}}G^Y_coCYT&Z#n}BO6XQ#_VC}ke*@VY6Q`Yl6b*EtNH*}_w|9e?pT@oEEkfL2 z*MhQ#|62VB&c;|c^$emYxNCt~!++o24P<^Q_oh3Lq=9Y}$Ois<_H7_*W8n0&0CfZ1 z3(6Y)>+~Wxlhe63{XrxJcP}Vw`0v@bn_1iJbAJ5zRRezhQ~>^um<721&ArtD{^9?W z8L*k>4lRMxA{XfS-{Esx;g5u8*$6vgA53GOHYBSEs9q@HFK7WUQm!Z!(HGCG_``lZ7I`?=wcld8e_V-=4 z+2-U9aHj?S;s58qhdKS8a2b)DkUxsyU#`2SvplN*$U6Z3;UE7$_umA=zZCzY-pA{H z|3A=iI{^H{KmPyu{RjMuT?kTi`_qYsulXL+ud-NF4EHBF@c-#;+z;382Qk8Z0-k^o zd%#yO6NT+-Y+tR@F?WC%?oV=L2=^!Q>Rj`@Yxjg-ZK3EBFk%lJz&}i1WBP8LgeZSc zff(*ja^5SKiQJuQo`3DWfd40&`aK{+`Ri$f90w+M^nFNzg8{r=%}ahx_di=^c~QT=zAGUkp6lC;rJfMqxE`SeUV4+(bVtRqWq7} zGOruEGel^ArlB9v_cDG~Eb#~&k8wO&H~7DYU72S~(Ed1mqchCw=I)HgE{ObA2GpQL z;GggRC%*sx_s$d{{*j0v?8?0DquTbr{X38Rea_EE>L+&xlmRs;k@mztPTa`M@|tz` z#A7!Eehb2`%-ag_569~`o~fk(^?#`-18Ptrf0efX+sw@J+I4pa{0Ffb@wV-$|2=K+ zyN=%#wUoI7BABc6p7782|BJr=|M%X2|4NWMxd`z8@7(eCI(vY`9pIoN5rTjGKfwQg z-NO<;5|BG0ns*7mujBWxdeQz4aL|zm!9V^V-+kh9<|v49CRc?@Q?o|`+ut)Kmu|{ zL<9cs_zKVMvnRCJ0UUHBLhz6OZ}9&%JAee_j)>y?rA|1Z4*NI>q0D9HbekMP>Qdqc?`z(GeM1poMd0sk+%14uybh$zNC{@vHVSM;vj z4&b085rTjGzli^r+yNvYcSIE8e}#YW9{u-+QagZyjzkFl@&7{pUv3AGfZP#LgnxXy zzi+SXVVNDkK}RA4|M-6~|1Y%zNI>q0D8T$W^g8pA-2atf= z5wV$n{94DaBYL@g2XN4l2*E%8U)29g>;MvwJ0dpnAK@3gr`|rXbq8?JkqE&*{$JSt zx97&9f=V9Q?0MJ@;GiQBf`9zKx&Mdm z01}WpA_Dl|=>vTBxqC;*4&b085rTjGU%>yvb^r;;9TAK9$A8cD-wM57z5_VuNQB@Y z{}=K9kR3n*a!15M{wv)7p0Y!#jY3jzkFl@qcmupV|Q=Aa_Iz@L&0!CpY$xcQY`w132hNgy0|l zKfwQocK`{<9T7MAe|NX?IKJCq25#>F4muJc_{aYb@&BP6Kmu|{#0~yC-0$Sb9`fA` z+}Z&gbRIs=z>00$k35d7o+2m1fz9Y6wdN5nV$U%g9t9=_Xg2EN?^9CRc?@Q?o= z>i?H^013z)5f1+y?{jiy54k%7?hfFfBN2js{QqG8|8@tEfZP%BhX1>FD9^`tJI}z| z9l$|HA_V{V|Ka}c?f?>yJ0f22-}xRVclMCc8F;w^IOs@(;2;0T|Nox>_{Td&y@S_j z%+AvtAYt;3h%f%n9Ba%meH`oK$^0`jV>3hDwCeV72RPO#5&FmfnPaUvrk`W|JduB9 zWo%Zcn`YfU?*IvtcSQX0f96ZV<{|L*|DIwe9s{hv9e2F$?o W44l9}eShvdHK8Up0}>wZi1-hIFIl<( literal 0 HcmV?d00001 diff --git a/cli/tests/webgpu_hellotriangle_shader.wgsl b/cli/tests/webgpu_hellotriangle_shader.wgsl new file mode 100644 index 00000000000000..71934415be220e --- /dev/null +++ b/cli/tests/webgpu_hellotriangle_shader.wgsl @@ -0,0 +1,19 @@ +[[builtin(vertex_index)]] +var in_vertex_index: u32; +[[builtin(position)]] +var out_pos: vec4; + +[[stage(vertex)]] +fn vs_main() { + var x: f32 = f32(i32(in_vertex_index) - 1); + var y: f32 = f32(i32(in_vertex_index & 1) * 2 - 1); + out_pos = vec4(x, y, 0.0, 1.0); +} + +[[location(0)]] +var out_color: vec4; + +[[stage(fragment)]] +fn fs_main() { + out_color = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/op_crates/webgpu/README.md b/op_crates/webgpu/README.md index 9d313a65fe648c..2f915dcbbee656 100644 --- a/op_crates/webgpu/README.md +++ b/op_crates/webgpu/README.md @@ -9,8 +9,8 @@ implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu). The spec is still very bare bones, and is still missing many details. As the spec becomes more concrete, we will implement to follow the spec more closely. -In addition, setting the `DENO_WEBGPU_TRACE` environmental variable will -output a +In addition, setting the `DENO_WEBGPU_TRACE` environmental variable will output +a [wgpu trace](https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications#tracing-infrastructure) to the specified directory. From 5d758dbe2a1ee7d8540431329571d12d1ea5eaa5 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 1 Mar 2021 01:23:43 +0100 Subject: [PATCH 142/144] trigger ci From be27fae8272715c0610dfd4b671c4431bb88f03e Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 1 Mar 2021 01:33:26 +0100 Subject: [PATCH 143/144] lint --- cli/tests/unit/webgpu_test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index d40851dfa4d70c..628a3c8db92667 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -1,3 +1,6 @@ +// TODO(lucacasonato): remove when GPUBufferUsage and friends are added to dlint +// deno-lint-ignore-file no-undef + import { assert, assertEquals, unitTest } from "./test_util.ts"; let isCI: boolean; From 115585bf0aefe6f731dbec4c40b8075f1513a311 Mon Sep 17 00:00:00 2001 From: crowlkats <13135287+crowlKats@users.noreply.github.com> Date: Mon, 1 Mar 2021 02:09:44 +0100 Subject: [PATCH 144/144] change interfaces to classes --- op_crates/webgpu/lib.deno_webgpu.d.ts | 240 ++++++++++++++++++++++---- 1 file changed, 202 insertions(+), 38 deletions(-) diff --git a/op_crates/webgpu/lib.deno_webgpu.d.ts b/op_crates/webgpu/lib.deno_webgpu.d.ts index 914ac867452e41..cd2680b3d7e790 100644 --- a/op_crates/webgpu/lib.deno_webgpu.d.ts +++ b/op_crates/webgpu/lib.deno_webgpu.d.ts @@ -7,7 +7,7 @@ // 8cc98b6f10b7f354473a08c3773bb1de839845b9 -declare interface GPUObjectBase { +interface GPUObjectBase { label: string | null; } @@ -15,7 +15,7 @@ declare interface GPUObjectDescriptorBase { label?: string; } -declare interface GPUAdapterLimits { +declare class GPUAdapterLimits { maxTextureDimension1D?: number; maxTextureDimension2D?: number; maxTextureDimension3D?: number; @@ -35,9 +35,27 @@ declare interface GPUAdapterLimits { maxVertexBufferArrayStride?: number; } -declare type GPUAdapterFeatures = GPUFeatureName[]; +declare class GPUAdapterFeatures { + forEach( + callbackfn: ( + value: GPUFeatureName, + value2: GPUFeatureName, + set: Set, + ) => void, + thisArg?: any, + ): void; + has(value: GPUFeatureName): boolean; + size: number; + [ + Symbol + .iterator + ](): IterableIterator; + entries(): IterableIterator<[GPUFeatureName, GPUFeatureName]>; + keys(): IterableIterator; + values(): IterableIterator; +} -declare interface GPU { +declare class GPU { requestAdapter( options?: GPURequestAdapterOptions, ): Promise; @@ -49,7 +67,7 @@ declare interface GPURequestAdapterOptions { declare type GPUPowerPreference = "low-power" | "high-performance"; -declare interface GPUAdapter { +declare class GPUAdapter { readonly name: string; readonly features: GPUAdapterFeatures; readonly limits: GPUAdapterLimits; @@ -86,7 +104,9 @@ declare type GPUFeatureName = | "shader-float64" | "vertex-attribute-64bit"; -declare interface GPUDevice extends EventTarget, GPUObjectBase { +declare class GPUDevice extends EventTarget implements GPUObjectBase { + label: string | null; + readonly lost: Promise; pushErrorScope(filter: GPUErrorFilter): undefined; popErrorScope(): Promise; @@ -137,7 +157,9 @@ declare interface GPUDevice extends EventTarget, GPUObjectBase { createQuerySet(descriptor: GPUQuerySetDescriptor): GPUQuerySet; } -declare interface GPUBuffer extends GPUObjectBase { +declare class GPUBuffer implements GPUObjectBase { + label: string | null; + mapAsync( mode: GPUMapModeFlags, offset?: number, @@ -175,7 +197,9 @@ declare class GPUMapMode { static WRITE: 0x0002; } -declare interface GPUTexture extends GPUObjectBase { +declare class GPUTexture implements GPUObjectBase { + label: string | null; + createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView; destroy(): undefined; } @@ -200,7 +224,9 @@ declare class GPUTextureUsage { static RENDER_ATTACHMENT: 0x10; } -declare interface GPUTextureView extends GPUObjectBase {} +declare class GPUTextureView implements GPUObjectBase { + label: string | null; +} declare interface GPUTextureViewDescriptor extends GPUObjectDescriptorBase { format?: GPUTextureFormat; @@ -281,7 +307,9 @@ declare type GPUTextureFormat = | "depth24unorm-stencil8" | "depth32float-stencil8"; -declare interface GPUSampler extends GPUObjectBase {} +declare class GPUSampler implements GPUObjectBase { + label: string | null; +} declare interface GPUSamplerDescriptor extends GPUObjectDescriptorBase { addressModeU?: GPUAddressMode; @@ -310,7 +338,9 @@ declare type GPUCompareFunction = | "greater-equal" | "always"; -declare interface GPUBindGroupLayout extends GPUObjectBase {} +declare class GPUBindGroupLayout implements GPUObjectBase { + label: string | null; +} declare interface GPUBindGroupLayoutDescriptor extends GPUObjectDescriptorBase { entries: GPUBindGroupLayoutEntry[]; @@ -377,7 +407,9 @@ declare interface GPUStorageTextureBindingLayout { viewDimension?: GPUTextureViewDimension; } -declare interface GPUBindGroup extends GPUObjectBase {} +declare class GPUBindGroup implements GPUObjectBase { + label: string | null; +} declare interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase { layout: GPUBindGroupLayout; @@ -400,7 +432,9 @@ declare interface GPUBufferBinding { size?: number; } -declare interface GPUPipelineLayout extends GPUObjectBase {} +declare class GPUPipelineLayout implements GPUObjectBase { + label: string | null; +} declare interface GPUPipelineLayoutDescriptor extends GPUObjectDescriptorBase { bindGroupLayouts: GPUBindGroupLayout[]; @@ -419,7 +453,9 @@ declare interface GPUCompilationInfo { readonly messages: ReadonlyArray; } -declare interface GPUShaderModule extends GPUObjectBase { +declare class GPUShaderModule implements GPUObjectBase { + label: string | null; + compilationInfo(): Promise; } @@ -441,14 +477,22 @@ declare interface GPUProgrammableStage { entryPoint: string; } -declare interface GPUComputePipeline extends GPUObjectBase, GPUPipelineBase {} +declare class GPUComputePipeline implements GPUObjectBase, GPUPipelineBase { + label: string | null; + + getBindGroupLayout(index: number): GPUBindGroupLayout; +} declare interface GPUComputePipelineDescriptor extends GPUPipelineDescriptorBase { compute: GPUProgrammableStage; } -declare interface GPURenderPipeline extends GPUObjectBase, GPUPipelineBase {} +declare class GPURenderPipeline implements GPUObjectBase, GPUPipelineBase { + label: string | null; + + getBindGroupLayout(index: number): GPUBindGroupLayout; +} declare interface GPURenderPipelineDescriptor extends GPUPipelineDescriptorBase { @@ -500,15 +544,13 @@ declare interface GPUBlendState { } declare type GPUColorWriteFlags = number; -/* -declare interface GPUColorWrite { - const GPUFlagsConstant RED = 0x1; - const GPUFlagsConstant GREEN = 0x2; - const GPUFlagsConstant BLUE = 0x4; - const GPUFlagsConstant ALPHA = 0x8; - const GPUFlagsConstant ALL = 0xF; -}; -*/ +declare class GPUColorWrite { + static RED: 0x1; + static GREEN: 0x2; + static BLUE: 0x4; + static ALPHA: 0x8; + static ALL: 0xF; +} declare interface GPUBlendComponent { srcFactor: GPUBlendFactor; @@ -627,13 +669,17 @@ declare interface GPUVertexAttribute { shaderLocation: number; } -declare interface GPUCommandBuffer extends GPUObjectBase { +declare class GPUCommandBuffer implements GPUObjectBase { + label: string | null; + readonly executionTime: Promise; } declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {} -declare interface GPUCommandEncoder extends GPUObjectBase { +declare class GPUCommandEncoder implements GPUObjectBase { + label: string | null; + beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder; beginComputePass( descriptor?: GPUComputePassDescriptor, @@ -703,7 +749,7 @@ declare interface GPUImageCopyTexture { aspect?: GPUTextureAspect; } -declare interface GPUProgrammablePassEncoder { +interface GPUProgrammablePassEncoder { setBindGroup( index: number, bindGroup: GPUBindGroup, @@ -723,8 +769,24 @@ declare interface GPUProgrammablePassEncoder { insertDebugMarker(markerLabel: string): undefined; } -declare interface GPUComputePassEncoder - extends GPUObjectBase, GPUProgrammablePassEncoder { +declare class GPUComputePassEncoder + implements GPUObjectBase, GPUProgrammablePassEncoder { + label: string | null; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsets?: number[], + ): undefined; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsetsData: Uint32Array, + dynamicOffsetsDataStart: number, + dynamicOffsetsDataLength: number, + ): undefined; + pushDebugGroup(groupLabel: string): undefined; + popDebugGroup(): undefined; + insertDebugMarker(markerLabel: string): undefined; setPipeline(pipeline: GPUComputePipeline): undefined; dispatch(x: number, y?: number, z?: number): undefined; dispatchIndirect( @@ -745,7 +807,7 @@ declare interface GPUComputePassEncoder declare interface GPUComputePassDescriptor extends GPUObjectDescriptorBase {} -declare interface GPURenderEncoderBase { +interface GPURenderEncoderBase { setPipeline(pipeline: GPURenderPipeline): undefined; setIndexBuffer( @@ -782,8 +844,56 @@ declare interface GPURenderEncoderBase { ): undefined; } -declare interface GPURenderPassEncoder - extends GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { +declare class GPURenderPassEncoder + implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { + label: string | null; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsets?: number[], + ): undefined; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsetsData: Uint32Array, + dynamicOffsetsDataStart: number, + dynamicOffsetsDataLength: number, + ): undefined; + pushDebugGroup(groupLabel: string): undefined; + popDebugGroup(): undefined; + insertDebugMarker(markerLabel: string): undefined; + setPipeline(pipeline: GPURenderPipeline): undefined; + setIndexBuffer( + buffer: GPUBuffer, + indexFormat: GPUIndexFormat, + offset?: number, + size?: number, + ): undefined; + setVertexBuffer( + slot: number, + buffer: GPUBuffer, + offset?: number, + size?: number, + ): undefined; + draw( + vertexCount: number, + instanceCount?: number, + firstVertex?: number, + firstInstance?: number, + ): undefined; + drawIndexed( + indexCount: number, + instanceCount?: number, + firstIndex?: number, + baseVertex?: number, + firstInstance?: number, + ): undefined; + drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; + drawIndexedIndirect( + indirectBuffer: GPUBuffer, + indirectOffset: number, + ): undefined; + setViewport( x: number, y: number, @@ -848,12 +958,62 @@ declare type GPULoadOp = "load"; declare type GPUStoreOp = "store" | "clear"; -declare interface GPURenderBundle extends GPUObjectBase {} +declare class GPURenderBundle implements GPUObjectBase { + label: string | null; +} declare interface GPURenderBundleDescriptor extends GPUObjectDescriptorBase {} -declare interface GPURenderBundleEncoder - extends GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { +declare class GPURenderBundleEncoder + implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { + label: string | null; + draw( + vertexCount: number, + instanceCount?: number, + firstVertex?: number, + firstInstance?: number, + ): undefined; + drawIndexed( + indexCount: number, + instanceCount?: number, + firstIndex?: number, + baseVertex?: number, + firstInstance?: number, + ): undefined; + drawIndexedIndirect( + indirectBuffer: GPUBuffer, + indirectOffset: number, + ): undefined; + drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; + insertDebugMarker(markerLabel: string): undefined; + popDebugGroup(): undefined; + pushDebugGroup(groupLabel: string): undefined; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsets?: number[], + ): undefined; + setBindGroup( + index: number, + bindGroup: GPUBindGroup, + dynamicOffsetsData: Uint32Array, + dynamicOffsetsDataStart: number, + dynamicOffsetsDataLength: number, + ): undefined; + setIndexBuffer( + buffer: GPUBuffer, + indexFormat: GPUIndexFormat, + offset?: number, + size?: number, + ): undefined; + setPipeline(pipeline: GPURenderPipeline): undefined; + setVertexBuffer( + slot: number, + buffer: GPUBuffer, + offset?: number, + size?: number, + ): undefined; + finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle; } @@ -864,7 +1024,9 @@ declare interface GPURenderBundleEncoderDescriptor sampleCount?: number; } -declare interface GPUQueue extends GPUObjectBase { +declare class GPUQueue implements GPUObjectBase { + label: string | null; + submit(commandBuffers: GPUCommandBuffer[]): undefined; onSubmittedWorkDone(): Promise; @@ -885,7 +1047,9 @@ declare interface GPUQueue extends GPUObjectBase { ): undefined; } -declare interface GPUQuerySet extends GPUObjectBase { +declare class GPUQuerySet implements GPUObjectBase { + label: string | null; + destroy(): undefined; }