diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index 35ac5b60aa..d6eb8903f5 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -75,7 +75,7 @@ jobs: - name: disable debug shell: bash run: | - mkdir wgpu/.cargo + mkdir -p wgpu/.cargo echo """[profile.dev] debug = 1" > wgpu/.cargo/config.toml diff --git a/Cargo.lock b/Cargo.lock index 3c67d5ccbb..07ebdffdf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,9 +159,9 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -184,7 +184,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide 0.7.1", + "miniz_oxide", "object", "rustc-demangle", ] @@ -625,26 +625,50 @@ dependencies = [ "uuid", ] +[[package]] +name = "deno-proc-macro-rules" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c65c2ffdafc1564565200967edc4851c7b55422d3913466688907efd05ea26f" +dependencies = [ + "deno-proc-macro-rules-macros", + "proc-macro2", + "syn 2.0.28", +] + +[[package]] +name = "deno-proc-macro-rules-macros" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3047b312b7451e3190865713a4dd6e1f821aed614ada219766ebc3024a690435" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "deno_console" -version = "0.106.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e7857cc8b133aed57e5f1dcfac6c0db308e70540727dfe0637af5281299758" +checksum = "106305c29d87aaa8030a472486074ba780dccc75c909a4f55bbac4376d8425a3" dependencies = [ "deno_core", ] [[package]] name = "deno_core" -version = "0.188.0" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83573c39d4045b6c2e056a2ad87e49c43e57b64b54ee4381894c030390fa1f76" +checksum = "be0af76effe9a766f7c9a253171ab10b9adfaf4b10c6eb0b9f005f9dd0ba2948" dependencies = [ "anyhow", "bytes", "deno_ops", + "deno_unsync", "futures", - "indexmap 1.9.3", + "indexmap 2.0.0", "libc", "log", "once_cell", @@ -662,10 +686,11 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.66.0" +version = "0.90.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0446caff6cdb14fbf6c5e85fc042e3102aa6c618fa19a2ef47b67fc2657c0e8e" +checksum = "568aba570695e05f08c2181bcd6cd3579684af42f489b9ae42712348044b4af7" dependencies = [ + "deno-proc-macro-rules", "lazy-regex", "once_cell", "pmutil", @@ -673,32 +698,45 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 1.0.109", + "strum", + "strum_macros", + "syn 2.0.28", + "thiserror", +] + +[[package]] +name = "deno_unsync" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0720e562455d6374a5292baec3fc895ed8bfed0937428e3245e50979924e5b15" +dependencies = [ + "tokio", ] [[package]] name = "deno_url" -version = "0.106.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae0fa17e1fc70d8bb1f59d64a952b790afd774d3499524d7a760812eec07486" +checksum = "df3885daa41f0236c622801aa7e7b6efdff1e253fbaa941eb5087ec3e7339114" dependencies = [ "deno_core", "serde", - "serde_repr", "urlpattern", ] [[package]] name = "deno_web" -version = "0.137.0" +version = "0.150.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a10df5503ffec0b1a59541e2587f84873676d714e5d935ecc4d2792685827198" +checksum = "227c8b22e230c85a7cbc5632a6ce81959d277deabd2dfc015dda332c33b1a20d" dependencies = [ "async-trait", "base64-simd", + "bytes", "deno_core", "encoding_rs", "flate2", + "futures", "serde", "tokio", "uuid", @@ -714,14 +752,15 @@ dependencies = [ "serde", "tokio", "wgpu-core", + "wgpu-hal", "wgpu-types", ] [[package]] name = "deno_webidl" -version = "0.106.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980a92f4619ace414abd464ad417ae362c7be05020009dfd4c4f1794ed21c71f" +checksum = "26983f124cb3d641d940eb2636a103f4907f02b4cd3b52e3acd8365f20a33c08" dependencies = [ "deno_core", ] @@ -782,9 +821,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -877,12 +916,13 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", - "miniz_oxide 0.5.4", + "libz-ng-sys", + "miniz_oxide", ] [[package]] @@ -1290,6 +1330,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.2" @@ -1437,9 +1483,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "lazy-regex" -version = "2.5.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63c423c68ea6814b7da9e88ce585f793c87ddd9e78f646970891769c8235d4" +checksum = "e723bd417b2df60a0f6a2b6825f297ea04b245d4ba52b5a22cb679bdf58b05fa" dependencies = [ "lazy-regex-proc_macros", "once_cell", @@ -1448,14 +1494,14 @@ dependencies = [ [[package]] name = "lazy-regex-proc_macros" -version = "2.4.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edfc11b8f56ce85e207e62ea21557cfa09bb24a8f6b04ae181b086ff8611c22" +checksum = "0f0a1d9139f0ee2e862e08a9c5d0ba0470f2aa21cd1e1aa1b1562f83116c725f" dependencies = [ "proc-macro2", "quote", "regex", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] @@ -1490,6 +1536,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libz-ng-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dd9f43e75536a46ee0f92b758f6b63846e594e86638c61a9251338a65baea63" +dependencies = [ + "cmake", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.3" @@ -1568,15 +1624,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2056,13 +2103,13 @@ dependencies = [ [[package]] name = "pmutil" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004" +checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] @@ -2075,7 +2122,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.7.1", + "miniz_oxide", ] [[package]] @@ -2324,6 +2371,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.15" @@ -2438,22 +2491,11 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_repr" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "serde_v8" -version = "0.99.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcb15f793aba70da4d29b2015c9b70943bd7f6970cab7963fcf83c19bbab1c9" +checksum = "cc3e1c4d2b20f6983e86077c66b25b8d768f2e102e09659af2af034ac47ae709" dependencies = [ "bytes", "derive_more", @@ -2566,9 +2608,9 @@ dependencies = [ [[package]] name = "sourcemap" -version = "6.3.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8df03d85f2767c45e61b4453eb6144153c80399e4fdd6407a6d16cb87cc0347" +checksum = "dbecc42a2b6131acc3bf9a25c9fe4161dba438eb52131bba83c5d781b5b70be3" dependencies = [ "data-encoding", "debugid", @@ -2608,6 +2650,28 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.28", +] + [[package]] name = "syn" version = "1.0.109" @@ -2894,9 +2958,9 @@ dependencies = [ [[package]] name = "v8" -version = "0.72.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5c1d09f66ab7f69e36211c5488d47f683fef6b65b83a627cfd75ed9cef254e6" +checksum = "9d4e8ae7ef8b4e852e728e343cb6bb471a0424dfefa22585ea0c14a61252d73f" dependencies = [ "bitflags 1.3.2", "fslock", diff --git a/Cargo.toml b/Cargo.toml index 1f15a39be3..96f3f1fa67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -129,11 +129,11 @@ wasm-bindgen-test = "0.3" web-sys = "0.3.64" # deno dependencies -deno_console = "0.106.0" -deno_core = "0.188.0" -deno_url = "0.106.0" -deno_web = "0.137.0" -deno_webidl = "0.106.0" +deno_console = "0.119.0" +deno_core = "0.214.0" +deno_url = "0.119.0" +deno_web = "0.150.0" +deno_webidl = "0.119.0" deno_webgpu = { path = "./deno_webgpu" } tokio = "1.32.0" termcolor = "1.3.0" diff --git a/cts_runner/examples/hello-compute.js b/cts_runner/examples/hello-compute.js index 5bbfa0719e..9c4023ed5e 100644 --- a/cts_runner/examples/hello-compute.js +++ b/cts_runner/examples/hello-compute.js @@ -49,13 +49,14 @@ const size = new Uint32Array(numbers).byteLength; const stagingBuffer = device.createBuffer({ size: size, - usage: 1 | 8, + usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, }); const storageBuffer = device.createBuffer({ label: "Storage Buffer", size: size, - usage: 0x80 | 8 | 4, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | + GPUBufferUsage.COPY_SRC, mappedAtCreation: true, }); diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index b4b0529662..4e6b1d36c1 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -a44186d9fa1d5babdb4a198e8ef04cf0d7035ebb \ No newline at end of file +7ea73ba6f44c9f6fedfffc06f14c73ea9f2eaa11 diff --git a/cts_runner/src/bootstrap.js b/cts_runner/src/bootstrap.js index 798a769262..640075e7ee 100644 --- a/cts_runner/src/bootstrap.js +++ b/cts_runner/src/bootstrap.js @@ -42,6 +42,64 @@ import "ext:deno_web/14_compression.js"; let globalThis_; +const { BadResource, Interrupted } = core; + +class NotFound extends Error { + constructor(msg) { + super(msg); + this.name = "NotFound"; + } +} + +class BrokenPipe extends Error { + constructor(msg) { + super(msg); + this.name = "BrokenPipe"; + } +} + +class AlreadyExists extends Error { + constructor(msg) { + super(msg); + this.name = "AlreadyExists"; + } +} + +class InvalidData extends Error { + constructor(msg) { + super(msg); + this.name = "InvalidData"; + } +} + +class TimedOut extends Error { + constructor(msg) { + super(msg); + this.name = "TimedOut"; + } +} + +class WriteZero extends Error { + constructor(msg) { + super(msg); + this.name = "WriteZero"; + } +} + +class UnexpectedEof extends Error { + constructor(msg) { + super(msg); + this.name = "UnexpectedEof"; + } +} + +class NotSupported extends Error { + constructor(msg) { + super(msg); + this.name = "NotSupported"; + } +} + const util = { writable(value) { return { @@ -88,7 +146,7 @@ const NavigatorPrototype = Navigator.prototype; const navigator = webidl.createBranded(Navigator); -ObjectDefineProperties(Navigator.prototype, { +ObjectDefineProperties(NavigatorPrototype, { gpu: { configurable: true, enumerable: true, @@ -108,6 +166,7 @@ const windowOrWorkerGlobalScope = { EventTarget: util.nonEnumerable(event.EventTarget), Navigator: util.nonEnumerable(Navigator), navigator: util.getterOnly(() => navigator), + MessageEvent: util.nonEnumerable(event.MessageEvent), Performance: util.nonEnumerable(performance.Performance), PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry), PerformanceMark: util.nonEnumerable(performance.PerformanceMark), @@ -127,15 +186,17 @@ const windowOrWorkerGlobalScope = { GPU: util.nonEnumerable(webgpu.GPU), GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), - GPUAdapterLimits: util.nonEnumerable(webgpu.GPUAdapterLimits), + GPUAdapterInfo: util.nonEnumerable(webgpu.GPUAdapterInfo), + GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits), GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures), + GPUDeviceLostInfo: util.nonEnumerable(webgpu.GPUDeviceLostInfo), 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), + GPUTexture: util.nonEnumerable(webgpu.GPUTexture), GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView), GPUSampler: util.nonEnumerable(webgpu.GPUSampler), GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout), @@ -153,8 +214,9 @@ const windowOrWorkerGlobalScope = { GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder), GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), - GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), + GPUError: util.nonEnumerable(webgpu.GPUError), GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), + GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), }; windowOrWorkerGlobalScope.console.enumerable = false; @@ -167,27 +229,54 @@ const mainRuntimeGlobalProperties = { const denoNs = { exit(code) { - core.opSync("op_exit", code); + core.ops.op_exit(code); }, readFileSync(path) { - return core.opSync("op_read_file_sync", pathFromURL(path)); + return core.ops.op_read_file_sync(pathFromURL(path)); }, readTextFileSync(path) { - const buf = core.opSync("op_read_file_sync", pathFromURL(path)); + const buf = core.ops.op_read_file_sync(pathFromURL(path)); const decoder = new TextDecoder(); return decoder.decode(buf); }, writeFileSync(path, buf) { - return core.opSync("op_write_file_sync", pathFromURL(path), buf); + return core.ops.op_write_file_sync(pathFromURL(path), buf); }, }; +core.registerErrorClass("NotFound", NotFound); +core.registerErrorClass("AlreadyExists", AlreadyExists); +core.registerErrorClass("InvalidData", InvalidData); +core.registerErrorClass("TimedOut", TimedOut); +core.registerErrorClass("Interrupted", Interrupted); +core.registerErrorClass("WriteZero", WriteZero); +core.registerErrorClass("UnexpectedEof", UnexpectedEof); +core.registerErrorClass("BadResource", BadResource); +core.registerErrorClass("NotSupported", NotSupported); core.registerErrorBuilder( "DOMExceptionOperationError", function DOMExceptionOperationError(msg) { return new DOMException(msg, "OperationError"); }, ); +core.registerErrorBuilder( + "DOMExceptionAbortError", + function DOMExceptionAbortError(msg) { + return new domException.DOMException(msg, "AbortError"); + }, +); +core.registerErrorBuilder( + "DOMExceptionInvalidCharacterError", + function DOMExceptionInvalidCharacterError(msg) { + return new domException.DOMException(msg, "InvalidCharacterError"); + }, +); +core.registerErrorBuilder( + "DOMExceptionDataError", + function DOMExceptionDataError(msg) { + return new domException.DOMException(msg, "DataError"); + }, +); let hasBootstrapped = false; diff --git a/cts_runner/src/main.rs b/cts_runner/src/main.rs index c5a70aabc1..37185e9cc4 100644 --- a/cts_runner/src/main.rs +++ b/cts_runner/src/main.rs @@ -1,5 +1,6 @@ #[cfg(not(target_arch = "wasm32"))] mod native { + use std::sync::Arc; use std::{ env, fmt, io::{Read, Write}, @@ -8,13 +9,12 @@ mod native { use deno_core::anyhow::anyhow; use deno_core::error::AnyError; - use deno_core::op; + use deno_core::op2; use deno_core::resolve_url_or_path; use deno_core::serde_json::json; use deno_core::v8; use deno_core::JsRuntime; use deno_core::RuntimeOptions; - use deno_core::ZeroCopyBuf; use deno_web::BlobStore; use termcolor::Ansi; use termcolor::Color::Red; @@ -36,7 +36,10 @@ mod native { deno_webidl::deno_webidl::init_ops_and_esm(), deno_console::deno_console::init_ops_and_esm(), deno_url::deno_url::init_ops_and_esm(), - deno_web::deno_web::init_ops_and_esm::(BlobStore::default(), None), + deno_web::deno_web::init_ops_and_esm::( + Arc::new(BlobStore::default()), + None, + ), deno_webgpu::deno_webgpu::init_ops_and_esm(true), cts_runner::init_ops_and_esm(), ], @@ -47,7 +50,7 @@ mod native { let cfg = json!({"args": args, "cwd": env::current_dir().unwrap().to_string_lossy() }); { - let context = isolate.global_context(); + let context = isolate.main_context(); let scope = &mut isolate.handle_scope(); let context_local = v8::Local::new(scope, context); let global_obj = context_local.global(scope); @@ -56,7 +59,6 @@ mod native { let bootstrap_fn = v8::Local::::try_from(bootstrap_fn).unwrap(); let options_v8 = deno_core::serde_v8::to_v8(scope, cfg).unwrap(); - let bootstrap_fn = v8::Local::new(scope, bootstrap_fn); let undefined = v8::undefined(scope); bootstrap_fn .call(scope, undefined.into(), &[options_v8]) @@ -86,28 +88,29 @@ mod native { deps = [deno_webidl, deno_web], ops = [op_exit, op_read_file_sync, op_write_file_sync], esm_entry_point = "ext:cts_runner/bootstrap.js", - esm = ["bootstrap.js"], + esm = ["src/bootstrap.js"], ); - #[op] + #[op2(fast)] fn op_exit(code: i32) -> Result<(), AnyError> { std::process::exit(code) } - #[op] - fn op_read_file_sync(path: String) -> Result { - let path = std::path::Path::new(&path); + #[op2] + #[buffer] + fn op_read_file_sync(#[string] path: &str) -> Result, AnyError> { + let path = std::path::Path::new(path); let mut file = std::fs::File::open(path)?; let mut buf = Vec::new(); file.read_to_end(&mut buf)?; - Ok(ZeroCopyBuf::from(buf)) + Ok(buf) } - #[op] - fn op_write_file_sync(path: String, buf: ZeroCopyBuf) -> Result<(), AnyError> { - let path = std::path::Path::new(&path); + #[op2(fast)] + fn op_write_file_sync(#[string] path: &str, #[buffer] buf: &[u8]) -> Result<(), AnyError> { + let path = std::path::Path::new(path); let mut file = std::fs::File::create(path)?; - file.write_all(&buf)?; + file.write_all(buf)?; Ok(()) } diff --git a/cts_runner/test.lst b/cts_runner/test.lst index f5ef47ece4..2a410aa5a0 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -1,11 +1,10 @@ unittests:* webgpu:api,operation,command_buffer,basic:* webgpu:api,operation,compute,basic:* -//FAIL: webgpu:api,validation,queue,copyToTexture,ImageBitmap:destination_texture,format:format="stencil8";*' webgpu:api,operation,rendering,basic:clear:* webgpu:api,operation,rendering,basic:fullscreen_quad:* -//HANG: webgpu:api,operation,rendering,basic:large_draw:* +//FAIL: webgpu:api,operation,rendering,basic:large_draw:* webgpu:api,operation,rendering,blending:* webgpu:api,operation,rendering,blending:GPUBlendComponent:* -//FAIL: webgpu:api,operation,rendering,depth:* -//FAIL: webgpu:api,operation,rendering,draw:* +webgpu:api,operation,rendering,depth:* +webgpu:api,operation,rendering,draw:* diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index 35d5db6b90..5d38ede30f 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -140,11 +140,15 @@ function normalizeGPUExtent3D(data) { if (ArrayIsArray(data)) { return { width: data[0], - height: data[1], - depthOrArrayLayers: data[2], + height: data[1] ?? 1, + depthOrArrayLayers: data[2] ?? 1, }; } else { - return data; + return { + width: data.width, + height: data.height ?? 1, + depthOrArrayLayers: data.depthOrArrayLayers ?? 1, + }; } } @@ -1019,13 +1023,13 @@ class GPUDevice extends EventTarget { for (let i = 0; i < descriptor.entries.length; ++i) { const entry = descriptor.entries[i]; - let i = 0; - if (entry.buffer) i++; - if (entry.sampler) i++; - if (entry.texture) i++; - if (entry.storageTexture) i++; + let j = 0; + if (entry.buffer) j++; + if (entry.sampler) j++; + if (entry.texture) j++; + if (entry.storageTexture) j++; - if (i !== 1) { + if (j !== 1) { throw new Error(); // TODO(@crowlKats): correct error } } @@ -2839,11 +2843,35 @@ class GPUCommandEncoder { }, ); + const occlusionQuerySet = assertResource( + descriptor.occlusionQuerySet, + { + prefix, + context: "occlusionQuerySet", + }, + ); + + let timestampWrites = null; + if (descriptor.timestampWrites) { + const querySet = assertResource(descriptor.querySet, { + prefix, + context: "querySet", + }); + + timestampWrites = { + querySet, + beginningOfPassWriteIndex: descriptor.beginningOfPassWriteIndex, + endOfPassWriteIndex: descriptor.endOfPassWriteIndex, + } + } + const { rid } = ops.op_webgpu_command_encoder_begin_render_pass( commandEncoderRid, descriptor.label, colorAttachments, depthStencilAttachment, + occlusionQuerySet, + timestampWrites, ); const renderPassEncoder = createGPURenderPassEncoder( @@ -2873,9 +2901,24 @@ class GPUCommandEncoder { context: "this", }); + let timestampWrites = null; + if (descriptor.timestampWrites) { + const querySet = assertResource(descriptor.querySet, { + prefix, + context: "querySet", + }); + + timestampWrites = { + querySet, + beginningOfPassWriteIndex: descriptor.beginningOfPassWriteIndex, + endOfPassWriteIndex: descriptor.endOfPassWriteIndex, + } + } + const { rid } = ops.op_webgpu_command_encoder_begin_compute_pass( commandEncoderRid, descriptor.label, + timestampWrites, ); const computePassEncoder = createGPUComputePassEncoder( @@ -3591,23 +3634,18 @@ class GPURenderPassEncoder { } /** - * @param {GPUQuerySet} querySet * @param {number} queryIndex */ - beginPipelineStatisticsQuery(querySet, queryIndex) { + beginOcclusionQuery(queryIndex) { webidl.assertBranded(this, GPURenderPassEncoderPrototype); const prefix = - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); + "Failed to execute 'beginOcclusionQuery' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); queryIndex = webidl.converters.GPUSize32(queryIndex, { prefix, - context: "Argument 2", + context: "Argument 1", }); - const device = assertDevice(this[_encoder], { + assertDevice(this[_encoder], { prefix, context: "encoder referenced by this", }); @@ -3616,26 +3654,16 @@ class GPURenderPassEncoder { 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", - }); - ops.op_webgpu_render_pass_begin_pipeline_statistics_query( + ops.op_webgpu_render_pass_begin_occlusion_query( renderPassRid, - querySetRid, queryIndex, ); } - endPipelineStatisticsQuery() { + endOcclusionQuery() { webidl.assertBranded(this, GPURenderPassEncoderPrototype); const prefix = - "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; + "Failed to execute 'endOcclusionQuery' on 'GPUComputePassEncoder'"; assertDevice(this[_encoder], { prefix, context: "encoder referenced by this", @@ -3645,49 +3673,7 @@ class GPURenderPassEncoder { context: "encoder referenced by this", }); const renderPassRid = assertResource(this, { prefix, context: "this" }); - ops.op_webgpu_render_pass_end_pipeline_statistics_query(renderPassRid); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - writeTimestamp(querySet, queryIndex) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - 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", - }); - 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", - }); - ops.op_webgpu_render_pass_write_timestamp( - renderPassRid, - querySetRid, - queryIndex, - ); + ops.op_webgpu_render_pass_end_occlusion_query(renderPassRid); } /** @@ -4346,106 +4332,6 @@ class GPUComputePassEncoder { ); } - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - beginPipelineStatisticsQuery(querySet, queryIndex) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - 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", - }); - 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", - }); - ops.op_webgpu_compute_pass_begin_pipeline_statistics_query( - computePassRid, - querySetRid, - queryIndex, - ); - } - - endPipelineStatisticsQuery() { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - 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" }); - ops.op_webgpu_compute_pass_end_pipeline_statistics_query(computePassRid); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - writeTimestamp(querySet, queryIndex) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - 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", - }); - 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", - }); - ops.op_webgpu_compute_pass_write_timestamp( - computePassRid, - querySetRid, - queryIndex, - ); - } - end() { webidl.assertBranded(this, GPUComputePassEncoderPrototype); const prefix = "Failed to execute 'end' on 'GPUComputePassEncoder'"; @@ -5205,7 +5091,7 @@ const GPUQuerySetPrototype = GPUQuerySet.prototype; // otherwise their converters might not be available yet. // DICTIONARY: GPUObjectDescriptorBase const dictMembersGPUObjectDescriptorBase = [ - { key: "label", converter: webidl.converters["USVString"] }, + { key: "label", converter: webidl.converters["USVString"], defaultValue: "" }, ]; webidl.converters["GPUObjectDescriptorBase"] = webidl .createDictionaryConverter( @@ -5285,7 +5171,7 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( "texture-compression-astc-hdr", "texture-adapter-specific-format-features", // api - "pipeline-statistics-query", + //"pipeline-statistics-query", "timestamp-query-inside-passes", "mappable-primary-buffers", "texture-binding-array", @@ -6862,8 +6748,33 @@ webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter( GPUComputePassEncoder.prototype, ); +// DICTIONARY: GPUComputePassTimestampWrites +webidl.converters["GPUComputePassTimestampWrites"] = webidl.createDictionaryConverter( + "GPUComputePassTimestampWrites", + [ + { + key: "querySet", + converter: webidl.converters["GPUQuerySet"], + required: true, + }, + { + key: "beginningOfPassWriteIndex", + converter: webidl.converters["GPUSize32"], + }, + { + key: "endOfPassWriteIndex", + converter: webidl.converters["GPUSize32"], + }, + ], +); + // DICTIONARY: GPUComputePassDescriptor -const dictMembersGPUComputePassDescriptor = []; +const dictMembersGPUComputePassDescriptor = [ + { + key: "timestampWrites", + converter: webidl.converters["GPUComputePassTimestampWrites"], + }, +]; webidl.converters["GPUComputePassDescriptor"] = webidl .createDictionaryConverter( "GPUComputePassDescriptor", @@ -7005,6 +6916,26 @@ webidl.converters.GPUQuerySet = webidl.createInterfaceConverter( GPUQuerySet.prototype, ); +// DICTIONARY: GPURenderPassTimestampWrites +webidl.converters["GPURenderPassTimestampWrites"] = webidl.createDictionaryConverter( + "GPURenderPassTimestampWrites", + [ + { + key: "querySet", + converter: webidl.converters["GPUQuerySet"], + required: true, + }, + { + key: "beginningOfPassWriteIndex", + converter: webidl.converters["GPUSize32"], + }, + { + key: "endOfPassWriteIndex", + converter: webidl.converters["GPUSize32"], + }, + ], +); + // DICTIONARY: GPURenderPassDescriptor const dictMembersGPURenderPassDescriptor = [ { @@ -7020,6 +6951,14 @@ const dictMembersGPURenderPassDescriptor = [ key: "depthStencilAttachment", converter: webidl.converters["GPURenderPassDepthStencilAttachment"], }, + { + key: "occlusionQuerySet", + converter: webidl.converters["GPUQuerySet"], + }, + { + key: "timestampWrites", + converter: webidl.converters["GPURenderPassTimestampWrites"], + }, ]; webidl.converters["GPURenderPassDescriptor"] = webidl .createDictionaryConverter( @@ -7109,23 +7048,10 @@ webidl.converters["GPUQueryType"] = webidl.createEnumConverter( "GPUQueryType", [ "occlusion", - "pipeline-statistics", "timestamp", ], ); -// 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 = [ { diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index df758a1d9c..bbc5b13f29 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -39,6 +39,10 @@ features = ["metal"] workspace = true features = ["dx11", "dx12"] +[target.'cfg(windows)'.dependencies.wgpu-hal] +path = "../wgpu-hal" +features = ["windows_rs"] + # We want the wgpu-core Vulkan backend on Unix (but not Emscripten) and Windows. [target.'cfg(any(windows, all(unix, not(target_os = "emscripten"))))'.dependencies.wgpu-core] workspace = true diff --git a/deno_webgpu/binding.rs b/deno_webgpu/binding.rs index 9ecb3f5143..5d582e900f 100644 --- a/deno_webgpu/binding.rs +++ b/deno_webgpu/binding.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -176,12 +176,13 @@ impl From for wgpu_types::BindingType { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_bind_group_layout( state: &mut OpState, - device_rid: ResourceId, - label: Option, - entries: Vec, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[serde] entries: Vec, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -202,7 +203,7 @@ pub fn op_webgpu_create_bind_group_layout( .collect::>(); let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { - label: label.map(Cow::from), + label: Some(label), entries: Cow::from(entries), }; @@ -213,12 +214,13 @@ pub fn op_webgpu_create_bind_group_layout( ) => state, WebGpuBindGroupLayout) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_pipeline_layout( state: &mut OpState, - device_rid: ResourceId, - label: Option, - bind_group_layouts: Vec, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[serde] bind_group_layouts: Vec, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -235,7 +237,7 @@ pub fn op_webgpu_create_pipeline_layout( .collect::, AnyError>>()?; let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { - label: label.map(Cow::from), + label: Some(label), bind_group_layouts: Cow::from(bind_group_layouts), push_constant_ranges: Default::default(), }; @@ -257,13 +259,14 @@ pub struct GpuBindGroupEntry { size: Option, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_bind_group( state: &mut OpState, - device_rid: ResourceId, - label: Option, - layout: ResourceId, - entries: Vec, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[smi] layout: ResourceId, + #[serde] entries: Vec, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -313,7 +316,7 @@ pub fn op_webgpu_create_bind_group( let bind_group_layout = state.resource_table.get::(layout)?; let descriptor = wgpu_core::binding_model::BindGroupDescriptor { - label: label.map(Cow::from), + label: Some(label), layout: bind_group_layout.1, entries: Cow::from(entries), }; diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index 7c5f9d58c2..03f088f8d1 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -3,14 +3,12 @@ use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::futures::channel::oneshot; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use std::borrow::Cow; use std::cell::RefCell; -use std::convert::TryFrom; use std::rc::Rc; use std::time::Duration; use wgpu_core::resource::BufferAccessResult; @@ -40,12 +38,13 @@ impl Resource for WebGpuBufferMapped { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_buffer( state: &mut OpState, - device_rid: ResourceId, - label: Option, - size: u64, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[number] size: u64, usage: u32, mapped_at_creation: bool, ) -> Result { @@ -56,7 +55,7 @@ pub fn op_webgpu_create_buffer( let device = device_resource.1; let descriptor = wgpu_core::resource::BufferDescriptor { - label: label.map(Cow::from), + label: Some(label), size, usage: wgpu_types::BufferUsages::from_bits(usage) .ok_or_else(|| type_error("usage is not valid"))?, @@ -70,14 +69,15 @@ pub fn op_webgpu_create_buffer( ) => state, WebGpuBuffer) } -#[op] +#[op2(async)] +#[serde] pub async fn op_webgpu_buffer_get_map_async( state: Rc>, - buffer_rid: ResourceId, - device_rid: ResourceId, + #[smi] buffer_rid: ResourceId, + #[smi] device_rid: ResourceId, mode: u32, - offset: u64, - size: u64, + #[number] offset: u64, + #[number] size: u64, ) -> Result { let (sender, receiver) = oneshot::channel::(); @@ -143,13 +143,14 @@ pub async fn op_webgpu_buffer_get_map_async( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_buffer_get_mapped_range( state: &mut OpState, - buffer_rid: ResourceId, - offset: u64, - size: Option, - mut buf: ZeroCopyBuf, + #[smi] buffer_rid: ResourceId, + #[number] offset: u64, + #[number] size: Option, + #[buffer] buf: &mut [u8], ) -> Result { let instance = state.borrow::(); let buffer_resource = state.resource_table.get::(buffer_rid)?; @@ -172,12 +173,13 @@ pub fn op_webgpu_buffer_get_mapped_range( Ok(WebGpuResult::rid(rid)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_buffer_unmap( state: &mut OpState, - buffer_rid: ResourceId, - mapped_rid: ResourceId, - buf: Option, + #[smi] buffer_rid: ResourceId, + #[smi] mapped_rid: ResourceId, + #[buffer] buf: Option<&[u8]>, ) -> Result { let mapped_resource = state .resource_table @@ -188,7 +190,7 @@ pub fn op_webgpu_buffer_unmap( if let Some(buf) = buf { let slice = unsafe { std::slice::from_raw_parts_mut(mapped_resource.0, mapped_resource.1) }; - slice.copy_from_slice(&buf); + slice.copy_from_slice(buf); } gfx_ok!(buffer => instance.buffer_unmap(buffer)) diff --git a/deno_webgpu/bundle.rs b/deno_webgpu/bundle.rs index bcb321f497..b053cf265c 100644 --- a/deno_webgpu/bundle.rs +++ b/deno_webgpu/bundle.rs @@ -2,11 +2,10 @@ use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -40,7 +39,7 @@ impl Resource for WebGpuRenderBundle { #[serde(rename_all = "camelCase")] pub struct CreateRenderBundleEncoderArgs { device_rid: ResourceId, - label: Option, + label: String, color_formats: Vec>, depth_stencil_format: Option, sample_count: u32, @@ -48,10 +47,11 @@ pub struct CreateRenderBundleEncoderArgs { stencil_read_only: bool, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_render_bundle_encoder( state: &mut OpState, - args: CreateRenderBundleEncoderArgs, + #[serde] args: CreateRenderBundleEncoderArgs, ) -> Result { let device_resource = state .resource_table @@ -67,7 +67,7 @@ pub fn op_webgpu_create_render_bundle_encoder( }); let descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { - label: args.label.map(Cow::from), + label: Some(Cow::Owned(args.label)), color_formats: Cow::from(args.color_formats), sample_count: args.sample_count, depth_stencil, @@ -92,11 +92,12 @@ pub fn op_webgpu_create_render_bundle_encoder( Ok(WebGpuResult::rid_err(rid, maybe_err)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_finish( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - label: Option, + #[smi] render_bundle_encoder_rid: ResourceId, + #[string] label: Cow, ) -> Result { let render_bundle_encoder_resource = state .resource_table @@ -111,21 +112,22 @@ pub fn op_webgpu_render_bundle_encoder_finish( gfx_put!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( render_bundle_encoder, &wgpu_core::command::RenderBundleDescriptor { - label: label.map(Cow::from), + label: Some(label), }, () ) => state, WebGpuRenderBundle) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_set_bind_group( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, index: u32, - bind_group: ResourceId, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, + #[smi] bind_group: ResourceId, + #[buffer] dynamic_offsets_data: &[u32], + #[number] dynamic_offsets_data_start: usize, + #[number] dynamic_offsets_data_length: usize, ) -> Result { let bind_group_resource = state .resource_table @@ -134,14 +136,6 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( .resource_table .get::(render_bundle_encoder_rid)?; - // Align the data - assert!(dynamic_offsets_data.len() % std::mem::size_of::() == 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = unsafe { dynamic_offsets_data.align_to::() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - let start = dynamic_offsets_data_start; let len = dynamic_offsets_data_length; @@ -149,7 +143,7 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( assert!(start <= dynamic_offsets_data.len()); assert!(len <= dynamic_offsets_data.len() - start); - let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; + let dynamic_offsets_data = &dynamic_offsets_data[start..start + len]; // SAFETY: the raw pointer and length are of the same slice, and that slice // lives longer than the below function invocation. @@ -166,11 +160,12 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_push_debug_group( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - group_label: String, + #[smi] render_bundle_encoder_rid: ResourceId, + #[string] group_label: &str, ) -> Result { let render_bundle_encoder_resource = state .resource_table @@ -189,10 +184,11 @@ pub fn op_webgpu_render_bundle_encoder_push_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_pop_debug_group( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, ) -> Result { let render_bundle_encoder_resource = state .resource_table @@ -205,11 +201,12 @@ pub fn op_webgpu_render_bundle_encoder_pop_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - marker_label: String, + #[smi] render_bundle_encoder_rid: ResourceId, + #[string] marker_label: &str, ) -> Result { let render_bundle_encoder_resource = state .resource_table @@ -228,11 +225,12 @@ pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_set_pipeline( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - pipeline: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, + #[smi] pipeline: ResourceId, ) -> Result { let render_pipeline_resource = state .resource_table @@ -249,14 +247,15 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_set_index_buffer( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - buffer: ResourceId, - index_format: wgpu_types::IndexFormat, - offset: u64, - size: u64, + #[smi] render_bundle_encoder_rid: ResourceId, + #[smi] buffer: ResourceId, + #[serde] index_format: wgpu_types::IndexFormat, + #[number] offset: u64, + #[number] size: u64, ) -> Result { let buffer_resource = state .resource_table @@ -276,14 +275,15 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, slot: u32, - buffer: ResourceId, - offset: u64, - size: Option, + #[smi] buffer: ResourceId, + #[number] offset: u64, + #[number] size: Option, ) -> Result { let buffer_resource = state .resource_table @@ -311,10 +311,11 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_draw( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, vertex_count: u32, instance_count: u32, first_vertex: u32, @@ -335,10 +336,11 @@ pub fn op_webgpu_render_bundle_encoder_draw( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_draw_indexed( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, + #[smi] render_bundle_encoder_rid: ResourceId, index_count: u32, instance_count: u32, first_index: u32, @@ -361,12 +363,13 @@ pub fn op_webgpu_render_bundle_encoder_draw_indexed( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_bundle_encoder_draw_indirect( state: &mut OpState, - render_bundle_encoder_rid: ResourceId, - indirect_buffer: ResourceId, - indirect_offset: u64, + #[smi] render_bundle_encoder_rid: ResourceId, + #[smi] indirect_buffer: ResourceId, + #[number] indirect_offset: u64, ) -> Result { let buffer_resource = state .resource_table diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 4857b0a7a7..60de26eaf9 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -1,7 +1,8 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use crate::WebGpuQuerySet; use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -44,11 +45,12 @@ impl Resource for WebGpuCommandBuffer { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_command_encoder( state: &mut OpState, - device_rid: ResourceId, - label: Option, + #[smi] device_rid: ResourceId, + #[string] label: Cow, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -56,9 +58,7 @@ pub fn op_webgpu_create_command_encoder( .get::(device_rid)?; let device = device_resource.1; - let descriptor = wgpu_types::CommandEncoderDescriptor { - label: label.map(Cow::from), - }; + let descriptor = wgpu_types::CommandEncoderDescriptor { label: Some(label) }; gfx_put!(device => instance.device_create_command_encoder( device, @@ -91,14 +91,24 @@ pub struct GpuRenderPassDepthStencilAttachment { stencil_read_only: bool, } -#[op] +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GPURenderPassTimestampWrites { + query_set: ResourceId, + beginning_of_pass_write_index: Option, + end_of_pass_write_index: Option, +} + +#[op2] +#[serde] pub fn op_webgpu_command_encoder_begin_render_pass( state: &mut OpState, - command_encoder_rid: ResourceId, - label: Option, - color_attachments: Vec>, - depth_stencil_attachment: Option, - occlusion_query_set: Option, + #[smi] command_encoder_rid: ResourceId, + #[string] label: Cow, + #[serde] color_attachments: Vec>, + #[serde] depth_stencil_attachment: Option, + #[smi] occlusion_query_set: Option, + #[serde] timestamp_writes: Option, ) -> Result { let command_encoder_resource = state .resource_table @@ -172,16 +182,31 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }); } + let timestamp_writes = if let Some(timestamp_writes) = timestamp_writes { + let query_set_resource = state + .resource_table + .get::(timestamp_writes.query_set)?; + let query_set = query_set_resource.1; + + Some(wgpu_core::command::RenderPassTimestampWrites { + query_set, + beginning_of_pass_write_index: timestamp_writes.beginning_of_pass_write_index, + end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, + }) + } else { + None + }; + let occlusion_query_set_resource = occlusion_query_set - .map(|rid| state.resource_table.get::(rid)) + .map(|rid| state.resource_table.get::(rid)) .transpose()? .map(|query_set| query_set.1); let descriptor = wgpu_core::command::RenderPassDescriptor { - label: label.map(Cow::from), + label: Some(label), color_attachments: Cow::from(color_attachments), depth_stencil_attachment: processed_depth_stencil_attachment.as_ref(), - timestamp_writes: None, + timestamp_writes: timestamp_writes.as_ref(), occlusion_query_set: occlusion_query_set_resource, }; @@ -196,19 +221,44 @@ pub fn op_webgpu_command_encoder_begin_render_pass( Ok(WebGpuResult::rid(rid)) } -#[op] +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GPUComputePassTimestampWrites { + query_set: ResourceId, + beginning_of_pass_write_index: Option, + end_of_pass_write_index: Option, +} + +#[op2] +#[serde] pub fn op_webgpu_command_encoder_begin_compute_pass( state: &mut OpState, - command_encoder_rid: ResourceId, - label: Option, + #[smi] command_encoder_rid: ResourceId, + #[string] label: Cow, + #[serde] timestamp_writes: Option, ) -> Result { let command_encoder_resource = state .resource_table .get::(command_encoder_rid)?; + let timestamp_writes = if let Some(timestamp_writes) = timestamp_writes { + let query_set_resource = state + .resource_table + .get::(timestamp_writes.query_set)?; + let query_set = query_set_resource.1; + + Some(wgpu_core::command::ComputePassTimestampWrites { + query_set, + beginning_of_pass_write_index: timestamp_writes.beginning_of_pass_write_index, + end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, + }) + } else { + None + }; + let descriptor = wgpu_core::command::ComputePassDescriptor { - label: label.map(Cow::from), - timestamp_writes: None, + label: Some(label), + timestamp_writes: timestamp_writes.as_ref(), }; let compute_pass = @@ -223,15 +273,16 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( Ok(WebGpuResult::rid(rid)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( state: &mut OpState, - command_encoder_rid: ResourceId, - source: ResourceId, - source_offset: u64, - destination: ResourceId, - destination_offset: u64, - size: u64, + #[smi] command_encoder_rid: ResourceId, + #[smi] source: ResourceId, + #[number] source_offset: u64, + #[smi] destination: ResourceId, + #[number] destination_offset: u64, + #[number] size: u64, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -275,13 +326,14 @@ pub struct GpuImageCopyTexture { pub aspect: wgpu_types::TextureAspect, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_copy_buffer_to_texture( state: &mut OpState, - command_encoder_rid: ResourceId, - source: GpuImageCopyBuffer, - destination: GpuImageCopyTexture, - copy_size: wgpu_types::Extent3d, + #[smi] command_encoder_rid: ResourceId, + #[serde] source: GpuImageCopyBuffer, + #[serde] destination: GpuImageCopyTexture, + #[serde] copy_size: wgpu_types::Extent3d, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -317,13 +369,14 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_copy_texture_to_buffer( state: &mut OpState, - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyBuffer, - copy_size: wgpu_types::Extent3d, + #[smi] command_encoder_rid: ResourceId, + #[serde] source: GpuImageCopyTexture, + #[serde] destination: GpuImageCopyBuffer, + #[serde] copy_size: wgpu_types::Extent3d, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -359,13 +412,14 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_copy_texture_to_texture( state: &mut OpState, - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyTexture, - copy_size: wgpu_types::Extent3d, + #[smi] command_encoder_rid: ResourceId, + #[serde] source: GpuImageCopyTexture, + #[serde] destination: GpuImageCopyTexture, + #[serde] copy_size: wgpu_types::Extent3d, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -399,13 +453,14 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_clear_buffer( state: &mut OpState, - command_encoder_rid: u32, - buffer_rid: u32, - offset: u64, - size: u64, + #[smi] command_encoder_rid: ResourceId, + #[smi] buffer_rid: ResourceId, + #[number] offset: u64, + #[number] size: u64, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -424,11 +479,12 @@ pub fn op_webgpu_command_encoder_clear_buffer( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_push_debug_group( state: &mut OpState, - command_encoder_rid: ResourceId, - group_label: String, + #[smi] command_encoder_rid: ResourceId, + #[string] group_label: &str, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -436,13 +492,14 @@ pub fn op_webgpu_command_encoder_push_debug_group( .get::(command_encoder_rid)?; let command_encoder = command_encoder_resource.1; - gfx_ok!(command_encoder => instance.command_encoder_push_debug_group(command_encoder, &group_label)) + gfx_ok!(command_encoder => instance.command_encoder_push_debug_group(command_encoder, group_label)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_pop_debug_group( state: &mut OpState, - command_encoder_rid: ResourceId, + #[smi] command_encoder_rid: ResourceId, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -453,11 +510,12 @@ pub fn op_webgpu_command_encoder_pop_debug_group( gfx_ok!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_insert_debug_marker( state: &mut OpState, - command_encoder_rid: ResourceId, - marker_label: String, + #[smi] command_encoder_rid: ResourceId, + #[string] marker_label: &str, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -467,15 +525,16 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( gfx_ok!(command_encoder => instance.command_encoder_insert_debug_marker( command_encoder, - &marker_label + marker_label )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_write_timestamp( state: &mut OpState, - command_encoder_rid: ResourceId, - query_set: ResourceId, + #[smi] command_encoder_rid: ResourceId, + #[smi] query_set: ResourceId, query_index: u32, ) -> Result { let instance = state.borrow::(); @@ -494,15 +553,16 @@ pub fn op_webgpu_command_encoder_write_timestamp( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_resolve_query_set( state: &mut OpState, - command_encoder_rid: ResourceId, - query_set: ResourceId, + #[smi] command_encoder_rid: ResourceId, + #[smi] query_set: ResourceId, first_query: u32, query_count: u32, - destination: ResourceId, - destination_offset: u64, + #[smi] destination: ResourceId, + #[number] destination_offset: u64, ) -> Result { let instance = state.borrow::(); let command_encoder_resource = state @@ -526,11 +586,12 @@ pub fn op_webgpu_command_encoder_resolve_query_set( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_command_encoder_finish( state: &mut OpState, - command_encoder_rid: ResourceId, - label: Option, + #[smi] command_encoder_rid: ResourceId, + #[string] label: Cow, ) -> Result { let command_encoder_resource = state .resource_table @@ -538,9 +599,7 @@ pub fn op_webgpu_command_encoder_finish( let command_encoder = command_encoder_resource.1; let instance = state.borrow::(); - let descriptor = wgpu_types::CommandBufferDescriptor { - label: label.map(Cow::from), - }; + let descriptor = wgpu_types::CommandBufferDescriptor { label: Some(label) }; let (val, maybe_err) = gfx_select!(command_encoder => instance.command_encoder_finish( command_encoder, diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index cc70146917..e1c9e29193 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -1,11 +1,10 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use std::borrow::Cow; use std::cell::RefCell; @@ -18,11 +17,12 @@ impl Resource for WebGpuComputePass { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_set_pipeline( state: &mut OpState, - compute_pass_rid: ResourceId, - pipeline: ResourceId, + #[smi] compute_pass_rid: ResourceId, + #[smi] pipeline: ResourceId, ) -> Result { let compute_pipeline_resource = state .resource_table @@ -39,10 +39,11 @@ pub fn op_webgpu_compute_pass_set_pipeline( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_dispatch_workgroups( state: &mut OpState, - compute_pass_rid: ResourceId, + #[smi] compute_pass_rid: ResourceId, x: u32, y: u32, z: u32, @@ -61,12 +62,13 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_dispatch_workgroups_indirect( state: &mut OpState, - compute_pass_rid: ResourceId, - indirect_buffer: ResourceId, - indirect_offset: u64, + #[smi] compute_pass_rid: ResourceId, + #[smi] indirect_buffer: ResourceId, + #[number] indirect_offset: u64, ) -> Result { let buffer_resource = state .resource_table @@ -84,73 +86,12 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups_indirect( Ok(WebGpuResult::empty()) } -#[op] -pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( - state: &mut OpState, - compute_pass_rid: ResourceId, - query_set: ResourceId, - query_index: u32, -) -> Result { - let compute_pass_resource = state - .resource_table - .get::(compute_pass_rid)?; - let query_set_resource = state - .resource_table - .get::(query_set)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.1, - query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[op] -pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( - state: &mut OpState, - compute_pass_rid: ResourceId, -) -> Result { - let compute_pass_resource = state - .resource_table - .get::(compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[op] -pub fn op_webgpu_compute_pass_write_timestamp( - state: &mut OpState, - compute_pass_rid: ResourceId, - query_set: ResourceId, - query_index: u32, -) -> Result { - let compute_pass_resource = state - .resource_table - .get::(compute_pass_rid)?; - let query_set_resource = state - .resource_table - .get::(query_set)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_write_timestamp( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.1, - query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_end( state: &mut OpState, - command_encoder_rid: ResourceId, - compute_pass_rid: ResourceId, + #[smi] command_encoder_rid: ResourceId, + #[smi] compute_pass_rid: ResourceId, ) -> Result { let command_encoder_resource = state @@ -169,15 +110,16 @@ pub fn op_webgpu_compute_pass_end( )) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_set_bind_group( state: &mut OpState, - compute_pass_rid: ResourceId, + #[smi] compute_pass_rid: ResourceId, index: u32, - bind_group: ResourceId, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, + #[smi] bind_group: ResourceId, + #[buffer] dynamic_offsets_data: &[u32], + #[number] dynamic_offsets_data_start: usize, + #[number] dynamic_offsets_data_length: usize, ) -> Result { let bind_group_resource = state .resource_table @@ -186,14 +128,6 @@ pub fn op_webgpu_compute_pass_set_bind_group( .resource_table .get::(compute_pass_rid)?; - // Align the data - assert!(dynamic_offsets_data_start % std::mem::size_of::() == 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = unsafe { dynamic_offsets_data.align_to::() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - let start = dynamic_offsets_data_start; let len = dynamic_offsets_data_length; @@ -218,11 +152,12 @@ pub fn op_webgpu_compute_pass_set_bind_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_push_debug_group( state: &mut OpState, - compute_pass_rid: ResourceId, - group_label: String, + #[smi] compute_pass_rid: ResourceId, + #[string] group_label: &str, ) -> Result { let compute_pass_resource = state .resource_table @@ -242,10 +177,11 @@ pub fn op_webgpu_compute_pass_push_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_pop_debug_group( state: &mut OpState, - compute_pass_rid: ResourceId, + #[smi] compute_pass_rid: ResourceId, ) -> Result { let compute_pass_resource = state .resource_table @@ -258,11 +194,12 @@ pub fn op_webgpu_compute_pass_pop_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pass_insert_debug_marker( state: &mut OpState, - compute_pass_rid: ResourceId, - marker_label: String, + #[smi] compute_pass_rid: ResourceId, + #[string] marker_label: &str, ) -> Result { let compute_pass_resource = state .resource_table diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index bf61e42517..27ff0680c3 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -3,7 +3,7 @@ #![warn(unsafe_op_in_unsafe_fn)] use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -12,7 +12,6 @@ use serde::Serialize; use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashSet; -use std::convert::TryFrom; use std::rc::Rc; pub use wgpu_core; pub use wgpu_types; @@ -181,9 +180,8 @@ deno_core::extension!( render_pass::op_webgpu_render_pass_set_scissor_rect, render_pass::op_webgpu_render_pass_set_blend_constant, render_pass::op_webgpu_render_pass_set_stencil_reference, - render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, - render_pass::op_webgpu_render_pass_end_pipeline_statistics_query, - render_pass::op_webgpu_render_pass_write_timestamp, + render_pass::op_webgpu_render_pass_begin_occlusion_query, + render_pass::op_webgpu_render_pass_end_occlusion_query, render_pass::op_webgpu_render_pass_execute_bundles, render_pass::op_webgpu_render_pass_end, render_pass::op_webgpu_render_pass_set_bind_group, @@ -200,9 +198,6 @@ deno_core::extension!( compute_pass::op_webgpu_compute_pass_set_pipeline, compute_pass::op_webgpu_compute_pass_dispatch_workgroups, compute_pass::op_webgpu_compute_pass_dispatch_workgroups_indirect, - compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query, - compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query, - compute_pass::op_webgpu_compute_pass_write_timestamp, compute_pass::op_webgpu_compute_pass_end, compute_pass::op_webgpu_compute_pass_set_bind_group, compute_pass::op_webgpu_compute_pass_push_debug_group, @@ -388,10 +383,11 @@ pub struct GpuAdapterDevice { is_software: bool, } -#[op] +#[op2(async)] +#[serde] pub async fn op_webgpu_request_adapter( state: Rc>, - power_preference: Option, + #[serde] power_preference: Option, force_fallback_adapter: bool, ) -> Result { let mut state = state.borrow_mut(); @@ -637,13 +633,14 @@ impl From for wgpu_types::Features { } } -#[op] +#[op2(async)] +#[serde] pub async fn op_webgpu_request_device( state: Rc>, - adapter_rid: ResourceId, - label: Option, - required_features: GpuRequiredFeatures, - required_limits: Option, + #[smi] adapter_rid: ResourceId, + #[string] label: String, + #[serde] required_features: GpuRequiredFeatures, + #[serde] required_limits: Option, ) -> Result { let mut state = state.borrow_mut(); let adapter_resource = state.resource_table.get::(adapter_rid)?; @@ -651,7 +648,7 @@ pub async fn op_webgpu_request_device( let instance = state.borrow::(); let descriptor = wgpu_types::DeviceDescriptor { - label: label.map(Cow::from), + label: Some(Cow::Owned(label)), features: required_features.into(), limits: required_limits.unwrap_or_default(), }; @@ -691,10 +688,11 @@ pub struct GPUAdapterInfo { description: String, } -#[op] +#[op2(async)] +#[serde] pub async fn op_webgpu_request_adapter_info( state: Rc>, - adapter_rid: ResourceId, + #[smi] adapter_rid: ResourceId, ) -> Result { let state = state.borrow_mut(); let adapter_resource = state.resource_table.get::(adapter_rid)?; @@ -715,7 +713,7 @@ pub async fn op_webgpu_request_adapter_info( #[serde(rename_all = "camelCase")] pub struct CreateQuerySetArgs { device_rid: ResourceId, - label: Option, + label: String, #[serde(flatten)] r#type: GpuQueryType, count: u32, @@ -725,10 +723,6 @@ pub struct CreateQuerySetArgs { #[serde(rename_all = "kebab-case", tag = "type")] enum GpuQueryType { Occlusion, - #[serde(rename_all = "camelCase")] - PipelineStatistics { - pipeline_statistics: HashSet, - }, Timestamp, } @@ -736,47 +730,23 @@ impl From for wgpu_types::QueryType { fn from(query_type: GpuQueryType) -> Self { match query_type { GpuQueryType::Occlusion => wgpu_types::QueryType::Occlusion, - GpuQueryType::PipelineStatistics { - pipeline_statistics, - } => { - use wgpu_types::PipelineStatisticsTypes; - - let mut types = PipelineStatisticsTypes::empty(); - - if pipeline_statistics.contains("vertex-shader-invocations") { - types.set(PipelineStatisticsTypes::VERTEX_SHADER_INVOCATIONS, true); - } - if pipeline_statistics.contains("clipper-invocations") { - types.set(PipelineStatisticsTypes::CLIPPER_INVOCATIONS, true); - } - if pipeline_statistics.contains("clipper-primitives-out") { - types.set(PipelineStatisticsTypes::CLIPPER_PRIMITIVES_OUT, true); - } - if pipeline_statistics.contains("fragment-shader-invocations") { - types.set(PipelineStatisticsTypes::FRAGMENT_SHADER_INVOCATIONS, true); - } - if pipeline_statistics.contains("compute-shader-invocations") { - types.set(PipelineStatisticsTypes::COMPUTE_SHADER_INVOCATIONS, true); - } - - wgpu_types::QueryType::PipelineStatistics(types) - } GpuQueryType::Timestamp => wgpu_types::QueryType::Timestamp, } } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_query_set( state: &mut OpState, - args: CreateQuerySetArgs, + #[serde] args: CreateQuerySetArgs, ) -> Result { let device_resource = state.resource_table.get::(args.device_rid)?; let device = device_resource.1; let instance = state.borrow::(); let descriptor = wgpu_types::QuerySetDescriptor { - label: args.label.map(Cow::from), + label: Some(Cow::Owned(args.label)), ty: args.r#type.into(), count: args.count, }; diff --git a/deno_webgpu/pipeline.rs b/deno_webgpu/pipeline.rs index 13589df2da..e0555b9d1e 100644 --- a/deno_webgpu/pipeline.rs +++ b/deno_webgpu/pipeline.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -81,13 +81,14 @@ pub struct GpuProgrammableStage { // constants: HashMap } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_compute_pipeline( state: &mut OpState, - device_rid: ResourceId, - label: Option, - layout: GPUPipelineLayoutOrGPUAutoLayoutMode, - compute: GpuProgrammableStage, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[serde] layout: GPUPipelineLayoutOrGPUAutoLayoutMode, + #[serde] compute: GpuProgrammableStage, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -108,7 +109,7 @@ pub fn op_webgpu_create_compute_pipeline( .get::(compute.module)?; let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: label.map(Cow::from), + label: Some(label), layout: pipeline_layout, stage: wgpu_core::pipeline::ProgrammableStageDescriptor { module: compute_shader_module_resource.1, @@ -148,10 +149,11 @@ pub struct PipelineLayout { err: Option, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_compute_pipeline_get_bind_group_layout( state: &mut OpState, - compute_pipeline_rid: ResourceId, + #[smi] compute_pipeline_rid: ResourceId, index: u32, ) -> Result { let instance = state.borrow::(); @@ -314,7 +316,7 @@ struct GpuFragmentState { #[serde(rename_all = "camelCase")] pub struct CreateRenderPipelineArgs { device_rid: ResourceId, - label: Option, + label: String, layout: GPUPipelineLayoutOrGPUAutoLayoutMode, vertex: GpuVertexState, primitive: GpuPrimitiveState, @@ -323,10 +325,11 @@ pub struct CreateRenderPipelineArgs { fragment: Option, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_render_pipeline( state: &mut OpState, - args: CreateRenderPipelineArgs, + #[serde] args: CreateRenderPipelineArgs, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -372,7 +375,7 @@ pub fn op_webgpu_create_render_pipeline( .collect(); let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { - label: args.label.map(Cow::Owned), + label: Some(Cow::Owned(args.label)), layout, vertex: wgpu_core::pipeline::VertexState { stage: wgpu_core::pipeline::ProgrammableStageDescriptor { @@ -412,10 +415,11 @@ pub fn op_webgpu_create_render_pipeline( Ok(WebGpuResult::rid_err(rid, maybe_err)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pipeline_get_bind_group_layout( state: &mut OpState, - render_pipeline_rid: ResourceId, + #[smi] render_pipeline_rid: ResourceId, index: u32, ) -> Result { let instance = state.borrow::(); diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 2845990776..1f6258935f 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -1,21 +1,23 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use crate::command_encoder::WebGpuCommandBuffer; use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; +use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use super::error::WebGpuResult; type WebGpuQueue = super::WebGpuDevice; -#[op] +#[op2] +#[serde] pub fn op_webgpu_queue_submit( state: &mut OpState, - queue_rid: ResourceId, - command_buffers: Vec, + #[smi] queue_rid: ResourceId, + #[serde] command_buffers: Vec, ) -> Result { let instance = state.borrow::(); let queue_resource = state.resource_table.get::(queue_rid)?; @@ -24,9 +26,7 @@ pub fn op_webgpu_queue_submit( let ids = command_buffers .iter() .map(|rid| { - let buffer_resource = state - .resource_table - .get::(*rid)?; + let buffer_resource = state.resource_table.get::(*rid)?; let mut id = buffer_resource.1.borrow_mut(); Ok(id.take().unwrap()) }) @@ -35,7 +35,8 @@ pub fn op_webgpu_queue_submit( let maybe_err = gfx_select!(queue => instance.queue_submit(queue, &ids)).err(); for rid in command_buffers { - state.resource_table.close(rid)?; + let resource = state.resource_table.take::(rid)?; + resource.close(); } Ok(WebGpuResult::maybe_err(maybe_err)) @@ -59,15 +60,16 @@ impl From for wgpu_types::ImageDataLayout { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_write_buffer( state: &mut OpState, - queue_rid: ResourceId, - buffer: ResourceId, - buffer_offset: u64, - data_offset: usize, - size: Option, - buf: ZeroCopyBuf, + #[smi] queue_rid: ResourceId, + #[smi] buffer: ResourceId, + #[number] buffer_offset: u64, + #[number] data_offset: usize, + #[number] size: Option, + #[buffer] buf: &[u8], ) -> Result { let instance = state.borrow::(); let buffer_resource = state @@ -92,14 +94,15 @@ pub fn op_webgpu_write_buffer( Ok(WebGpuResult::maybe_err(maybe_err)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_write_texture( state: &mut OpState, - queue_rid: ResourceId, - destination: super::command_encoder::GpuImageCopyTexture, - data_layout: GpuImageDataLayout, - size: wgpu_types::Extent3d, - buf: ZeroCopyBuf, + #[smi] queue_rid: ResourceId, + #[serde] destination: super::command_encoder::GpuImageCopyTexture, + #[serde] data_layout: GpuImageDataLayout, + #[serde] size: wgpu_types::Extent3d, + #[buffer] buf: &[u8], ) -> Result { let instance = state.borrow::(); let texture_resource = state @@ -119,7 +122,7 @@ pub fn op_webgpu_write_texture( gfx_ok!(queue => instance.queue_write_texture( queue, &destination, - &*buf, + buf, &data_layout, &size )) diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index 678990ea3d..47b98c91fd 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -2,11 +2,10 @@ use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; @@ -32,10 +31,11 @@ pub struct RenderPassSetViewportArgs { max_depth: f32, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_viewport( state: &mut OpState, - args: RenderPassSetViewportArgs, + #[serde] args: RenderPassSetViewportArgs, ) -> Result { let render_pass_resource = state .resource_table @@ -54,10 +54,11 @@ pub fn op_webgpu_render_pass_set_viewport( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_scissor_rect( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, x: u32, y: u32, width: u32, @@ -78,11 +79,12 @@ pub fn op_webgpu_render_pass_set_scissor_rect( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_blend_constant( state: &mut OpState, - render_pass_rid: ResourceId, - color: wgpu_types::Color, + #[smi] render_pass_rid: ResourceId, + #[serde] color: wgpu_types::Color, ) -> Result { let render_pass_resource = state .resource_table @@ -96,10 +98,11 @@ pub fn op_webgpu_render_pass_set_blend_constant( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_stencil_reference( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, reference: u32, ) -> Result { let render_pass_resource = state @@ -114,10 +117,11 @@ pub fn op_webgpu_render_pass_set_stencil_reference( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_begin_occlusion_query( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, query_index: u32, ) -> Result { let render_pass_resource = state @@ -132,10 +136,11 @@ pub fn op_webgpu_render_pass_begin_occlusion_query( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_end_occlusion_query( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, ) -> Result { let render_pass_resource = state .resource_table @@ -148,73 +153,12 @@ pub fn op_webgpu_render_pass_end_occlusion_query( Ok(WebGpuResult::empty()) } -#[op] -pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( - state: &mut OpState, - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -) -> Result { - let render_pass_resource = state - .resource_table - .get::(render_pass_rid)?; - let query_set_resource = state - .resource_table - .get::(query_set)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.1, - query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[op] -pub fn op_webgpu_render_pass_end_pipeline_statistics_query( - state: &mut OpState, - render_pass_rid: ResourceId, -) -> Result { - let render_pass_resource = state - .resource_table - .get::(render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[op] -pub fn op_webgpu_render_pass_write_timestamp( - state: &mut OpState, - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -) -> Result { - let render_pass_resource = state - .resource_table - .get::(render_pass_rid)?; - let query_set_resource = state - .resource_table - .get::(query_set)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_write_timestamp( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.1, - query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_execute_bundles( state: &mut OpState, - render_pass_rid: ResourceId, - bundles: Vec, + #[smi] render_pass_rid: ResourceId, + #[serde] bundles: Vec, ) -> Result { let bundles = bundles .iter() @@ -243,11 +187,12 @@ pub fn op_webgpu_render_pass_execute_bundles( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_end( state: &mut OpState, - command_encoder_rid: ResourceId, - render_pass_rid: ResourceId, + #[smi] command_encoder_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, ) -> Result { let command_encoder_resource = state @@ -263,15 +208,16 @@ pub fn op_webgpu_render_pass_end( gfx_ok!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_bind_group( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, index: u32, bind_group: u32, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, + #[buffer] dynamic_offsets_data: &[u32], + #[number] dynamic_offsets_data_start: usize, + #[number] dynamic_offsets_data_length: usize, ) -> Result { let bind_group_resource = state .resource_table @@ -280,14 +226,6 @@ pub fn op_webgpu_render_pass_set_bind_group( .resource_table .get::(render_pass_rid)?; - // Align the data - assert_eq!(dynamic_offsets_data_start % std::mem::size_of::(), 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = unsafe { dynamic_offsets_data.align_to::() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - let start = dynamic_offsets_data_start; let len = dynamic_offsets_data_length; @@ -312,11 +250,12 @@ pub fn op_webgpu_render_pass_set_bind_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_push_debug_group( state: &mut OpState, - render_pass_rid: ResourceId, - group_label: String, + #[smi] render_pass_rid: ResourceId, + #[string] group_label: &str, ) -> Result { let render_pass_resource = state .resource_table @@ -336,10 +275,11 @@ pub fn op_webgpu_render_pass_push_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_pop_debug_group( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, ) -> Result { let render_pass_resource = state .resource_table @@ -352,11 +292,12 @@ pub fn op_webgpu_render_pass_pop_debug_group( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_insert_debug_marker( state: &mut OpState, - render_pass_rid: ResourceId, - marker_label: String, + #[smi] render_pass_rid: ResourceId, + #[string] marker_label: &str, ) -> Result { let render_pass_resource = state .resource_table @@ -376,10 +317,11 @@ pub fn op_webgpu_render_pass_insert_debug_marker( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_pipeline( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, pipeline: u32, ) -> Result { let render_pipeline_resource = state @@ -397,14 +339,15 @@ pub fn op_webgpu_render_pass_set_pipeline( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_index_buffer( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, buffer: u32, - index_format: wgpu_types::IndexFormat, - offset: u64, - size: Option, + #[serde] index_format: wgpu_types::IndexFormat, + #[number] offset: u64, + #[number] size: Option, ) -> Result { let buffer_resource = state .resource_table @@ -432,14 +375,15 @@ pub fn op_webgpu_render_pass_set_index_buffer( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_set_vertex_buffer( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, slot: u32, buffer: u32, - offset: u64, - size: Option, + #[number] offset: u64, + #[number] size: Option, ) -> Result { let buffer_resource = state .resource_table @@ -468,10 +412,11 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_draw( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, vertex_count: u32, instance_count: u32, first_vertex: u32, @@ -492,10 +437,11 @@ pub fn op_webgpu_render_pass_draw( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_draw_indexed( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, index_count: u32, instance_count: u32, first_index: u32, @@ -518,12 +464,13 @@ pub fn op_webgpu_render_pass_draw_indexed( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_draw_indirect( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, indirect_buffer: u32, - indirect_offset: u64, + #[number] indirect_offset: u64, ) -> Result { let buffer_resource = state .resource_table @@ -541,12 +488,13 @@ pub fn op_webgpu_render_pass_draw_indirect( Ok(WebGpuResult::empty()) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_render_pass_draw_indexed_indirect( state: &mut OpState, - render_pass_rid: ResourceId, + #[smi] render_pass_rid: ResourceId, indirect_buffer: u32, - indirect_offset: u64, + #[number] indirect_offset: u64, ) -> Result { let buffer_resource = state .resource_table diff --git a/deno_webgpu/sampler.rs b/deno_webgpu/sampler.rs index d064ba2ebe..6f9b66ad4d 100644 --- a/deno_webgpu/sampler.rs +++ b/deno_webgpu/sampler.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -30,7 +30,7 @@ impl Resource for WebGpuSampler { #[serde(rename_all = "camelCase")] pub struct CreateSamplerArgs { device_rid: ResourceId, - label: Option, + label: String, address_mode_u: wgpu_types::AddressMode, address_mode_v: wgpu_types::AddressMode, address_mode_w: wgpu_types::AddressMode, @@ -43,10 +43,11 @@ pub struct CreateSamplerArgs { max_anisotropy: u16, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_sampler( state: &mut OpState, - args: CreateSamplerArgs, + #[serde] args: CreateSamplerArgs, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -55,7 +56,7 @@ pub fn op_webgpu_create_sampler( let device = device_resource.1; let descriptor = wgpu_core::resource::SamplerDescriptor { - label: args.label.map(Cow::from), + label: Some(Cow::Owned(args.label)), address_modes: [ args.address_mode_u, args.address_mode_v, diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index fb4f316926..f7cce24281 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -25,12 +25,13 @@ impl Resource for WebGpuShaderModule { } } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_shader_module( state: &mut OpState, - device_rid: ResourceId, - label: Option, - code: String, + #[smi] device_rid: ResourceId, + #[string] label: Cow, + #[string] code: Cow, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -38,10 +39,10 @@ pub fn op_webgpu_create_shader_module( .get::(device_rid)?; let device = device_resource.1; - let source = wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::from(code)); + let source = wgpu_core::pipeline::ShaderModuleSource::Wgsl(code); let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { - label: label.map(Cow::from), + label: Some(label), shader_bound_checks: wgpu_types::ShaderBoundChecks::default(), }; diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 8f797f12a5..1ac9d8704d 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -2,7 +2,7 @@ use super::WebGpuResult; use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -51,10 +51,11 @@ pub struct SurfaceConfigureArgs { view_formats: Vec, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_surface_configure( state: &mut OpState, - args: SurfaceConfigureArgs, + #[serde] args: SurfaceConfigureArgs, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -81,11 +82,12 @@ pub fn op_webgpu_surface_configure( Ok(WebGpuResult::maybe_err(err)) } -#[op] +#[op2] +#[serde] pub fn op_webgpu_surface_get_current_texture( state: &mut OpState, - device_rid: ResourceId, - surface_rid: ResourceId, + #[smi] device_rid: ResourceId, + #[smi] surface_rid: ResourceId, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -111,11 +113,11 @@ pub fn op_webgpu_surface_get_current_texture( } } -#[op] +#[op2(fast)] pub fn op_webgpu_surface_present( state: &mut OpState, - device_rid: ResourceId, - surface_rid: ResourceId, + #[smi] device_rid: ResourceId, + #[smi] surface_rid: ResourceId, ) -> Result<(), AnyError> { let instance = state.borrow::(); let device_resource = state diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index 92c8457071..5eadd5b3c2 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -1,7 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use deno_core::error::AnyError; -use deno_core::op; +use deno_core::op2; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -48,7 +48,7 @@ impl Resource for WebGpuTextureView { #[serde(rename_all = "camelCase")] pub struct CreateTextureArgs { device_rid: ResourceId, - label: Option, + label: String, size: wgpu_types::Extent3d, mip_level_count: u32, sample_count: u32, @@ -58,10 +58,11 @@ pub struct CreateTextureArgs { view_formats: Vec, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_texture( state: &mut OpState, - args: CreateTextureArgs, + #[serde] args: CreateTextureArgs, ) -> Result { let instance = state.borrow::(); let device_resource = state @@ -70,7 +71,7 @@ pub fn op_webgpu_create_texture( let device = device_resource.1; let descriptor = wgpu_core::resource::TextureDescriptor { - label: args.label.map(Cow::from), + label: Some(Cow::Owned(args.label)), size: args.size, mip_level_count: args.mip_level_count, sample_count: args.sample_count, @@ -99,17 +100,18 @@ pub fn op_webgpu_create_texture( #[serde(rename_all = "camelCase")] pub struct CreateTextureViewArgs { texture_rid: ResourceId, - label: Option, + label: String, format: Option, dimension: Option, #[serde(flatten)] range: wgpu_types::ImageSubresourceRange, } -#[op] +#[op2] +#[serde] pub fn op_webgpu_create_texture_view( state: &mut OpState, - args: CreateTextureViewArgs, + #[serde] args: CreateTextureViewArgs, ) -> Result { let instance = state.borrow::(); let texture_resource = state @@ -118,7 +120,7 @@ pub fn op_webgpu_create_texture_view( let texture = texture_resource.id; let descriptor = wgpu_core::resource::TextureViewDescriptor { - label: args.label.map(Cow::from), + label: Some(Cow::Owned(args.label)), format: args.format, dimension: args.dimension, range: args.range, diff --git a/deno_webgpu/webgpu.idl b/deno_webgpu/webgpu.idl index f2fea59c9f..59b0547db4 100644 --- a/deno_webgpu/webgpu.idl +++ b/deno_webgpu/webgpu.idl @@ -3,7 +3,7 @@ interface mixin GPUObjectBase { }; dictionary GPUObjectDescriptorBase { - USVString label; + USVString label = ""; }; [Exposed=(Window, DedicatedWorker), SecureContext] @@ -563,7 +563,8 @@ interface GPUPipelineLayout { }; GPUPipelineLayout includes GPUObjectBase; -dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase { +dictionary GPUPipelineLayoutDescriptor + : GPUObjectDescriptorBase { required sequence bindGroupLayouts; }; @@ -572,7 +573,8 @@ interface GPUShaderModule { }; GPUShaderModule includes GPUObjectBase; -dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { +dictionary GPUShaderModuleDescriptor + : GPUObjectDescriptorBase { required USVString code; }; @@ -935,11 +937,6 @@ interface GPUComputePassEncoder { undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1); undefined dispatchWorkgroupsIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); - undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); - undefined endPipelineStatisticsQuery(); - - undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); - undefined end(); }; GPUComputePassEncoder includes GPUObjectBase; @@ -947,8 +944,15 @@ GPUComputePassEncoder includes GPUCommandsMixin; GPUComputePassEncoder includes GPUDebugCommandsMixin; GPUComputePassEncoder includes GPUBindingCommandsMixin; +dictionary GPUComputePassTimestampWrites { + required GPUQuerySet querySet; + GPUSize32 beginningOfPassWriteIndex; + GPUSize32 endOfPassWriteIndex; +}; + dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase { + GPUComputePassTimestampWrites timestampWrites; }; [Exposed=(Window, DedicatedWorker), SecureContext] @@ -963,10 +967,8 @@ interface GPURenderPassEncoder { undefined setBlendConstant(GPUColor color); undefined setStencilReference(GPUStencilValue reference); - undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); - undefined endPipelineStatisticsQuery(); - - undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); + undefined beginOcclusionQuery(GPUSize32 queryIndex); + undefined endOcclusionQuery(); undefined executeBundles(sequence bundles); undefined end(); @@ -977,11 +979,18 @@ GPURenderPassEncoder includes GPUDebugCommandsMixin; GPURenderPassEncoder includes GPUBindingCommandsMixin; GPURenderPassEncoder includes GPURenderCommandsMixin; +dictionary GPURenderPassTimestampWrites { + required GPUQuerySet querySet; + GPUSize32 beginningOfPassWriteIndex; + GPUSize32 endOfPassWriteIndex; +}; + dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase { required sequence colorAttachments; GPURenderPassDepthStencilAttachment depthStencilAttachment; GPUQuerySet occlusionQuerySet; + GPURenderPassTimestampWrites timestampWrites; }; dictionary GPURenderPassColorAttachment { @@ -1100,23 +1109,13 @@ 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", -}; - [Exposed=(Window, DedicatedWorker), SecureContext] interface GPUCanvasContext { readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas; diff --git a/player/tests/data/clear-buffer-texture.ron b/player/tests/data/clear-buffer-texture.ron index c6879e31da..39b541cd22 100644 --- a/player/tests/data/clear-buffer-texture.ron +++ b/player/tests/data/clear-buffer-texture.ron @@ -85,10 +85,10 @@ dst: Id(0, 1, Empty), subresource_range: ImageSubresourceRange( aspect: all, - base_mip_level: 0, - mip_level_count: None, - base_array_layer: 0, - array_layer_count: None, + baseMipLevel: 0, + mipLevelCount: None, + baseArrayLayer: 0, + arrayLayerCount: None, ), ), CopyTextureToBuffer( diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 03d64db162..e2a6039dba 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -5,6 +5,6 @@ # to the user in the error, instead of "error: invalid channel name '[toolchain]'". [toolchain] -channel = "1.70" +channel = "1.70" # Needed for deno & cts_runner. Firefox's MSRV is 1.65 components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 26cf8ccbc0..3352e58eff 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6147,6 +6147,7 @@ impl ImageCopyTextureTagged { #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ImageSubresourceRange { /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA]. ///