From bd5d445da98435d03e2f6a6f6d5478ff623bd714 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Mon, 24 Jan 2022 23:47:05 +0100 Subject: [PATCH] chore: re-enable wgpu_sync (#13453) --- Cargo.lock | 87 +- cli/build.rs | 9 +- {ext/webgpu => cli/dts}/lib.deno_webgpu.d.ts | 62 +- .../testdata/webgpu_computepass_shader.wgsl | 5 +- cli/tests/unit/webgpu_test.ts | 5 +- ext/webgpu/01_webgpu.js | 49 +- ext/webgpu/02_idl_types.js | 69 +- ext/webgpu/Cargo.toml | 15 +- ext/webgpu/LICENSE.md | 2 +- ext/webgpu/pipeline.rs | 791 ------------------ ext/webgpu/sampler.rs | 132 --- ext/webgpu/{ => src}/binding.rs | 48 +- ext/webgpu/{ => src}/buffer.rs | 0 ext/webgpu/{ => src}/bundle.rs | 16 +- ext/webgpu/{ => src}/command_encoder.rs | 126 ++- ext/webgpu/{ => src}/compute_pass.rs | 12 +- ext/webgpu/{ => src}/error.rs | 7 + ext/webgpu/{ => src}/lib.rs | 414 ++++----- ext/webgpu/{ => src}/queue.rs | 8 +- ext/webgpu/{ => src}/render_pass.rs | 36 +- ext/webgpu/{ => src}/shader.rs | 1 + ext/webgpu/texture.rs | 419 ---------- ext/webgpu/webgpu.idl | 187 +++-- tools/README.md | 13 + tools/util.js | 2 +- tools/wgpu_sync.js | 119 +++ 26 files changed, 734 insertions(+), 1900 deletions(-) rename {ext/webgpu => cli/dts}/lib.deno_webgpu.d.ts (95%) delete mode 100644 ext/webgpu/pipeline.rs delete mode 100644 ext/webgpu/sampler.rs rename ext/webgpu/{ => src}/binding.rs (88%) rename ext/webgpu/{ => src}/buffer.rs (100%) rename ext/webgpu/{ => src}/bundle.rs (97%) rename ext/webgpu/{ => src}/command_encoder.rs (89%) rename ext/webgpu/{ => src}/compute_pass.rs (98%) rename ext/webgpu/{ => src}/error.rs (97%) rename ext/webgpu/{ => src}/lib.rs (68%) rename ext/webgpu/{ => src}/queue.rs (96%) rename ext/webgpu/{ => src}/render_pass.rs (96%) rename ext/webgpu/{ => src}/shader.rs (95%) delete mode 100644 ext/webgpu/texture.rs create mode 100755 tools/wgpu_sync.js diff --git a/Cargo.lock b/Cargo.lock index ef64b823f5..a7dc96e322 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "ash" -version = "0.33.3+1.2.191" +version = "0.34.0+1.2.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219" +checksum = "b0f780da53d0063880d45554306489f09dd8d1bda47688b4a57bc579119356df" dependencies = [ "libloading", ] @@ -283,6 +283,16 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitflags_serde_shim" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25c3d626f0280ec39b33a6fc5c6c1067432b4c41e94aee40ded197a6649bf025" +dependencies = [ + "bitflags", + "serde", +] + [[package]] name = "block" version = "0.1.6" @@ -1430,12 +1440,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" -[[package]] -name = "fixedbitset" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" - [[package]] name = "flaky_test" version = "0.1.0" @@ -1799,6 +1803,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + [[package]] name = "hmac" version = "0.11.0" @@ -2360,17 +2370,18 @@ dependencies = [ [[package]] name = "naga" -version = "0.6.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5859e55c51da10b98e7a73068e0a0c5da7bbcae4fc38f86043d0c6d1b917cf" +checksum = "22c5cfe6dbc4ae14962316265a931fbb89b892c5ed6a4a61d7fe4e9f58c0bf94" dependencies = [ "bit-set", "bitflags", "codespan-reporting", - "fxhash", + "hexf-parse", + "indexmap", "log", "num-traits", - "petgraph 0.6.0", + "rustc-hash", "serde", "spirv", "thiserror", @@ -2662,17 +2673,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" dependencies = [ - "fixedbitset 0.2.0", - "indexmap", -] - -[[package]] -name = "petgraph" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" -dependencies = [ - "fixedbitset 0.4.1", + "fixedbitset", "indexmap", ] @@ -3040,16 +3041,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" -[[package]] -name = "raw-window-handle" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" -dependencies = [ - "libc", - "raw-window-handle 0.4.2", -] - [[package]] name = "raw-window-handle" version = "0.4.2" @@ -3185,9 +3176,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4" +checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" dependencies = [ "base64 0.13.0", "bitflags", @@ -3732,7 +3723,7 @@ dependencies = [ "is-macro", "once_cell", "parking_lot", - "petgraph 0.5.1", + "petgraph", "radix_fmt", "relative-path", "retain_mut", @@ -4083,7 +4074,7 @@ checksum = "1d53bbcbb4b055c547f283af1f84211f425b95ac59e02d8b70c94b8a63a4704f" dependencies = [ "ahash", "indexmap", - "petgraph 0.5.1", + "petgraph", "swc_common", ] @@ -4095,7 +4086,7 @@ checksum = "83b42a8b13068dd90dec954ec44576d5922914687bc34277f3b0f8d0bbeb4e83" dependencies = [ "ahash", "auto_impl", - "petgraph 0.5.1", + "petgraph", "swc_fast_graph", "tracing", ] @@ -4905,13 +4896,14 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.10.4" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f963c62473a36e3cef6c58181f2ed6d0d38d2043d970dbed46cb197190090c99" +checksum = "c4688c000eb841ca55f7b35db659b78d6e1cd77d7caf8fb929f4e181f754047d" dependencies = [ "arrayvec 0.7.2", "bitflags", "cfg_aliases", + "codespan-reporting", "copyless", "fxhash", "log", @@ -4928,9 +4920,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.10.7" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27cd894b17bff1958ee93da1cc991fd64bf99667746d4bd2a7403855f4d37fe2" +checksum = "62fa524903bf336b51a399f0d586f3c30af94101149588678ef147c30be89e53" dependencies = [ "arrayvec 0.7.2", "ash", @@ -4945,6 +4937,7 @@ dependencies = [ "gpu-alloc", "gpu-descriptor", "inplace_it", + "js-sys", "khronos-egl", "libloading", "log", @@ -4952,21 +4945,25 @@ dependencies = [ "naga", "objc", "parking_lot", + "profiling", "range-alloc", - "raw-window-handle 0.3.4", + "raw-window-handle", "renderdoc-sys", "thiserror", + "wasm-bindgen", + "web-sys", "wgpu-types", "winapi 0.3.9", ] [[package]] name = "wgpu-types" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25feb2fbf24ab3219a9f10890ceb8e1ef02b13314ed89d64a9ae99dcad883e18" +checksum = "549533d9e1cdd4b4cda7718d33ff500fc4c34b5467b71d76b547ae0324f3b2a2" dependencies = [ "bitflags", + "bitflags_serde_shim", "serde", ] diff --git a/cli/build.rs b/cli/build.rs index 87c6884804..2daeffa0d7 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -82,7 +82,7 @@ fn create_compiler_snapshot( op_crate_libs.insert("deno.url", deno_url::get_declaration()); op_crate_libs.insert("deno.web", deno_web::get_declaration()); op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration()); - op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration()); + op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration()); op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration()); op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration()); op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration()); @@ -322,7 +322,7 @@ fn main() { ); println!( "cargo:rustc-env=DENO_WEBGPU_LIB_PATH={}", - deno_webgpu::get_declaration().display() + deno_webgpu_get_declaration().display() ); println!( "cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}", @@ -369,6 +369,11 @@ fn main() { } } +fn deno_webgpu_get_declaration() -> PathBuf { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + manifest_dir.join("dts").join("lib.deno_webgpu.d.ts") +} + fn get_js_files(d: &str) -> Vec { let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let mut js_files = std::fs::read_dir(d) diff --git a/ext/webgpu/lib.deno_webgpu.d.ts b/cli/dts/lib.deno_webgpu.d.ts similarity index 95% rename from ext/webgpu/lib.deno_webgpu.d.ts rename to cli/dts/lib.deno_webgpu.d.ts index 6d480d3c3a..1337b3f5e2 100644 --- a/ext/webgpu/lib.deno_webgpu.d.ts +++ b/cli/dts/lib.deno_webgpu.d.ts @@ -92,12 +92,15 @@ declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase { } declare type GPUFeatureName = - | "depth-clamping" + | "depth-clip-control" | "depth24unorm-stencil8" | "depth32float-stencil8" | "pipeline-statistics-query" | "texture-compression-bc" + | "texture-compression-etc2" + | "texture-compression-astc" | "timestamp-query" + | "indirect-first-instance" // extended from spec | "mappable-primary-buffers" | "sampled-texture-binding-array" @@ -108,9 +111,6 @@ declare type GPUFeatureName = | "multi-draw-indirect-count" | "push-constants" | "address-mode-clamp-to-border" - | "non-fill-polygon-mode" - | "texture-compression-etc2" - | "texture-compression-astc-ldr" | "texture-adapter-specific-format-features" | "shader-float64" | "vertex-attribute-64bit"; @@ -314,6 +314,44 @@ declare type GPUTextureFormat = | "bc6h-rgb-float" | "bc7-rgba-unorm" | "bc7-rgba-unorm-srgb" + | "etc2-rgb8unorm" + | "etc2-rgb8unorm-srgb" + | "etc2-rgb8a1unorm" + | "etc2-rgb8a1unorm-srgb" + | "etc2-rgba8unorm" + | "etc2-rgba8unorm-srgb" + | "eac-r11unorm" + | "eac-r11snorm" + | "eac-rg11unorm" + | "eac-rg11snorm" + | "astc-4x4-unorm" + | "astc-4x4-unorm-srgb" + | "astc-5x4-unorm" + | "astc-5x4-unorm-srgb" + | "astc-5x5-unorm" + | "astc-5x5-unorm-srgb" + | "astc-6x5-unorm" + | "astc-6x5-unorm-srgb" + | "astc-6x6-unorm" + | "astc-6x6-unorm-srgb" + | "astc-8x5-unorm" + | "astc-8x5-unorm-srgb" + | "astc-8x6-unorm" + | "astc-8x6-unorm-srgb" + | "astc-8x8-unorm" + | "astc-8x8-unorm-srgb" + | "astc-10x5-unorm" + | "astc-10x5-unorm-srgb" + | "astc-10x6-unorm" + | "astc-10x6-unorm-srgb" + | "astc-10x8-unorm" + | "astc-10x8-unorm-srgb" + | "astc-10x10-unorm" + | "astc-10x10-unorm-srgb" + | "astc-12x10-unorm" + | "astc-12x10-unorm-srgb" + | "astc-12x12-unorm" + | "astc-12x12-unorm-srgb" | "depth24unorm-stencil8" | "depth32float-stencil8"; @@ -519,7 +557,7 @@ declare interface GPUPrimitiveState { stripIndexFormat?: GPUIndexFormat; frontFace?: GPUFrontFace; cullMode?: GPUCullMode; - clampDepth?: boolean; + unclippedDepth?: boolean; } declare type GPUFrontFace = "ccw" | "cw"; @@ -558,9 +596,9 @@ declare class GPUColorWrite { } declare interface GPUBlendComponent { + operation: GPUBlendOperation; srcFactor: GPUBlendFactor; dstFactor: GPUBlendFactor; - operation: GPUBlendOperation; } declare type GPUBlendFactor = @@ -673,8 +711,6 @@ declare interface GPUVertexAttribute { declare class GPUCommandBuffer implements GPUObjectBase { label: string | null; - - readonly executionTime: Promise; } declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {} @@ -713,6 +749,12 @@ declare class GPUCommandEncoder implements GPUObjectBase { copySize: GPUExtent3D, ): undefined; + clearBuffer( + destination: GPUBuffer, + destinationOffset: number, + size: number, + ): undefined; + pushDebugGroup(groupLabel: string): undefined; popDebugGroup(): undefined; insertDebugMarker(markerLabel: string): undefined; @@ -730,9 +772,7 @@ declare class GPUCommandEncoder implements GPUObjectBase { finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer; } -declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase { - measureExecutionTime?: boolean; -} +declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {} declare interface GPUImageDataLayout { offset?: number; diff --git a/cli/tests/testdata/webgpu_computepass_shader.wgsl b/cli/tests/testdata/webgpu_computepass_shader.wgsl index 9fc79eeba6..df541aff5e 100644 --- a/cli/tests/testdata/webgpu_computepass_shader.wgsl +++ b/cli/tests/testdata/webgpu_computepass_shader.wgsl @@ -1,9 +1,10 @@ -[[block]] struct PrimeIndices { data: [[stride(4)]] array; }; // this is used as both input and output for convenience + [[group(0), binding(0)]] var v_indices: PrimeIndices; + // The Collatz Conjecture states that for any integer n: // If n is even, n = n/2 // If n is odd, n = 3n+1 @@ -25,12 +26,14 @@ fn collatz_iterations(n_base: u32) -> u32{ if (n >= 1431655765u) { // 0x55555555u return 4294967295u; // 0xffffffffu } + n = 3u * n + 1u; } i = i + 1u; } return i; } + [[stage(compute), workgroup_size(1)]] fn main([[builtin(global_invocation_id)]] global_id: vec3) { v_indices.data[global_id.x] = collatz_iterations(v_indices.data[global_id.x]); diff --git a/cli/tests/unit/webgpu_test.ts b/cli/tests/unit/webgpu_test.ts index 1d54d7b026..b1b3b1ecbc 100644 --- a/cli/tests/unit/webgpu_test.ts +++ b/cli/tests/unit/webgpu_test.ts @@ -33,13 +33,14 @@ Deno.test({ 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/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js index f1d3eb120a..45d910c1a2 100644 --- a/ext/webgpu/01_webgpu.js +++ b/ext/webgpu/01_webgpu.js @@ -3060,6 +3060,48 @@ device.pushError(err); } + /** + * @param {GPUBuffer} destination + * @param {GPUSize64} destinationOffset + * @param {GPUSize64} size + */ + clearBuffer(destination, destinationOffset, size) { + webidl.assertBranded(this, GPUCommandEncoder); + const prefix = "Failed to execute 'clearBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + destination = webidl.converters.GPUBuffer(destination, { + prefix, + context: "Argument 1", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 2", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const destinationRid = assertResource(destination, { + prefix, + context: "Argument 1", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_clear_buffer", + { + commandEncoderRid, + destinationRid, + destinationOffset, + size, + }, + ); + device.pushError(err); + } + /** * @param {string} groupLabel */ @@ -3203,7 +3245,7 @@ prefix, context: "Argument 3", }); - destination = webidl.converters.GPUQuerySet(destination, { + destination = webidl.converters.GPUBuffer(destination, { prefix, context: "Argument 4", }); @@ -4527,15 +4569,10 @@ webidl.illegalConstructor(); } - get executionTime() { - throw new Error("Not yet implemented"); - } - [SymbolFor("Deno.privateCustomInspect")](inspect) { return `${this.constructor.name} ${ inspect({ label: this.label, - // TODO(crowlKats): executionTime }) }`; } diff --git a/ext/webgpu/02_idl_types.js b/ext/webgpu/02_idl_types.js index 3c49c18884..bc92bebab0 100644 --- a/ext/webgpu/02_idl_types.js +++ b/ext/webgpu/02_idl_types.js @@ -111,28 +111,35 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( "GPUFeatureName", [ - "depth-clamping", + "depth-clip-control", "depth24unorm-stencil8", "depth32float-stencil8", "pipeline-statistics-query", "texture-compression-bc", + "texture-compression-etc2", + "texture-compression-astc", "timestamp-query", + "indirect-first-instance", // extended from spec "mappable-primary-buffers", - "sampled-texture-binding-array", - "sampled-texture-array-dynamic-indexing", - "sampled-texture-array-non-uniform-indexing", + "texture-binding-array", + "buffer-binding-array", + "storage-resource-binding-array", + "sampled-texture-and-storage-buffer-array-non-uniform-indexing", + "uniform-buffer-and-storage-buffer-texture-non-uniform-indexing", "unsized-binding-array", "multi-draw-indirect", "multi-draw-indirect-count", "push-constants", "address-mode-clamp-to-border", - "non-fill-polygon-mode", - "texture-compression-etc2", - "texture-compression-astc-ldr", "texture-adapter-specific-format-features", "shader-float64", "vertex-attribute-64bit", + "conservative-rasterization", + "vertex-writable-storage", + "clear-commands", + "spirv-shader-passthrough", + "shader-primitive-index", ], ); @@ -348,6 +355,44 @@ "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", + "etc2-rgb8unorm", + "etc2-rgb8unorm-srgb", + "etc2-rgb8a1unorm", + "etc2-rgb8a1unorm-srgb", + "etc2-rgba8unorm", + "etc2-rgba8unorm-srgb", + "eac-r11unorm", + "eac-r11snorm", + "eac-rg11unorm", + "eac-rg11snorm", + "astc-4x4-unorm", + "astc-4x4-unorm-srgb", + "astc-5x4-unorm", + "astc-5x4-unorm-srgb", + "astc-5x5-unorm", + "astc-5x5-unorm-srgb", + "astc-6x5-unorm", + "astc-6x5-unorm-srgb", + "astc-6x6-unorm", + "astc-6x6-unorm-srgb", + "astc-8x5-unorm", + "astc-8x5-unorm-srgb", + "astc-8x6-unorm", + "astc-8x6-unorm-srgb", + "astc-8x8-unorm", + "astc-8x8-unorm-srgb", + "astc-10x5-unorm", + "astc-10x5-unorm-srgb", + "astc-10x6-unorm", + "astc-10x6-unorm-srgb", + "astc-10x8-unorm", + "astc-10x8-unorm-srgb", + "astc-10x10-unorm", + "astc-10x10-unorm-srgb", + "astc-12x10-unorm", + "astc-12x10-unorm-srgb", + "astc-12x12-unorm", + "astc-12x12-unorm-srgb", "depth24unorm-stencil8", "depth32float-stencil8", ], @@ -1131,7 +1176,7 @@ defaultValue: "none", }, { - key: "clampDepth", + key: "unclippedDepth", converter: webidl.converters["boolean"], defaultValue: false, }, @@ -1458,13 +1503,7 @@ ); // DICTIONARY: GPUCommandEncoderDescriptor - const dictMembersGPUCommandEncoderDescriptor = [ - { - key: "measureExecutionTime", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; + const dictMembersGPUCommandEncoderDescriptor = []; webidl.converters["GPUCommandEncoderDescriptor"] = webidl .createDictionaryConverter( "GPUCommandEncoderDescriptor", diff --git a/ext/webgpu/Cargo.toml b/ext/webgpu/Cargo.toml index f2379c8408..050fb9e4ff 100644 --- a/ext/webgpu/Cargo.toml +++ b/ext/webgpu/Cargo.toml @@ -1,4 +1,4 @@ -# Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. [package] name = "deno_webgpu" @@ -7,15 +7,12 @@ authors = ["the Deno authors"] edition = "2021" license = "MIT" readme = "README.md" -repository = "https://github.com/denoland/deno" +repository = "https://github.com/gfx-rs/wgpu" description = "WebGPU implementation for Deno" -[lib] -path = "lib.rs" - [dependencies] deno_core = { version = "0.116.0", path = "../../core" } -serde = { version = "1.0.129", features = ["derive"] } -tokio = { version = "1.10.1", features = ["full"] } -wgpu-core = { version = "0.10.1", features = ["trace"] } -wgpu-types = "0.10.0" +serde = { version = "1.0", features = ["derive"] } +tokio = { version = "1.10", features = ["full"] } +wgpu-core = { version = "0.12", features = ["trace", "replay", "serde"] } +wgpu-types = { version = "0.12", features = ["trace", "replay", "serde"] } diff --git a/ext/webgpu/LICENSE.md b/ext/webgpu/LICENSE.md index cfc3a5226e..bbf190721d 100644 --- a/ext/webgpu/LICENSE.md +++ b/ext/webgpu/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright 2018-2022 the Deno authors +Copyright 2018-2021 the Deno authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/ext/webgpu/pipeline.rs b/ext/webgpu/pipeline.rs deleted file mode 100644 index 1d22bdba0d..0000000000 --- a/ext/webgpu/pipeline.rs +++ /dev/null @@ -1,791 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; - -use crate::sampler::GpuCompareFunction; -use crate::texture::GpuTextureFormat; - -use super::error::{WebGpuError, WebGpuResult}; - -const MAX_BIND_GROUPS: usize = 8; - -pub(crate) struct WebGpuPipelineLayout( - pub(crate) wgpu_core::id::PipelineLayoutId, -); -impl Resource for WebGpuPipelineLayout { - fn name(&self) -> Cow { - "webGPUPipelineLayout".into() - } -} - -pub(crate) struct WebGpuComputePipeline( - pub(crate) wgpu_core::id::ComputePipelineId, -); -impl Resource for WebGpuComputePipeline { - fn name(&self) -> Cow { - "webGPUComputePipeline".into() - } -} - -pub(crate) struct WebGpuRenderPipeline( - pub(crate) wgpu_core::id::RenderPipelineId, -); -impl Resource for WebGpuRenderPipeline { - fn name(&self) -> Cow { - "webGPURenderPipeline".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuIndexFormat { - Uint16, - Uint32, -} - -impl From for wgpu_types::IndexFormat { - fn from(value: GpuIndexFormat) -> wgpu_types::IndexFormat { - match value { - GpuIndexFormat::Uint16 => wgpu_types::IndexFormat::Uint16, - GpuIndexFormat::Uint32 => wgpu_types::IndexFormat::Uint32, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GPUStencilOperation { - Keep, - Zero, - Replace, - Invert, - IncrementClamp, - DecrementClamp, - IncrementWrap, - DecrementWrap, -} - -impl From for wgpu_types::StencilOperation { - fn from(value: GPUStencilOperation) -> wgpu_types::StencilOperation { - match value { - GPUStencilOperation::Keep => wgpu_types::StencilOperation::Keep, - GPUStencilOperation::Zero => wgpu_types::StencilOperation::Zero, - GPUStencilOperation::Replace => wgpu_types::StencilOperation::Replace, - GPUStencilOperation::Invert => wgpu_types::StencilOperation::Invert, - GPUStencilOperation::IncrementClamp => { - wgpu_types::StencilOperation::IncrementClamp - } - GPUStencilOperation::DecrementClamp => { - wgpu_types::StencilOperation::DecrementClamp - } - GPUStencilOperation::IncrementWrap => { - wgpu_types::StencilOperation::IncrementWrap - } - GPUStencilOperation::DecrementWrap => { - wgpu_types::StencilOperation::DecrementWrap - } - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuBlendFactor { - Zero, - One, - Src, - OneMinusSrc, - SrcAlpha, - OneMinusSrcAlpha, - Dst, - OneMinusDst, - DstAlpha, - OneMinusDstAlpha, - SrcAlphaSaturated, - Constant, - OneMinusConstant, -} - -impl From for wgpu_types::BlendFactor { - fn from(value: GpuBlendFactor) -> wgpu_types::BlendFactor { - match value { - GpuBlendFactor::Zero => wgpu_types::BlendFactor::Zero, - GpuBlendFactor::One => wgpu_types::BlendFactor::One, - GpuBlendFactor::Src => wgpu_types::BlendFactor::Src, - GpuBlendFactor::OneMinusSrc => wgpu_types::BlendFactor::OneMinusSrc, - GpuBlendFactor::SrcAlpha => wgpu_types::BlendFactor::SrcAlpha, - GpuBlendFactor::OneMinusSrcAlpha => { - wgpu_types::BlendFactor::OneMinusSrcAlpha - } - GpuBlendFactor::Dst => wgpu_types::BlendFactor::Dst, - GpuBlendFactor::OneMinusDst => wgpu_types::BlendFactor::OneMinusDst, - GpuBlendFactor::DstAlpha => wgpu_types::BlendFactor::DstAlpha, - GpuBlendFactor::OneMinusDstAlpha => { - wgpu_types::BlendFactor::OneMinusDstAlpha - } - GpuBlendFactor::SrcAlphaSaturated => { - wgpu_types::BlendFactor::SrcAlphaSaturated - } - GpuBlendFactor::Constant => wgpu_types::BlendFactor::Constant, - GpuBlendFactor::OneMinusConstant => { - wgpu_types::BlendFactor::OneMinusConstant - } - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuBlendOperation { - Add, - Subtract, - ReverseSubtract, - Min, - Max, -} - -impl From for wgpu_types::BlendOperation { - fn from(value: GpuBlendOperation) -> wgpu_types::BlendOperation { - match value { - GpuBlendOperation::Add => wgpu_types::BlendOperation::Add, - GpuBlendOperation::Subtract => wgpu_types::BlendOperation::Subtract, - GpuBlendOperation::ReverseSubtract => { - wgpu_types::BlendOperation::ReverseSubtract - } - GpuBlendOperation::Min => wgpu_types::BlendOperation::Min, - GpuBlendOperation::Max => wgpu_types::BlendOperation::Max, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuPrimitiveTopology { - PointList, - LineList, - LineStrip, - TriangleList, - TriangleStrip, -} - -impl From for wgpu_types::PrimitiveTopology { - fn from(value: GpuPrimitiveTopology) -> wgpu_types::PrimitiveTopology { - match value { - GpuPrimitiveTopology::PointList => { - wgpu_types::PrimitiveTopology::PointList - } - GpuPrimitiveTopology::LineList => wgpu_types::PrimitiveTopology::LineList, - GpuPrimitiveTopology::LineStrip => { - wgpu_types::PrimitiveTopology::LineStrip - } - GpuPrimitiveTopology::TriangleList => { - wgpu_types::PrimitiveTopology::TriangleList - } - GpuPrimitiveTopology::TriangleStrip => { - wgpu_types::PrimitiveTopology::TriangleStrip - } - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuFrontFace { - Ccw, - Cw, -} - -impl From for wgpu_types::FrontFace { - fn from(value: GpuFrontFace) -> wgpu_types::FrontFace { - match value { - GpuFrontFace::Ccw => wgpu_types::FrontFace::Ccw, - GpuFrontFace::Cw => wgpu_types::FrontFace::Cw, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuCullMode { - None, - Front, - Back, -} - -impl From for Option { - fn from(value: GpuCullMode) -> Option { - match value { - GpuCullMode::None => None, - GpuCullMode::Front => Some(wgpu_types::Face::Front), - GpuCullMode::Back => Some(wgpu_types::Face::Back), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuProgrammableStage { - module: ResourceId, - entry_point: String, - // constants: HashMap -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateComputePipelineArgs { - device_rid: ResourceId, - label: Option, - layout: Option, - compute: GpuProgrammableStage, -} - -pub fn op_webgpu_create_compute_pipeline( - state: &mut OpState, - args: CreateComputePipelineArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(args.device_rid)?; - let device = device_resource.0; - - let pipeline_layout = if let Some(rid) = args.layout { - let id = state.resource_table.get::(rid)?; - Some(id.0) - } else { - None - }; - - let compute_shader_module_resource = - state - .resource_table - .get::(args.compute.module)?; - - let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: args.label.map(Cow::from), - layout: pipeline_layout, - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: compute_shader_module_resource.0, - entry_point: Cow::from(args.compute.entry_point), - // TODO(lucacasonato): support args.compute.constants - }, - }; - let implicit_pipelines = match args.layout { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS], - }), - }; - - let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuComputePipeline(compute_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePipelineGetBindGroupLayoutArgs { - compute_pipeline_rid: ResourceId, - index: u32, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PipelineLayout { - rid: ResourceId, - label: String, - err: Option, -} - -pub fn op_webgpu_compute_pipeline_get_bind_group_layout( - state: &mut OpState, - args: ComputePipelineGetBindGroupLayoutArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let compute_pipeline_resource = state - .resource_table - .get::(args.compute_pipeline_rid)?; - let compute_pipeline = compute_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuPrimitiveState { - topology: GpuPrimitiveTopology, - strip_index_format: Option, - front_face: GpuFrontFace, - cull_mode: GpuCullMode, - clamp_depth: bool, -} - -impl From for wgpu_types::PrimitiveState { - fn from(value: GpuPrimitiveState) -> wgpu_types::PrimitiveState { - wgpu_types::PrimitiveState { - topology: value.topology.into(), - strip_index_format: value.strip_index_format.map(Into::into), - front_face: value.front_face.into(), - cull_mode: value.cull_mode.into(), - clamp_depth: value.clamp_depth, - polygon_mode: Default::default(), // native-only - conservative: false, // native-only - } - } -} -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBlendComponent { - src_factor: GpuBlendFactor, - dst_factor: GpuBlendFactor, - operation: GpuBlendOperation, -} - -impl From for wgpu_types::BlendComponent { - fn from(component: GpuBlendComponent) -> Self { - wgpu_types::BlendComponent { - src_factor: component.src_factor.into(), - dst_factor: component.dst_factor.into(), - operation: component.operation.into(), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBlendState { - color: GpuBlendComponent, - alpha: GpuBlendComponent, -} - -impl From for wgpu_types::BlendState { - fn from(state: GpuBlendState) -> wgpu_types::BlendState { - wgpu_types::BlendState { - color: state.color.into(), - alpha: state.alpha.into(), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuColorTargetState { - format: GpuTextureFormat, - blend: Option, - write_mask: u32, -} - -impl TryFrom for wgpu_types::ColorTargetState { - type Error = AnyError; - fn try_from( - state: GpuColorTargetState, - ) -> Result { - Ok(wgpu_types::ColorTargetState { - format: state.format.try_into()?, - blend: state.blend.map(Into::into), - write_mask: wgpu_types::ColorWrites::from_bits_truncate(state.write_mask), - }) - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuStencilFaceState { - compare: GpuCompareFunction, - fail_op: GPUStencilOperation, - depth_fail_op: GPUStencilOperation, - pass_op: GPUStencilOperation, -} - -impl From for wgpu_types::StencilFaceState { - fn from(state: GpuStencilFaceState) -> Self { - wgpu_types::StencilFaceState { - compare: state.compare.into(), - fail_op: state.fail_op.into(), - depth_fail_op: state.depth_fail_op.into(), - pass_op: state.pass_op.into(), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuDepthStencilState { - format: GpuTextureFormat, - depth_write_enabled: bool, - depth_compare: GpuCompareFunction, - stencil_front: GpuStencilFaceState, - stencil_back: GpuStencilFaceState, - stencil_read_mask: u32, - stencil_write_mask: u32, - depth_bias: i32, - depth_bias_slope_scale: f32, - depth_bias_clamp: f32, -} - -impl TryFrom for wgpu_types::DepthStencilState { - type Error = AnyError; - fn try_from( - state: GpuDepthStencilState, - ) -> Result { - Ok(wgpu_types::DepthStencilState { - format: state.format.try_into()?, - depth_write_enabled: state.depth_write_enabled, - depth_compare: state.depth_compare.into(), - stencil: wgpu_types::StencilState { - front: state.stencil_front.into(), - back: state.stencil_back.into(), - read_mask: state.stencil_read_mask, - write_mask: state.stencil_write_mask, - }, - bias: wgpu_types::DepthBiasState { - constant: state.depth_bias, - slope_scale: state.depth_bias_slope_scale, - clamp: state.depth_bias_clamp, - }, - }) - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexAttribute { - format: GpuVertexFormat, - offset: u64, - shader_location: u32, -} - -impl From for wgpu_types::VertexAttribute { - fn from(attribute: GpuVertexAttribute) -> Self { - wgpu_types::VertexAttribute { - format: attribute.format.into(), - offset: attribute.offset, - shader_location: attribute.shader_location, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "lowercase")] -enum GpuVertexFormat { - Uint8x2, - Uint8x4, - Sint8x2, - Sint8x4, - Unorm8x2, - Unorm8x4, - Snorm8x2, - Snorm8x4, - Uint16x2, - Uint16x4, - Sint16x2, - Sint16x4, - Unorm16x2, - Unorm16x4, - Snorm16x2, - Snorm16x4, - Float16x2, - Float16x4, - Float32, - Float32x2, - Float32x3, - Float32x4, - Uint32, - Uint32x2, - Uint32x3, - Uint32x4, - Sint32, - Sint32x2, - Sint32x3, - Sint32x4, - Float64, - Float64x2, - Float64x3, - Float64x4, -} - -impl From for wgpu_types::VertexFormat { - fn from(vf: GpuVertexFormat) -> wgpu_types::VertexFormat { - use wgpu_types::VertexFormat; - match vf { - GpuVertexFormat::Uint8x2 => VertexFormat::Uint8x2, - GpuVertexFormat::Uint8x4 => VertexFormat::Uint8x4, - GpuVertexFormat::Sint8x2 => VertexFormat::Sint8x2, - GpuVertexFormat::Sint8x4 => VertexFormat::Sint8x4, - GpuVertexFormat::Unorm8x2 => VertexFormat::Unorm8x2, - GpuVertexFormat::Unorm8x4 => VertexFormat::Unorm8x4, - GpuVertexFormat::Snorm8x2 => VertexFormat::Snorm8x2, - GpuVertexFormat::Snorm8x4 => VertexFormat::Snorm8x4, - GpuVertexFormat::Uint16x2 => VertexFormat::Uint16x2, - GpuVertexFormat::Uint16x4 => VertexFormat::Uint16x4, - GpuVertexFormat::Sint16x2 => VertexFormat::Sint16x2, - GpuVertexFormat::Sint16x4 => VertexFormat::Sint16x4, - GpuVertexFormat::Unorm16x2 => VertexFormat::Unorm16x2, - GpuVertexFormat::Unorm16x4 => VertexFormat::Unorm16x4, - GpuVertexFormat::Snorm16x2 => VertexFormat::Snorm16x2, - GpuVertexFormat::Snorm16x4 => VertexFormat::Snorm16x4, - GpuVertexFormat::Float16x2 => VertexFormat::Float16x2, - GpuVertexFormat::Float16x4 => VertexFormat::Float16x4, - GpuVertexFormat::Float32 => VertexFormat::Float32, - GpuVertexFormat::Float32x2 => VertexFormat::Float32x2, - GpuVertexFormat::Float32x3 => VertexFormat::Float32x3, - GpuVertexFormat::Float32x4 => VertexFormat::Float32x4, - GpuVertexFormat::Uint32 => VertexFormat::Uint32, - GpuVertexFormat::Uint32x2 => VertexFormat::Uint32x2, - GpuVertexFormat::Uint32x3 => VertexFormat::Uint32x3, - GpuVertexFormat::Uint32x4 => VertexFormat::Uint32x4, - GpuVertexFormat::Sint32 => VertexFormat::Sint32, - GpuVertexFormat::Sint32x2 => VertexFormat::Sint32x2, - GpuVertexFormat::Sint32x3 => VertexFormat::Sint32x3, - GpuVertexFormat::Sint32x4 => VertexFormat::Sint32x4, - GpuVertexFormat::Float64 => VertexFormat::Float64, - GpuVertexFormat::Float64x2 => VertexFormat::Float64x2, - GpuVertexFormat::Float64x3 => VertexFormat::Float64x3, - GpuVertexFormat::Float64x4 => VertexFormat::Float64x4, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -enum GpuVertexStepMode { - Vertex, - Instance, -} - -impl From for wgpu_types::VertexStepMode { - fn from(vsm: GpuVertexStepMode) -> wgpu_types::VertexStepMode { - use wgpu_types::VertexStepMode; - match vsm { - GpuVertexStepMode::Vertex => VertexStepMode::Vertex, - GpuVertexStepMode::Instance => VertexStepMode::Instance, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexBufferLayout { - array_stride: u64, - step_mode: GpuVertexStepMode, - attributes: Vec, -} - -impl<'a> From - for wgpu_core::pipeline::VertexBufferLayout<'a> -{ - fn from( - layout: GpuVertexBufferLayout, - ) -> wgpu_core::pipeline::VertexBufferLayout<'a> { - wgpu_core::pipeline::VertexBufferLayout { - array_stride: layout.array_stride, - step_mode: layout.step_mode.into(), - attributes: Cow::Owned( - layout.attributes.into_iter().map(Into::into).collect(), - ), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexState { - module: ResourceId, - entry_point: String, - buffers: Vec>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuMultisampleState { - count: u32, - mask: u64, - alpha_to_coverage_enabled: bool, -} - -impl From for wgpu_types::MultisampleState { - fn from(gms: GpuMultisampleState) -> wgpu_types::MultisampleState { - wgpu_types::MultisampleState { - count: gms.count, - mask: gms.mask, - alpha_to_coverage_enabled: gms.alpha_to_coverage_enabled, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuFragmentState { - targets: Vec, - module: u32, - entry_point: String, - // TODO(lucacasonato): constants -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateRenderPipelineArgs { - device_rid: ResourceId, - label: Option, - layout: Option, - vertex: GpuVertexState, - primitive: GpuPrimitiveState, - depth_stencil: Option, - multisample: GpuMultisampleState, - fragment: Option, -} - -pub fn op_webgpu_create_render_pipeline( - state: &mut OpState, - args: CreateRenderPipelineArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(args.device_rid)?; - let device = device_resource.0; - - let layout = if let Some(rid) = args.layout { - let pipeline_layout_resource = - state.resource_table.get::(rid)?; - Some(pipeline_layout_resource.0) - } else { - None - }; - - let vertex_shader_module_resource = - state - .resource_table - .get::(args.vertex.module)?; - - let fragment = if let Some(fragment) = args.fragment { - let fragment_shader_module_resource = - state - .resource_table - .get::(fragment.module)?; - - let mut targets = Vec::with_capacity(fragment.targets.len()); - - for target in fragment.targets { - targets.push(target.try_into()?); - } - - Some(wgpu_core::pipeline::FragmentState { - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: fragment_shader_module_resource.0, - entry_point: Cow::from(fragment.entry_point), - }, - targets: Cow::from(targets), - }) - } else { - None - }; - - let vertex_buffers = args - .vertex - .buffers - .into_iter() - .flatten() - .map(Into::into) - .collect(); - - let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { - label: args.label.map(Cow::Owned), - layout, - vertex: wgpu_core::pipeline::VertexState { - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: vertex_shader_module_resource.0, - entry_point: Cow::Owned(args.vertex.entry_point), - }, - buffers: Cow::Owned(vertex_buffers), - }, - primitive: args.primitive.into(), - depth_stencil: args.depth_stencil.map(TryInto::try_into).transpose()?, - multisample: args.multisample.into(), - fragment, - }; - - let implicit_pipelines = match args.layout { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS], - }), - }; - - let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuRenderPipeline(render_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPipelineGetBindGroupLayoutArgs { - render_pipeline_rid: ResourceId, - index: u32, -} - -pub fn op_webgpu_render_pipeline_get_bind_group_layout( - state: &mut OpState, - args: RenderPipelineGetBindGroupLayoutArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let render_pipeline_resource = state - .resource_table - .get::(args.render_pipeline_rid)?; - let render_pipeline = render_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} diff --git a/ext/webgpu/sampler.rs b/ext/webgpu/sampler.rs deleted file mode 100644 index 23652cc470..0000000000 --- a/ext/webgpu/sampler.rs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuSampler(pub(crate) wgpu_core::id::SamplerId); -impl Resource for WebGpuSampler { - fn name(&self) -> Cow { - "webGPUSampler".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuAddressMode { - ClampToEdge, - Repeat, - MirrorRepeat, -} - -impl From for wgpu_types::AddressMode { - fn from(value: GpuAddressMode) -> wgpu_types::AddressMode { - match value { - GpuAddressMode::ClampToEdge => wgpu_types::AddressMode::ClampToEdge, - GpuAddressMode::Repeat => wgpu_types::AddressMode::Repeat, - GpuAddressMode::MirrorRepeat => wgpu_types::AddressMode::MirrorRepeat, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuFilterMode { - Nearest, - Linear, -} - -impl From for wgpu_types::FilterMode { - fn from(value: GpuFilterMode) -> wgpu_types::FilterMode { - match value { - GpuFilterMode::Nearest => wgpu_types::FilterMode::Nearest, - GpuFilterMode::Linear => wgpu_types::FilterMode::Linear, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuCompareFunction { - Never, - Less, - Equal, - LessEqual, - Greater, - NotEqual, - GreaterEqual, - Always, -} - -impl From for wgpu_types::CompareFunction { - fn from(value: GpuCompareFunction) -> wgpu_types::CompareFunction { - match value { - GpuCompareFunction::Never => wgpu_types::CompareFunction::Never, - GpuCompareFunction::Less => wgpu_types::CompareFunction::Less, - GpuCompareFunction::Equal => wgpu_types::CompareFunction::Equal, - GpuCompareFunction::LessEqual => wgpu_types::CompareFunction::LessEqual, - GpuCompareFunction::Greater => wgpu_types::CompareFunction::Greater, - GpuCompareFunction::NotEqual => wgpu_types::CompareFunction::NotEqual, - GpuCompareFunction::GreaterEqual => { - wgpu_types::CompareFunction::GreaterEqual - } - GpuCompareFunction::Always => wgpu_types::CompareFunction::Always, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateSamplerArgs { - device_rid: ResourceId, - label: Option, - address_mode_u: GpuAddressMode, - address_mode_v: GpuAddressMode, - address_mode_w: GpuAddressMode, - mag_filter: GpuFilterMode, - min_filter: GpuFilterMode, - mipmap_filter: GpuFilterMode, - lod_min_clamp: f32, - lod_max_clamp: f32, - compare: Option, - max_anisotropy: u8, -} - -pub fn op_webgpu_create_sampler( - state: &mut OpState, - args: CreateSamplerArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(args.device_rid)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::SamplerDescriptor { - label: args.label.map(Cow::from), - address_modes: [ - args.address_mode_u.into(), - args.address_mode_v.into(), - args.address_mode_w.into(), - ], - mag_filter: args.mag_filter.into(), - min_filter: args.min_filter.into(), - mipmap_filter: args.mipmap_filter.into(), - lod_min_clamp: args.lod_min_clamp, - lod_max_clamp: args.lod_max_clamp, - compare: args.compare.map(Into::into), - anisotropy_clamp: std::num::NonZeroU8::new(args.max_anisotropy), - border_color: None, // native-only - }; - - gfx_put!(device => instance.device_create_sampler( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuSampler) -} diff --git a/ext/webgpu/binding.rs b/ext/webgpu/src/binding.rs similarity index 88% rename from ext/webgpu/binding.rs rename to ext/webgpu/src/binding.rs index fea99fc163..9a8fa455f2 100644 --- a/ext/webgpu/binding.rs +++ b/ext/webgpu/src/binding.rs @@ -5,8 +5,7 @@ use deno_core::ResourceId; use deno_core::{OpState, Resource}; use serde::Deserialize; use std::borrow::Cow; - -use crate::texture::{GpuTextureFormat, GpuTextureViewDimension}; +use std::convert::{TryFrom, TryInto}; use super::error::WebGpuResult; @@ -59,41 +58,14 @@ impl From for wgpu_types::BufferBindingType { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GpuSamplerBindingLayout { - r#type: GpuSamplerBindingType, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuSamplerBindingType { - Filtering, - NonFiltering, - Comparison, -} - -impl From for wgpu_types::BindingType { - fn from(binding_type: GpuSamplerBindingType) -> Self { - match binding_type { - GpuSamplerBindingType::Filtering => wgpu_types::BindingType::Sampler { - filtering: true, - comparison: false, - }, - GpuSamplerBindingType::NonFiltering => wgpu_types::BindingType::Sampler { - filtering: false, - comparison: false, - }, - GpuSamplerBindingType::Comparison => wgpu_types::BindingType::Sampler { - filtering: true, - comparison: true, - }, - } - } + r#type: wgpu_types::SamplerBindingType, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GpuTextureBindingLayout { sample_type: GpuTextureSampleType, - view_dimension: GpuTextureViewDimension, + view_dimension: wgpu_types::TextureViewDimension, multisampled: bool, } @@ -127,8 +99,8 @@ impl From for wgpu_types::TextureSampleType { #[serde(rename_all = "camelCase")] struct GpuStorageTextureBindingLayout { access: GpuStorageTextureAccess, - format: GpuTextureFormat, - view_dimension: GpuTextureViewDimension, + format: wgpu_types::TextureFormat, + view_dimension: wgpu_types::TextureViewDimension, } #[derive(Deserialize)] @@ -177,17 +149,19 @@ impl TryFrom for wgpu_types::BindingType { has_dynamic_offset: buffer.has_dynamic_offset, min_binding_size: std::num::NonZeroU64::new(buffer.min_binding_size), }, - GpuBindingType::Sampler(sampler) => sampler.r#type.into(), + GpuBindingType::Sampler(sampler) => { + wgpu_types::BindingType::Sampler(sampler.r#type) + } GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture { sample_type: texture.sample_type.into(), - view_dimension: texture.view_dimension.into(), + view_dimension: texture.view_dimension, multisampled: texture.multisampled, }, GpuBindingType::StorageTexture(storage_texture) => { wgpu_types::BindingType::StorageTexture { access: storage_texture.access.into(), - format: storage_texture.format.try_into()?, - view_dimension: storage_texture.view_dimension.into(), + format: storage_texture.format, + view_dimension: storage_texture.view_dimension, } } }; diff --git a/ext/webgpu/buffer.rs b/ext/webgpu/src/buffer.rs similarity index 100% rename from ext/webgpu/buffer.rs rename to ext/webgpu/src/buffer.rs diff --git a/ext/webgpu/bundle.rs b/ext/webgpu/src/bundle.rs similarity index 97% rename from ext/webgpu/bundle.rs rename to ext/webgpu/src/bundle.rs index 7b32c1ecef..ea327651a5 100644 --- a/ext/webgpu/bundle.rs +++ b/ext/webgpu/src/bundle.rs @@ -9,9 +9,6 @@ use std::borrow::Cow; use std::cell::RefCell; use std::rc::Rc; -use crate::pipeline::GpuIndexFormat; -use crate::texture::GpuTextureFormat; - use super::error::WebGpuResult; struct WebGpuRenderBundleEncoder( @@ -35,8 +32,8 @@ impl Resource for WebGpuRenderBundle { pub struct CreateRenderBundleEncoderArgs { device_rid: ResourceId, label: Option, - color_formats: Vec, - depth_stencil_format: Option, + color_formats: Vec, + depth_stencil_format: Option, sample_count: u32, depth_read_only: bool, stencil_read_only: bool, @@ -55,12 +52,12 @@ pub fn op_webgpu_create_render_bundle_encoder( let mut color_formats = vec![]; for format in args.color_formats { - color_formats.push(format.try_into()?); + color_formats.push(format); } let depth_stencil = if let Some(format) = args.depth_stencil_format { Some(wgpu_types::RenderBundleDepthStencil { - format: format.try_into()?, + format, depth_read_only: args.depth_read_only, stencil_read_only: args.stencil_read_only, }) @@ -73,6 +70,7 @@ pub fn op_webgpu_create_render_bundle_encoder( color_formats: Cow::from(color_formats), sample_count: args.sample_count, depth_stencil, + multiview: None, }; let res = @@ -301,7 +299,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline( pub struct RenderBundleEncoderSetIndexBufferArgs { render_bundle_encoder_rid: ResourceId, buffer: ResourceId, - index_format: GpuIndexFormat, + index_format: wgpu_types::IndexFormat, offset: u64, size: u64, } @@ -324,7 +322,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer( .borrow_mut() .set_index_buffer( buffer_resource.0, - args.index_format.into(), + args.index_format, args.offset, std::num::NonZeroU64::new(args.size), ); diff --git a/ext/webgpu/command_encoder.rs b/ext/webgpu/src/command_encoder.rs similarity index 89% rename from ext/webgpu/command_encoder.rs rename to ext/webgpu/src/command_encoder.rs index cbd57f694e..894b08f274 100644 --- a/ext/webgpu/command_encoder.rs +++ b/ext/webgpu/src/command_encoder.rs @@ -8,8 +8,6 @@ use std::borrow::Cow; use std::cell::RefCell; use std::num::NonZeroU32; -use crate::texture::GpuTextureAspect; - use super::error::WebGpuResult; pub(crate) struct WebGpuCommandEncoder( @@ -65,8 +63,8 @@ pub fn op_webgpu_create_command_encoder( pub struct GpuRenderPassColorAttachment { view: ResourceId, resolve_target: Option, - load_op: GpuLoadOp, - store_op: GpuStoreOp, + load_op: GpuLoadOp, + store_op: wgpu_core::command::StoreOp, } #[derive(Deserialize)] @@ -76,31 +74,15 @@ enum GpuLoadOp { Clear(T), } -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuStoreOp { - Store, - Discard, -} - -impl From for wgpu_core::command::StoreOp { - fn from(value: GpuStoreOp) -> wgpu_core::command::StoreOp { - match value { - GpuStoreOp::Store => wgpu_core::command::StoreOp::Store, - GpuStoreOp::Discard => wgpu_core::command::StoreOp::Discard, - } - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct GpuRenderPassDepthStencilAttachment { view: ResourceId, depth_load_op: GpuLoadOp, - depth_store_op: GpuStoreOp, + depth_store_op: wgpu_core::command::StoreOp, depth_read_only: bool, stencil_load_op: GpuLoadOp, - stencil_store_op: GpuStoreOp, + stencil_store_op: wgpu_core::command::StoreOp, stencil_read_only: bool, } @@ -147,19 +129,14 @@ pub fn op_webgpu_command_encoder_begin_render_pass( channel: match color_attachment.load_op { GpuLoadOp::Load => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Load, - store_op: color_attachment.store_op.into(), + store_op: color_attachment.store_op, clear_value: Default::default(), read_only: false, }, GpuLoadOp::Clear(color) => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Clear, - store_op: color_attachment.store_op.into(), - clear_value: wgpu_types::Color { - r: color.r, - g: color.g, - b: color.b, - a: color.a, - }, + store_op: color_attachment.store_op, + clear_value: color, read_only: false, }, }, @@ -182,13 +159,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass( depth: match attachment.depth_load_op { GpuLoadOp::Load => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Load, - store_op: attachment.depth_store_op.into(), + store_op: attachment.depth_store_op, clear_value: 0.0, read_only: attachment.depth_read_only, }, GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Clear, - store_op: attachment.depth_store_op.into(), + store_op: attachment.depth_store_op, clear_value: value, read_only: attachment.depth_read_only, }, @@ -196,13 +173,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass( stencil: match attachment.stencil_load_op { GpuLoadOp::Load => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Load, - store_op: attachment.stencil_store_op.into(), + store_op: attachment.stencil_store_op, clear_value: 0, read_only: attachment.stencil_read_only, }, GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { load_op: wgpu_core::command::LoadOp::Clear, - store_op: attachment.stencil_store_op.into(), + store_op: attachment.stencil_store_op, clear_value: value, read_only: attachment.stencil_read_only, }, @@ -315,31 +292,13 @@ pub struct GpuImageCopyBuffer { rows_per_image: Option, } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuOrigin3D { - pub x: u32, - pub y: u32, - pub z: u32, -} - -impl From for wgpu_types::Origin3d { - fn from(origin: GpuOrigin3D) -> wgpu_types::Origin3d { - wgpu_types::Origin3d { - x: origin.x, - y: origin.y, - z: origin.z, - } - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct GpuImageCopyTexture { pub texture: ResourceId, pub mip_level: u32, - pub origin: GpuOrigin3D, - pub aspect: GpuTextureAspect, + pub origin: wgpu_types::Origin3d, + pub aspect: wgpu_types::TextureAspect, } #[derive(Deserialize)] @@ -348,7 +307,7 @@ pub struct CommandEncoderCopyBufferToTextureArgs { command_encoder_rid: ResourceId, source: GpuImageCopyBuffer, destination: GpuImageCopyTexture, - copy_size: super::texture::GpuExtent3D, + copy_size: wgpu_types::Extent3d, } pub fn op_webgpu_command_encoder_copy_buffer_to_texture( @@ -381,14 +340,14 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( let destination = wgpu_core::command::ImageCopyTexture { texture: destination_texture_resource.0, mip_level: args.destination.mip_level, - origin: args.destination.origin.into(), - aspect: args.destination.aspect.into(), + origin: args.destination.origin, + aspect: args.destination.aspect, }; gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture( command_encoder, &source, &destination, - &args.copy_size.into() + &args.copy_size )) } @@ -398,7 +357,7 @@ pub struct CommandEncoderCopyTextureToBufferArgs { command_encoder_rid: ResourceId, source: GpuImageCopyTexture, destination: GpuImageCopyBuffer, - copy_size: super::texture::GpuExtent3D, + copy_size: wgpu_types::Extent3d, } pub fn op_webgpu_command_encoder_copy_texture_to_buffer( @@ -423,8 +382,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( let source = wgpu_core::command::ImageCopyTexture { texture: source_texture_resource.0, mip_level: args.source.mip_level, - origin: args.source.origin.into(), - aspect: args.source.aspect.into(), + origin: args.source.origin, + aspect: args.source.aspect, }; let destination = wgpu_core::command::ImageCopyBuffer { buffer: destination_buffer_resource.0, @@ -442,7 +401,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( command_encoder, &source, &destination, - &args.copy_size.into() + &args.copy_size )) } @@ -452,7 +411,7 @@ pub struct CommandEncoderCopyTextureToTextureArgs { command_encoder_rid: ResourceId, source: GpuImageCopyTexture, destination: GpuImageCopyTexture, - copy_size: super::texture::GpuExtent3D, + copy_size: wgpu_types::Extent3d, } pub fn op_webgpu_command_encoder_copy_texture_to_texture( @@ -477,20 +436,51 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( let source = wgpu_core::command::ImageCopyTexture { texture: source_texture_resource.0, mip_level: args.source.mip_level, - origin: args.source.origin.into(), - aspect: args.source.aspect.into(), + origin: args.source.origin, + aspect: args.source.aspect, }; let destination = wgpu_core::command::ImageCopyTexture { texture: destination_texture_resource.0, mip_level: args.destination.mip_level, - origin: args.destination.origin.into(), - aspect: args.destination.aspect.into(), + origin: args.destination.origin, + aspect: args.destination.aspect, }; gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture( command_encoder, &source, &destination, - &args.copy_size.into() + &args.copy_size + )) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CommandEncoderClearBufferArgs { + command_encoder_rid: u32, + destination_rid: u32, + destination_offset: u64, + size: u64, +} + +pub fn op_webgpu_command_encoder_clear_buffer( + state: &mut OpState, + args: CommandEncoderClearBufferArgs, + _: (), +) -> Result { + let instance = state.borrow::(); + let command_encoder_resource = state + .resource_table + .get::(args.command_encoder_rid)?; + let command_encoder = command_encoder_resource.0; + let destination_resource = state + .resource_table + .get::(args.destination_rid)?; + + gfx_ok!(command_encoder => instance.command_encoder_clear_buffer( + command_encoder, + destination_resource.0, + args.destination_offset, + std::num::NonZeroU64::new(args.size) )) } diff --git a/ext/webgpu/compute_pass.rs b/ext/webgpu/src/compute_pass.rs similarity index 98% rename from ext/webgpu/compute_pass.rs rename to ext/webgpu/src/compute_pass.rs index e52db461c7..03d9163cb2 100644 --- a/ext/webgpu/compute_pass.rs +++ b/ext/webgpu/src/compute_pass.rs @@ -125,10 +125,10 @@ pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( .get::(args.query_set)?; wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); + &mut compute_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); Ok(WebGpuResult::empty()) } @@ -149,8 +149,8 @@ pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( .get::(args.compute_pass_rid)?; wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - ); + &mut compute_pass_resource.0.borrow_mut(), + ); Ok(WebGpuResult::empty()) } diff --git a/ext/webgpu/error.rs b/ext/webgpu/src/error.rs similarity index 97% rename from ext/webgpu/error.rs rename to ext/webgpu/src/error.rs index 18ffdf1a82..ae6e480546 100644 --- a/ext/webgpu/error.rs +++ b/ext/webgpu/src/error.rs @@ -8,6 +8,7 @@ use wgpu_core::binding_model::CreateBindGroupError; use wgpu_core::binding_model::CreateBindGroupLayoutError; use wgpu_core::binding_model::CreatePipelineLayoutError; use wgpu_core::binding_model::GetBindGroupLayoutError; +use wgpu_core::command::ClearError; use wgpu_core::command::CommandEncoderError; use wgpu_core::command::ComputePassError; use wgpu_core::command::CopyError; @@ -258,6 +259,12 @@ impl From for WebGpuError { } } +impl From for WebGpuError { + fn from(err: ClearError) -> Self { + WebGpuError::Validation(err.to_string()) + } +} + #[derive(Debug)] pub struct DomExceptionOperationError { pub msg: String, diff --git a/ext/webgpu/lib.rs b/ext/webgpu/src/lib.rs similarity index 68% rename from ext/webgpu/lib.rs rename to ext/webgpu/src/lib.rs index 81f84f6bf9..9d227a51e4 100644 --- a/ext/webgpu/lib.rs +++ b/ext/webgpu/src/lib.rs @@ -14,7 +14,6 @@ use serde::Serialize; use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashSet; -use std::path::PathBuf; use std::rc::Rc; pub use wgpu_core; pub use wgpu_types; @@ -125,15 +124,11 @@ pub fn init(unstable: bool) -> Extension { .build() } -pub fn get_declaration() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webgpu.d.ts") -} - fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { let mut return_features: Vec<&'static str> = vec![]; - if features.contains(wgpu_types::Features::DEPTH_CLAMPING) { - return_features.push("depth-clamping"); + if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { + return_features.push("depth-clip-control"); } if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { return_features.push("pipeline-statistics-query"); @@ -141,9 +136,18 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { return_features.push("texture-compression-bc"); } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { + return_features.push("texture-compression-etc2"); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { + return_features.push("texture-compression-astc"); + } if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { return_features.push("timestamp-query"); } + if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) { + return_features.push("indirect-first-instance"); + } // extended from spec if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { @@ -158,12 +162,16 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) { return_features.push("storage-resource-binding-array"); } - if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING) { - return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing"); - } - if features.contains(wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) { - return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"); - } + if features.contains( + wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, + ) { + return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing"); + } + if features.contains( + wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + ) { + return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"); + } if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { return_features.push("unsized-binding-array"); } @@ -179,15 +187,6 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { return_features.push("address-mode-clamp-to-border"); } - if features.contains(wgpu_types::Features::NON_FILL_POLYGON_MODE) { - return_features.push("non-fill-polygon-mode"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { - return_features.push("texture-compression-etc2"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { - return_features.push("texture-compression-astc-ldr"); - } if features .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) { @@ -206,7 +205,7 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { return_features.push("vertex-writable-storage"); } if features.contains(wgpu_types::Features::CLEAR_COMMANDS) { - return_features.push("clear-commands"); + return_features.push("clear-texture"); } if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) { return_features.push("spirv-shader-passthrough"); @@ -218,28 +217,11 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { return_features } -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuPowerPreference { - LowPower, - HighPerformance, -} - -impl From for wgpu_types::PowerPreference { - fn from(value: GpuPowerPreference) -> wgpu_types::PowerPreference { - match value { - GpuPowerPreference::LowPower => wgpu_types::PowerPreference::LowPower, - GpuPowerPreference::HighPerformance => { - wgpu_types::PowerPreference::HighPerformance - } - } - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct RequestAdapterArgs { - power_preference: Option, + power_preference: Option, + force_fallback_adapter: bool, } #[derive(Serialize)] @@ -266,31 +248,35 @@ pub async fn op_webgpu_request_adapter( ) -> Result { let mut state = state.borrow_mut(); check_unstable(&state, "navigator.gpu.requestAdapter"); + let backends = std::env::var("DENO_WEBGPU_BACKEND") + .ok() + .map_or_else(wgpu_types::Backends::all, |s| { + wgpu_core::instance::parse_backends_from_comma_list(&s) + }); let instance = if let Some(instance) = state.try_borrow::() { instance } else { state.put(wgpu_core::hub::Global::new( "webgpu", wgpu_core::hub::IdentityManagerFactory, - wgpu_types::Backends::PRIMARY, + backends, )); state.borrow::() }; let descriptor = wgpu_core::instance::RequestAdapterOptions { power_preference: match args.power_preference { - Some(power_preference) => power_preference.into(), + Some(power_preference) => power_preference, None => PowerPreference::default(), }, - // TODO(lucacasonato): respect forceFallbackAdapter + force_fallback_adapter: args.force_fallback_adapter, compatible_surface: None, // windowless }; let res = instance.request_adapter( &descriptor, - wgpu_core::instance::AdapterInputs::Mask( - wgpu_types::Backends::PRIMARY, - |_| std::marker::PhantomData, - ), + wgpu_core::instance::AdapterInputs::Mask(backends, |_| { + std::marker::PhantomData + }), ); let adapter = match res { @@ -319,116 +305,13 @@ pub async fn op_webgpu_request_adapter( })) } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuLimits { - max_texture_dimension_1d: Option, - max_texture_dimension_2d: Option, - max_texture_dimension_3d: Option, - max_texture_array_layers: Option, - max_bind_groups: Option, - max_dynamic_uniform_buffers_per_pipeline_layout: Option, - max_dynamic_storage_buffers_per_pipeline_layout: Option, - max_sampled_textures_per_shader_stage: Option, - max_samplers_per_shader_stage: Option, - max_storage_buffers_per_shader_stage: Option, - max_storage_textures_per_shader_stage: Option, - max_uniform_buffers_per_shader_stage: Option, - max_uniform_buffer_binding_size: Option, // TODO(@crowlkats): u64 - max_storage_buffer_binding_size: Option, // TODO(@crowlkats): u64 - // min_uniform_buffer_offset_alignment: Option, - // min_storage_buffer_offset_alignment: Option, - max_vertex_buffers: Option, - max_vertex_attributes: Option, - max_vertex_buffer_array_stride: Option, - // max_inter_stage_shader_components: Option, - // max_compute_workgroup_storage_size: Option, - // max_compute_invocations_per_workgroup: Option, - // max_compute_workgroup_size_x: Option, - // max_compute_workgroup_size_y: Option, - // max_compute_workgroup_size_z: Option, - // max_compute_workgroups_per_dimension: Option, -} - -impl From for wgpu_types::Limits { - fn from(limits: GpuLimits) -> wgpu_types::Limits { - wgpu_types::Limits { - max_texture_dimension_1d: limits.max_texture_dimension_1d.unwrap_or(8192), - max_texture_dimension_2d: limits.max_texture_dimension_2d.unwrap_or(8192), - max_texture_dimension_3d: limits.max_texture_dimension_3d.unwrap_or(2048), - max_texture_array_layers: limits.max_texture_array_layers.unwrap_or(2048), - max_bind_groups: limits.max_bind_groups.unwrap_or(4), - max_dynamic_uniform_buffers_per_pipeline_layout: limits - .max_dynamic_uniform_buffers_per_pipeline_layout - .unwrap_or(8), - max_dynamic_storage_buffers_per_pipeline_layout: limits - .max_dynamic_storage_buffers_per_pipeline_layout - .unwrap_or(4), - max_sampled_textures_per_shader_stage: limits - .max_sampled_textures_per_shader_stage - .unwrap_or(16), - max_samplers_per_shader_stage: limits - .max_samplers_per_shader_stage - .unwrap_or(16), - max_storage_buffers_per_shader_stage: limits - .max_storage_buffers_per_shader_stage - .unwrap_or(4), - max_storage_textures_per_shader_stage: limits - .max_storage_textures_per_shader_stage - .unwrap_or(4), - max_uniform_buffers_per_shader_stage: limits - .max_uniform_buffers_per_shader_stage - .unwrap_or(12), - max_uniform_buffer_binding_size: limits - .max_uniform_buffer_binding_size - .unwrap_or(16384), - max_storage_buffer_binding_size: limits - .max_storage_buffer_binding_size - .unwrap_or(134217728), - // min_uniform_buffer_offset_alignment: limits - // .min_uniform_buffer_offset_alignment - // .unwrap_or(default), - // min_storage_buffer_offset_alignment: limits - // .min_storage_buffer_offset_alignment - // .unwrap_or(default), - max_vertex_buffers: limits.max_vertex_buffers.unwrap_or(8), - max_vertex_attributes: limits.max_vertex_attributes.unwrap_or(16), - max_vertex_buffer_array_stride: limits - .max_vertex_buffer_array_stride - .unwrap_or(2048), - // max_inter_stage_shader_components: limits - // .max_inter_stage_shader_components - // .unwrap_or(default), - // max_compute_workgroup_storage_size: limits - // .max_compute_workgroup_storage_size - // .unwrap_or(default), - // max_compute_invocations_per_workgroup: limits - // .max_compute_invocations_per_workgroup - // .unwrap_or(default), - // max_compute_workgroup_size_x: limits - // .max_compute_workgroup_size_x - // .unwrap_or(default), - // max_compute_workgroup_size_y: limits - // .max_compute_workgroup_size_y - // .unwrap_or(default), - // max_compute_workgroup_size_z: limits - // .max_compute_workgroup_size_z - // .unwrap_or(default), - // max_compute_workgroups_per_dimension: limits - // .max_compute_workgroups_per_dimension - // .unwrap_or(default), - max_push_constant_size: 0, - } - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct RequestDeviceArgs { adapter_rid: ResourceId, label: Option, required_features: Option, - required_limits: Option, + required_limits: Option, } #[derive(Deserialize)] @@ -437,101 +320,120 @@ pub struct GpuRequiredFeatures(HashSet); impl From for wgpu_types::Features { fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features { let mut features: wgpu_types::Features = wgpu_types::Features::empty(); - - if required_features.0.contains("depth-clamping") { - features.set(wgpu_types::Features::DEPTH_CLAMPING, true); - } - if required_features.0.contains("pipeline-statistics-query") { - features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true); - } - if required_features.0.contains("texture-compression-bc") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true); - } - if required_features.0.contains("timestamp-query") { - features.set(wgpu_types::Features::TIMESTAMP_QUERY, true); - } + features.set( + wgpu_types::Features::DEPTH_CLIP_CONTROL, + required_features.0.contains("depth-clip-control"), + ); + features.set( + wgpu_types::Features::PIPELINE_STATISTICS_QUERY, + required_features.0.contains("pipeline-statistics-query"), + ); + features.set( + wgpu_types::Features::TEXTURE_COMPRESSION_BC, + required_features.0.contains("texture-compression-bc"), + ); + features.set( + wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, + required_features.0.contains("texture-compression-etc2"), + ); + features.set( + wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, + required_features.0.contains("texture-compression-astc"), + ); + features.set( + wgpu_types::Features::TIMESTAMP_QUERY, + required_features.0.contains("timestamp-query"), + ); + features.set( + wgpu_types::Features::INDIRECT_FIRST_INSTANCE, + required_features.0.contains("indirect-first-instance"), + ); // extended from spec - if required_features.0.contains("mappable-primary-buffers") { - features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true); - } - if required_features.0.contains("texture-binding-array") { - features.set(wgpu_types::Features::TEXTURE_BINDING_ARRAY, true); - } - if required_features.0.contains("buffer-binding-array") { - features.set(wgpu_types::Features::BUFFER_BINDING_ARRAY, true); - } - if required_features - .0 - .contains("storage-resource-binding-array") - { - features.set(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, true); - } - if required_features - .0 - .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing") - { - features.set(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, true); - } - if required_features.0.contains( - "uniform-buffer-and-storage-buffer-texture-non-uniform-indexing", - ) { - features.set(wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, true); - } - if required_features.0.contains("unsized-binding-array") { - features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true); - } - if required_features.0.contains("multi-draw-indirect") { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, true); - } - if required_features.0.contains("multi-draw-indirect-count") { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, true); - } - if required_features.0.contains("push-constants") { - features.set(wgpu_types::Features::PUSH_CONSTANTS, true); - } - if required_features.0.contains("address-mode-clamp-to-border") { - features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); - } - if required_features.0.contains("non-fill-polygon-mode") { - features.set(wgpu_types::Features::NON_FILL_POLYGON_MODE, true); - } - if required_features.0.contains("texture-compression-etc2") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, true); - } - if required_features.0.contains("texture-compression-astc-ldr") { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true); - } - if required_features - .0 - .contains("texture-adapter-specific-format-features") - { - features.set( - wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, - true, - ); - } - if required_features.0.contains("shader-float64") { - features.set(wgpu_types::Features::SHADER_FLOAT64, true); - } - if required_features.0.contains("vertex-attribute-64bit") { - features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, true); - } - if required_features.0.contains("conservative-rasterization") { - features.set(wgpu_types::Features::CONSERVATIVE_RASTERIZATION, true); - } - if required_features.0.contains("vertex-writable-storage") { - features.set(wgpu_types::Features::VERTEX_WRITABLE_STORAGE, true); - } - if required_features.0.contains("clear-commands") { - features.set(wgpu_types::Features::CLEAR_COMMANDS, true); - } - if required_features.0.contains("spirv-shader-passthrough") { - features.set(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, true); - } - if required_features.0.contains("shader-primitive-index") { - features.set(wgpu_types::Features::SHADER_PRIMITIVE_INDEX, true); - } + features.set( + wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, + required_features.0.contains("mappable-primary-buffers"), + ); + features.set( + wgpu_types::Features::TEXTURE_BINDING_ARRAY, + required_features.0.contains("texture-binding-array"), + ); + features.set( + wgpu_types::Features::BUFFER_BINDING_ARRAY, + required_features.0.contains("buffer-binding-array"), + ); + features.set( + wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, + required_features + .0 + .contains("storage-resource-binding-array"), + ); + features.set( + wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, + required_features + .0 + .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"), + ); + features.set( + wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + required_features + .0 + .contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"), + ); + features.set( + wgpu_types::Features::UNSIZED_BINDING_ARRAY, + required_features.0.contains("unsized-binding-array"), + ); + features.set( + wgpu_types::Features::MULTI_DRAW_INDIRECT, + required_features.0.contains("multi-draw-indirect"), + ); + features.set( + wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, + required_features.0.contains("multi-draw-indirect-count"), + ); + features.set( + wgpu_types::Features::PUSH_CONSTANTS, + required_features.0.contains("push-constants"), + ); + features.set( + wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, + required_features.0.contains("address-mode-clamp-to-border"), + ); + features.set( + wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, + required_features + .0 + .contains("texture-adapter-specific-format-features"), + ); + features.set( + wgpu_types::Features::SHADER_FLOAT64, + required_features.0.contains("shader-float64"), + ); + features.set( + wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, + required_features.0.contains("vertex-attribute-64bit"), + ); + features.set( + wgpu_types::Features::CONSERVATIVE_RASTERIZATION, + required_features.0.contains("conservative-rasterization"), + ); + features.set( + wgpu_types::Features::VERTEX_WRITABLE_STORAGE, + required_features.0.contains("vertex-writable-storage"), + ); + features.set( + wgpu_types::Features::CLEAR_COMMANDS, + required_features.0.contains("clear-commands"), + ); + features.set( + wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, + required_features.0.contains("spirv-shader-passthrough"), + ); + features.set( + wgpu_types::Features::SHADER_PRIMITIVE_INDEX, + required_features.0.contains("shader-primitive-index"), + ); features } @@ -775,6 +677,10 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box)> { command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, ), ), + ( + "op_webgpu_command_encoder_clear_buffer", + op_sync(command_encoder::op_webgpu_command_encoder_clear_buffer), + ), ( "op_webgpu_command_encoder_push_debug_group", op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group), @@ -895,6 +801,22 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box)> { "op_webgpu_compute_pass_dispatch_indirect", op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect), ), + ( + "op_webgpu_compute_pass_begin_pipeline_statistics_query", + op_sync( + compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query, + ), + ), + ( + "op_webgpu_compute_pass_end_pipeline_statistics_query", + op_sync( + compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query, + ), + ), + ( + "op_webgpu_compute_pass_write_timestamp", + op_sync(compute_pass::op_webgpu_compute_pass_write_timestamp), + ), ( "op_webgpu_compute_pass_end_pass", op_sync(compute_pass::op_webgpu_compute_pass_end_pass), diff --git a/ext/webgpu/queue.rs b/ext/webgpu/src/queue.rs similarity index 96% rename from ext/webgpu/queue.rs rename to ext/webgpu/src/queue.rs index 39bd936037..a662c4ead6 100644 --- a/ext/webgpu/queue.rs +++ b/ext/webgpu/src/queue.rs @@ -108,7 +108,7 @@ pub struct QueueWriteTextureArgs { queue_rid: ResourceId, destination: super::command_encoder::GpuImageCopyTexture, data_layout: GpuImageDataLayout, - size: super::texture::GpuExtent3D, + size: wgpu_types::Extent3d, } pub fn op_webgpu_write_texture( @@ -127,8 +127,8 @@ pub fn op_webgpu_write_texture( let destination = wgpu_core::command::ImageCopyTexture { texture: texture_resource.0, mip_level: args.destination.mip_level, - origin: args.destination.origin.into(), - aspect: args.destination.aspect.into(), + origin: args.destination.origin, + aspect: args.destination.aspect, }; let data_layout = args.data_layout.into(); @@ -137,6 +137,6 @@ pub fn op_webgpu_write_texture( &destination, &*zero_copy, &data_layout, - &args.size.into() + &args.size )) } diff --git a/ext/webgpu/render_pass.rs b/ext/webgpu/src/render_pass.rs similarity index 96% rename from ext/webgpu/render_pass.rs rename to ext/webgpu/src/render_pass.rs index 780b6ea577..469bf727e4 100644 --- a/ext/webgpu/render_pass.rs +++ b/ext/webgpu/src/render_pass.rs @@ -9,8 +9,6 @@ use serde::Deserialize; use std::borrow::Cow; use std::cell::RefCell; -use crate::pipeline::GpuIndexFormat; - use super::error::WebGpuResult; pub(crate) struct WebGpuRenderPass( @@ -86,20 +84,11 @@ pub fn op_webgpu_render_pass_set_scissor_rect( Ok(WebGpuResult::empty()) } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuColor { - pub r: f64, - pub g: f64, - pub b: f64, - pub a: f64, -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct RenderPassSetBlendConstantArgs { render_pass_rid: ResourceId, - color: GpuColor, + color: wgpu_types::Color, } pub fn op_webgpu_render_pass_set_blend_constant( @@ -113,12 +102,7 @@ pub fn op_webgpu_render_pass_set_blend_constant( wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant( &mut render_pass_resource.0.borrow_mut(), - &wgpu_types::Color { - r: args.color.r, - g: args.color.g, - b: args.color.b, - a: args.color.a, - }, + &args.color, ); Ok(WebGpuResult::empty()) @@ -169,10 +153,10 @@ pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( .get::(args.query_set)?; wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); + &mut render_pass_resource.0.borrow_mut(), + query_set_resource.0, + args.query_index, + ); Ok(WebGpuResult::empty()) } @@ -193,8 +177,8 @@ pub fn op_webgpu_render_pass_end_pipeline_statistics_query( .get::(args.render_pass_rid)?; wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - ); + &mut render_pass_resource.0.borrow_mut(), + ); Ok(WebGpuResult::empty()) } @@ -466,7 +450,7 @@ pub fn op_webgpu_render_pass_set_pipeline( pub struct RenderPassSetIndexBufferArgs { render_pass_rid: ResourceId, buffer: u32, - index_format: GpuIndexFormat, + index_format: wgpu_types::IndexFormat, offset: u64, size: Option, } @@ -494,7 +478,7 @@ pub fn op_webgpu_render_pass_set_index_buffer( render_pass_resource.0.borrow_mut().set_index_buffer( buffer_resource.0, - args.index_format.into(), + args.index_format, args.offset, size, ); diff --git a/ext/webgpu/shader.rs b/ext/webgpu/src/shader.rs similarity index 95% rename from ext/webgpu/shader.rs rename to ext/webgpu/src/shader.rs index 2477beceb9..60290de8b0 100644 --- a/ext/webgpu/shader.rs +++ b/ext/webgpu/src/shader.rs @@ -40,6 +40,7 @@ pub fn op_webgpu_create_shader_module( let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { label: args.label.map(Cow::from), + shader_bound_checks: wgpu_types::ShaderBoundChecks::default(), }; gfx_put!(device => instance.device_create_shader_module( diff --git a/ext/webgpu/texture.rs b/ext/webgpu/texture.rs deleted file mode 100644 index 9b007b34d4..0000000000 --- a/ext/webgpu/texture.rs +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::not_supported; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; -pub(crate) struct WebGpuTexture(pub(crate) wgpu_core::id::TextureId); -impl Resource for WebGpuTexture { - fn name(&self) -> Cow { - "webGPUTexture".into() - } -} - -pub(crate) struct WebGpuTextureView(pub(crate) wgpu_core::id::TextureViewId); -impl Resource for WebGpuTextureView { - fn name(&self) -> Cow { - "webGPUTextureView".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuTextureFormat { - // 8-bit formats - #[serde(rename = "r8unorm")] - R8Unorm, - #[serde(rename = "r8snorm")] - R8Snorm, - #[serde(rename = "r8uint")] - R8Uint, - #[serde(rename = "r8sint")] - R8Sint, - - // 16-bit formats - #[serde(rename = "r16uint")] - R16Uint, - #[serde(rename = "r16sint")] - R16Sint, - #[serde(rename = "r16float")] - R16Float, - #[serde(rename = "rg8unorm")] - Rg8Unorm, - #[serde(rename = "rg8snorm")] - Rg8Snorm, - #[serde(rename = "rg8uint")] - Rg8Uint, - #[serde(rename = "rg8sint")] - Rg8Sint, - - // 32-bit formats - #[serde(rename = "r32uint")] - R32Uint, - #[serde(rename = "r32sint")] - R32Sint, - #[serde(rename = "r32float")] - R32Float, - #[serde(rename = "rg16uint")] - Rg16Uint, - #[serde(rename = "rg16sint")] - Rg16Sint, - #[serde(rename = "rg16float")] - Rg16Float, - #[serde(rename = "rgba8unorm")] - Rgba8Unorm, - #[serde(rename = "rgba8unorm-srgb")] - Rgba8UnormSrgb, - #[serde(rename = "rgba8snorm")] - Rgba8Snorm, - #[serde(rename = "rgba8uint")] - Rgba8Uint, - #[serde(rename = "rgba8sint")] - Rgba8Sint, - #[serde(rename = "bgra8unorm")] - Bgra8Unorm, - #[serde(rename = "bgra8unorm-srgb")] - Bgra8UnormSrgb, - // Packed 32-bit formats - #[serde(rename = "rgb9e5ufloat")] - RgB9E5UFloat, - #[serde(rename = "rgb10a2unorm")] - Rgb10a2Unorm, - #[serde(rename = "rg11b10ufloat")] - Rg11b10Float, - - // 64-bit formats - #[serde(rename = "rg32uint")] - Rg32Uint, - #[serde(rename = "rg32sint")] - Rg32Sint, - #[serde(rename = "rg32float")] - Rg32Float, - #[serde(rename = "rgba16uint")] - Rgba16Uint, - #[serde(rename = "rgba16sint")] - Rgba16Sint, - #[serde(rename = "rgba16float")] - Rgba16Float, - - // 128-bit formats - #[serde(rename = "rgba32uint")] - Rgba32Uint, - #[serde(rename = "rgba32sint")] - Rgba32Sint, - #[serde(rename = "rgba32float")] - Rgba32Float, - - // Depth and stencil formats - #[serde(rename = "stencil8")] - Stencil8, - #[serde(rename = "depth16unorm")] - Depth16Unorm, - #[serde(rename = "depth24plus")] - Depth24Plus, - #[serde(rename = "depth24plus-stencil8")] - Depth24PlusStencil8, - #[serde(rename = "depth32float")] - Depth32Float, - - // BC compressed formats usable if "texture-compression-bc" is both - // supported by the device/user agent and enabled in requestDevice. - #[serde(rename = "bc1-rgba-unorm")] - Bc1RgbaUnorm, - #[serde(rename = "bc1-rgba-unorm-srgb")] - Bc1RgbaUnormSrgb, - #[serde(rename = "bc2-rgba-unorm")] - Bc2RgbaUnorm, - #[serde(rename = "bc2-rgba-unorm-srgb")] - Bc2RgbaUnormSrgb, - #[serde(rename = "bc3-rgba-unorm")] - Bc3RgbaUnorm, - #[serde(rename = "bc3-rgba-unorm-srgb")] - Bc3RgbaUnormSrgb, - #[serde(rename = "bc4-r-unorm")] - Bc4RUnorm, - #[serde(rename = "bc4-r-snorm")] - Bc4RSnorm, - #[serde(rename = "bc5-rg-unorm")] - Bc5RgUnorm, - #[serde(rename = "bc5-rg-snorm")] - Bc5RgSnorm, - #[serde(rename = "bc6h-rgb-ufloat")] - Bc6hRgbUfloat, - #[serde(rename = "bc6h-rgb-float")] - Bc6HRgbFloat, - #[serde(rename = "bc7-rgba-unorm")] - Bc7RgbaUnorm, - #[serde(rename = "bc7-rgba-unorm-srgb")] - Bc7RgbaUnormSrgb, - - // "depth24unorm-stencil8" feature - #[serde(rename = "depth24unorm-stencil8")] - Depth24UnormStencil8, - - // "depth32float-stencil8" feature - #[serde(rename = "depth32float-stencil8")] - Depth32FloatStencil8, -} - -impl TryFrom for wgpu_types::TextureFormat { - type Error = AnyError; - - fn try_from(value: GpuTextureFormat) -> Result { - use wgpu_types::TextureFormat; - match value { - GpuTextureFormat::R8Unorm => Ok(TextureFormat::R8Unorm), - GpuTextureFormat::R8Snorm => Ok(TextureFormat::R8Snorm), - GpuTextureFormat::R8Uint => Ok(TextureFormat::R8Uint), - GpuTextureFormat::R8Sint => Ok(TextureFormat::R8Sint), - - GpuTextureFormat::R16Uint => Ok(TextureFormat::R16Uint), - GpuTextureFormat::R16Sint => Ok(TextureFormat::R16Sint), - GpuTextureFormat::R16Float => Ok(TextureFormat::R16Float), - GpuTextureFormat::Rg8Unorm => Ok(TextureFormat::Rg8Unorm), - GpuTextureFormat::Rg8Snorm => Ok(TextureFormat::Rg8Snorm), - GpuTextureFormat::Rg8Uint => Ok(TextureFormat::Rg8Uint), - GpuTextureFormat::Rg8Sint => Ok(TextureFormat::Rg8Sint), - - GpuTextureFormat::R32Uint => Ok(TextureFormat::R32Uint), - GpuTextureFormat::R32Sint => Ok(TextureFormat::R32Sint), - GpuTextureFormat::R32Float => Ok(TextureFormat::R32Float), - GpuTextureFormat::Rg16Uint => Ok(TextureFormat::Rg16Uint), - GpuTextureFormat::Rg16Sint => Ok(TextureFormat::Rg16Sint), - GpuTextureFormat::Rg16Float => Ok(TextureFormat::Rg16Float), - GpuTextureFormat::Rgba8Unorm => Ok(TextureFormat::Rgba8Unorm), - GpuTextureFormat::Rgba8UnormSrgb => Ok(TextureFormat::Rgba8UnormSrgb), - GpuTextureFormat::Rgba8Snorm => Ok(TextureFormat::Rgba8Snorm), - GpuTextureFormat::Rgba8Uint => Ok(TextureFormat::Rgba8Uint), - GpuTextureFormat::Rgba8Sint => Ok(TextureFormat::Rgba8Sint), - GpuTextureFormat::Bgra8Unorm => Ok(TextureFormat::Bgra8Unorm), - GpuTextureFormat::Bgra8UnormSrgb => Ok(TextureFormat::Bgra8UnormSrgb), - GpuTextureFormat::RgB9E5UFloat => Err(not_supported()), // wgpu#967 - GpuTextureFormat::Rgb10a2Unorm => Ok(TextureFormat::Rgb10a2Unorm), - GpuTextureFormat::Rg11b10Float => Ok(TextureFormat::Rg11b10Float), - - GpuTextureFormat::Rg32Uint => Ok(TextureFormat::Rg32Uint), - GpuTextureFormat::Rg32Sint => Ok(TextureFormat::Rg32Sint), - GpuTextureFormat::Rg32Float => Ok(TextureFormat::Rg32Float), - GpuTextureFormat::Rgba16Uint => Ok(TextureFormat::Rgba16Uint), - GpuTextureFormat::Rgba16Sint => Ok(TextureFormat::Rgba16Sint), - GpuTextureFormat::Rgba16Float => Ok(TextureFormat::Rgba16Float), - - GpuTextureFormat::Rgba32Uint => Ok(TextureFormat::Rgba32Uint), - GpuTextureFormat::Rgba32Sint => Ok(TextureFormat::Rgba32Sint), - GpuTextureFormat::Rgba32Float => Ok(TextureFormat::Rgba32Float), - - GpuTextureFormat::Stencil8 => Err(not_supported()), // wgpu#967 - GpuTextureFormat::Depth16Unorm => Err(not_supported()), // wgpu#967 - GpuTextureFormat::Depth24Plus => Ok(TextureFormat::Depth24Plus), - GpuTextureFormat::Depth24PlusStencil8 => { - Ok(TextureFormat::Depth24PlusStencil8) - } - GpuTextureFormat::Depth32Float => Ok(TextureFormat::Depth32Float), - - GpuTextureFormat::Bc1RgbaUnorm => Ok(TextureFormat::Bc1RgbaUnorm), - GpuTextureFormat::Bc1RgbaUnormSrgb => Ok(TextureFormat::Bc1RgbaUnormSrgb), - GpuTextureFormat::Bc2RgbaUnorm => Ok(TextureFormat::Bc2RgbaUnorm), - GpuTextureFormat::Bc2RgbaUnormSrgb => Ok(TextureFormat::Bc2RgbaUnormSrgb), - GpuTextureFormat::Bc3RgbaUnorm => Ok(TextureFormat::Bc3RgbaUnorm), - GpuTextureFormat::Bc3RgbaUnormSrgb => Ok(TextureFormat::Bc3RgbaUnormSrgb), - GpuTextureFormat::Bc4RUnorm => Ok(TextureFormat::Bc4RUnorm), - GpuTextureFormat::Bc4RSnorm => Ok(TextureFormat::Bc4RSnorm), - GpuTextureFormat::Bc5RgUnorm => Ok(TextureFormat::Bc5RgUnorm), - GpuTextureFormat::Bc5RgSnorm => Ok(TextureFormat::Bc5RgSnorm), - GpuTextureFormat::Bc6hRgbUfloat => Ok(TextureFormat::Bc6hRgbUfloat), - GpuTextureFormat::Bc6HRgbFloat => Ok(TextureFormat::Bc6hRgbSfloat), // wgpu#967 - GpuTextureFormat::Bc7RgbaUnorm => Ok(TextureFormat::Bc7RgbaUnorm), - GpuTextureFormat::Bc7RgbaUnormSrgb => Ok(TextureFormat::Bc7RgbaUnormSrgb), - - GpuTextureFormat::Depth24UnormStencil8 => Err(not_supported()), // wgpu#967, - - GpuTextureFormat::Depth32FloatStencil8 => Err(not_supported()), // wgpu#967 - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuTextureViewDimension { - #[serde(rename = "1d")] - D1, - #[serde(rename = "2d")] - D2, - #[serde(rename = "2d-array")] - D2Array, - #[serde(rename = "cube")] - Cube, - #[serde(rename = "cube-array")] - CubeArray, - #[serde(rename = "3d")] - D3, -} - -impl From for wgpu_types::TextureViewDimension { - fn from(view_dimension: GpuTextureViewDimension) -> Self { - match view_dimension { - GpuTextureViewDimension::D1 => wgpu_types::TextureViewDimension::D1, - GpuTextureViewDimension::D2 => wgpu_types::TextureViewDimension::D2, - GpuTextureViewDimension::D2Array => { - wgpu_types::TextureViewDimension::D2Array - } - GpuTextureViewDimension::Cube => wgpu_types::TextureViewDimension::Cube, - GpuTextureViewDimension::CubeArray => { - wgpu_types::TextureViewDimension::CubeArray - } - GpuTextureViewDimension::D3 => wgpu_types::TextureViewDimension::D3, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuTextureDimension { - #[serde(rename = "1d")] - D1, - #[serde(rename = "2d")] - D2, - #[serde(rename = "3d")] - D3, -} - -impl From for wgpu_types::TextureDimension { - fn from(texture_dimension: GpuTextureDimension) -> Self { - match texture_dimension { - GpuTextureDimension::D1 => wgpu_types::TextureDimension::D1, - GpuTextureDimension::D2 => wgpu_types::TextureDimension::D2, - GpuTextureDimension::D3 => wgpu_types::TextureDimension::D3, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum GpuTextureAspect { - All, - StencilOnly, - DepthOnly, -} - -impl From for wgpu_types::TextureAspect { - fn from(aspect: GpuTextureAspect) -> wgpu_types::TextureAspect { - match aspect { - GpuTextureAspect::All => wgpu_types::TextureAspect::All, - GpuTextureAspect::StencilOnly => wgpu_types::TextureAspect::StencilOnly, - GpuTextureAspect::DepthOnly => wgpu_types::TextureAspect::DepthOnly, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuExtent3D { - pub width: u32, - pub height: u32, - pub depth_or_array_layers: u32, -} - -impl From for wgpu_types::Extent3d { - fn from(extent: GpuExtent3D) -> Self { - wgpu_types::Extent3d { - width: extent.width, - height: extent.height, - depth_or_array_layers: extent.depth_or_array_layers, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateTextureArgs { - device_rid: ResourceId, - label: Option, - size: GpuExtent3D, - mip_level_count: u32, - sample_count: u32, - dimension: GpuTextureDimension, - format: GpuTextureFormat, - usage: u32, -} - -pub fn op_webgpu_create_texture( - state: &mut OpState, - args: CreateTextureArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(args.device_rid)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::TextureDescriptor { - label: args.label.map(Cow::from), - size: args.size.into(), - mip_level_count: args.mip_level_count, - sample_count: args.sample_count, - dimension: args.dimension.into(), - format: args.format.try_into()?, - usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage), - }; - - gfx_put!(device => instance.device_create_texture( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuTexture) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateTextureViewArgs { - texture_rid: ResourceId, - label: Option, - format: Option, - dimension: Option, - aspect: GpuTextureAspect, - base_mip_level: u32, - mip_level_count: Option, - base_array_layer: u32, - array_layer_count: Option, -} - -pub fn op_webgpu_create_texture_view( - state: &mut OpState, - args: CreateTextureViewArgs, - _: (), -) -> Result { - let instance = state.borrow::(); - let texture_resource = state - .resource_table - .get::(args.texture_rid)?; - let texture = texture_resource.0; - - let descriptor = wgpu_core::resource::TextureViewDescriptor { - label: args.label.map(Cow::from), - format: args.format.map(|s| s.try_into()).transpose()?, - dimension: args.dimension.map(|s| s.into()), - range: wgpu_types::ImageSubresourceRange { - aspect: args.aspect.into(), - base_mip_level: args.base_mip_level, - mip_level_count: std::num::NonZeroU32::new( - args.mip_level_count.unwrap_or(0), - ), - base_array_layer: args.base_array_layer, - array_layer_count: std::num::NonZeroU32::new( - args.array_layer_count.unwrap_or(0), - ), - }, - }; - - gfx_put!(texture => instance.texture_create_view( - texture, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuTextureView) -} diff --git a/ext/webgpu/webgpu.idl b/ext/webgpu/webgpu.idl index 0265069968..79d65791d4 100644 --- a/ext/webgpu/webgpu.idl +++ b/ext/webgpu/webgpu.idl @@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase { USVString label; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUSupportedLimits { readonly attribute unsigned long maxTextureDimension1D; readonly attribute unsigned long maxTextureDimension2D; @@ -36,7 +36,7 @@ interface GPUSupportedLimits { readonly attribute unsigned long maxComputeWorkgroupsPerDimension; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUSupportedFeatures { readonly setlike; }; @@ -46,12 +46,12 @@ enum GPUPredefinedColorSpace { }; interface mixin NavigatorGPU { - [SameObject] readonly attribute GPU gpu; + [SameObject, SecureContext] readonly attribute GPU gpu; }; Navigator includes NavigatorGPU; WorkerNavigator includes NavigatorGPU; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPU { Promise requestAdapter(optional GPURequestAdapterOptions options = {}); }; @@ -63,10 +63,10 @@ dictionary GPURequestAdapterOptions { enum GPUPowerPreference { "low-power", - "high-performance" + "high-performance", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUAdapter { readonly attribute DOMString name; [SameObject] readonly attribute GPUSupportedFeatures features; @@ -82,15 +82,18 @@ dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { }; enum GPUFeatureName { - "depth-clamping", + "depth-clip-control", "depth24unorm-stencil8", "depth32float-stencil8", "pipeline-statistics-query", "texture-compression-bc", + "texture-compression-etc2", + "texture-compression-astc", "timestamp-query", + "indirect-first-instance", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUDevice : EventTarget { [SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedLimits limits; @@ -120,7 +123,7 @@ interface GPUDevice : EventTarget { }; GPUDevice includes GPUObjectBase; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUBuffer { Promise mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); @@ -158,7 +161,7 @@ interface GPUMapMode { const GPUFlagsConstant WRITE = 0x0002; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUTexture { GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); @@ -191,7 +194,7 @@ interface GPUTextureUsage { const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUTextureView { }; GPUTextureView includes GPUObjectBase; @@ -212,13 +215,13 @@ enum GPUTextureViewDimension { "2d-array", "cube", "cube-array", - "3d" + "3d", }; enum GPUTextureAspect { "all", "stencil-only", - "depth-only" + "depth-only", }; enum GPUTextureFormat { @@ -293,6 +296,50 @@ enum GPUTextureFormat { "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + "etc2-rgb8unorm", + "etc2-rgb8unorm-srgb", + "etc2-rgb8a1unorm", + "etc2-rgb8a1unorm-srgb", + "etc2-rgba8unorm", + "etc2-rgba8unorm-srgb", + "eac-r11unorm", + "eac-r11snorm", + "eac-rg11unorm", + "eac-rg11snorm", + + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + "astc-4x4-unorm", + "astc-4x4-unorm-srgb", + "astc-5x4-unorm", + "astc-5x4-unorm-srgb", + "astc-5x5-unorm", + "astc-5x5-unorm-srgb", + "astc-6x5-unorm", + "astc-6x5-unorm-srgb", + "astc-6x6-unorm", + "astc-6x6-unorm-srgb", + "astc-8x5-unorm", + "astc-8x5-unorm-srgb", + "astc-8x6-unorm", + "astc-8x6-unorm-srgb", + "astc-8x8-unorm", + "astc-8x8-unorm-srgb", + "astc-10x5-unorm", + "astc-10x5-unorm-srgb", + "astc-10x6-unorm", + "astc-10x6-unorm-srgb", + "astc-10x8-unorm", + "astc-10x8-unorm-srgb", + "astc-10x10-unorm", + "astc-10x10-unorm-srgb", + "astc-12x10-unorm", + "astc-12x10-unorm-srgb", + "astc-12x12-unorm", + "astc-12x12-unorm-srgb", + // "depth24unorm-stencil8" feature "depth24unorm-stencil8", @@ -300,7 +347,7 @@ enum GPUTextureFormat { "depth32float-stencil8", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUSampler { }; GPUSampler includes GPUObjectBase; @@ -321,12 +368,12 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase { enum GPUAddressMode { "clamp-to-edge", "repeat", - "mirror-repeat" + "mirror-repeat", }; enum GPUFilterMode { "nearest", - "linear" + "linear", }; enum GPUCompareFunction { @@ -337,10 +384,10 @@ enum GPUCompareFunction { "greater", "not-equal", "greater-equal", - "always" + "always", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUBindGroupLayout { }; GPUBindGroupLayout includes GPUObjectBase; @@ -390,11 +437,11 @@ dictionary GPUSamplerBindingLayout { }; enum GPUTextureSampleType { - "float", - "unfilterable-float", - "depth", - "sint", - "uint", + "float", + "unfilterable-float", + "depth", + "sint", + "uint", }; dictionary GPUTextureBindingLayout { @@ -413,7 +460,7 @@ dictionary GPUStorageTextureBindingLayout { GPUTextureViewDimension viewDimension = "2d"; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUBindGroup { }; GPUBindGroup includes GPUObjectBase; @@ -436,7 +483,7 @@ dictionary GPUBufferBinding { GPUSize64 size; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUPipelineLayout { }; GPUPipelineLayout includes GPUObjectBase; @@ -445,7 +492,7 @@ dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase { required sequence bindGroupLayouts; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUShaderModule { Promise compilationInfo(); }; @@ -459,10 +506,10 @@ dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { enum GPUCompilationMessageType { "error", "warning", - "info" + "info", }; -[Exposed=(Window, DedicatedWorker), Serializable] +[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] interface GPUCompilationMessage { readonly attribute DOMString message; readonly attribute GPUCompilationMessageType type; @@ -472,7 +519,7 @@ interface GPUCompilationMessage { readonly attribute unsigned long long length; }; -[Exposed=(Window, DedicatedWorker), Serializable] +[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] interface GPUCompilationInfo { readonly attribute FrozenArray messages; }; @@ -493,7 +540,7 @@ dictionary GPUProgrammableStage { typedef double GPUPipelineConstantValue; // May represent WGSL’s bool, f32, i32, u32. -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUComputePipeline { }; GPUComputePipeline includes GPUObjectBase; @@ -503,7 +550,7 @@ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase { required GPUProgrammableStage compute; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPURenderPipeline { }; GPURenderPipeline includes GPUObjectBase; @@ -522,7 +569,7 @@ enum GPUPrimitiveTopology { "line-list", "line-strip", "triangle-list", - "triangle-strip" + "triangle-strip", }; dictionary GPUPrimitiveState { @@ -531,19 +578,19 @@ dictionary GPUPrimitiveState { GPUFrontFace frontFace = "ccw"; GPUCullMode cullMode = "none"; - // Enable depth clamping (requires "depth-clamping" feature) - boolean clampDepth = false; + // Requires "depth-clip-control" feature. + boolean unclippedDepth = false; }; enum GPUFrontFace { "ccw", - "cw" + "cw", }; enum GPUCullMode { "none", "front", - "back" + "back", }; dictionary GPUMultisampleState { @@ -552,7 +599,7 @@ dictionary GPUMultisampleState { boolean alphaToCoverageEnabled = false; }; -dictionary GPUFragmentState: GPUProgrammableStage { +dictionary GPUFragmentState : GPUProgrammableStage { required sequence targets; }; @@ -579,9 +626,9 @@ interface GPUColorWrite { }; dictionary GPUBlendComponent { + GPUBlendOperation operation = "add"; GPUBlendFactor srcFactor = "one"; GPUBlendFactor dstFactor = "zero"; - GPUBlendOperation operation = "add"; }; enum GPUBlendFactor { @@ -597,7 +644,7 @@ enum GPUBlendFactor { "one-minus-dst-alpha", "src-alpha-saturated", "constant", - "one-minus-constant" + "one-minus-constant", }; enum GPUBlendOperation { @@ -605,7 +652,7 @@ enum GPUBlendOperation { "subtract", "reverse-subtract", "min", - "max" + "max", }; dictionary GPUDepthStencilState { @@ -640,12 +687,12 @@ enum GPUStencilOperation { "increment-clamp", "decrement-clamp", "increment-wrap", - "decrement-wrap" + "decrement-wrap", }; enum GPUIndexFormat { "uint16", - "uint32" + "uint32", }; enum GPUVertexFormat { @@ -683,10 +730,10 @@ enum GPUVertexFormat { enum GPUVertexStepMode { "vertex", - "instance" + "instance", }; -dictionary GPUVertexState: GPUProgrammableStage { +dictionary GPUVertexState : GPUProgrammableStage { sequence buffers = []; }; @@ -703,16 +750,15 @@ dictionary GPUVertexAttribute { required GPUIndex32 shaderLocation; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUCommandBuffer { - readonly attribute Promise executionTime; }; GPUCommandBuffer includes GPUObjectBase; dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase { }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUCommandEncoder { GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); @@ -739,6 +785,11 @@ interface GPUCommandEncoder { GPUImageCopyTexture destination, GPUExtent3D copySize); + undefined clearBuffer( + GPUBuffer destination, + GPUSize64 destinationOffset, + GPUSize64 size); + undefined pushDebugGroup(USVString groupLabel); undefined popDebugGroup(); undefined insertDebugMarker(USVString markerLabel); @@ -757,7 +808,6 @@ interface GPUCommandEncoder { GPUCommandEncoder includes GPUObjectBase; dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase { - boolean measureExecutionTime = false; }; dictionary GPUImageDataLayout { @@ -791,7 +841,7 @@ interface mixin GPUProgrammablePassEncoder { undefined insertDebugMarker(USVString markerLabel); }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUComputePassEncoder { undefined setPipeline(GPUComputePipeline pipeline); undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1); @@ -827,7 +877,7 @@ interface mixin GPURenderEncoderBase { undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPURenderPassEncoder { undefined setViewport(float x, float y, float width, float height, @@ -881,12 +931,12 @@ dictionary GPURenderPassDepthStencilAttachment { }; enum GPULoadOp { - "load" + "load", }; enum GPUStoreOp { "store", - "discard" + "discard", }; dictionary GPURenderPassLayout: GPUObjectDescriptorBase { @@ -895,7 +945,7 @@ dictionary GPURenderPassLayout: GPUObjectDescriptorBase { GPUSize32 sampleCount = 1; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPURenderBundle { }; GPURenderBundle includes GPUObjectBase; @@ -903,7 +953,7 @@ GPURenderBundle includes GPUObjectBase; dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase { }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPURenderBundleEncoder { GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); }; @@ -916,7 +966,7 @@ dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout { boolean stencilReadOnly = false; }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUQueue { undefined submit(sequence commandBuffers); @@ -930,14 +980,14 @@ interface GPUQueue { optional GPUSize64 size); undefined writeTexture( - GPUImageCopyTexture destination, - [AllowShared] BufferSource data, - GPUImageDataLayout dataLayout, - GPUExtent3D size); + GPUImageCopyTexture destination, + [AllowShared] BufferSource data, + GPUImageDataLayout dataLayout, + GPUExtent3D size); }; GPUQueue includes GPUObjectBase; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUQuerySet { undefined destroy(); }; @@ -952,7 +1002,7 @@ dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase { enum GPUQueryType { "occlusion", "pipeline-statistics", - "timestamp" + "timestamp", }; enum GPUPipelineStatisticName { @@ -960,14 +1010,14 @@ enum GPUPipelineStatisticName { "clipper-invocations", "clipper-primitives-out", "fragment-shader-invocations", - "compute-shader-invocations" + "compute-shader-invocations", }; enum GPUDeviceLostReason { "destroyed", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUDeviceLostInfo { readonly attribute (GPUDeviceLostReason or undefined) reason; readonly attribute DOMString message; @@ -979,15 +1029,15 @@ partial interface GPUDevice { enum GPUErrorFilter { "out-of-memory", - "validation" + "validation", }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUOutOfMemoryError { constructor(); }; -[Exposed=(Window, DedicatedWorker)] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUValidationError { constructor(DOMString message); readonly attribute DOMString message; @@ -1000,9 +1050,7 @@ partial interface GPUDevice { Promise popErrorScope(); }; -[ - Exposed=(Window, DedicatedWorker) -] +[Exposed=(Window, DedicatedWorker), SecureContext] interface GPUUncapturedErrorEvent : Event { constructor( DOMString type, @@ -1060,3 +1108,4 @@ dictionary GPUExtent3DDict { GPUIntegerCoordinate depthOrArrayLayers = 1; }; typedef (sequence or GPUExtent3DDict) GPUExtent3D; + diff --git a/tools/README.md b/tools/README.md index 7bdf6f77a1..59860ca1b1 100644 --- a/tools/README.md +++ b/tools/README.md @@ -59,3 +59,16 @@ So you can simply run `./tools/flamebench.js op_baseline bench_op_async` or Tip: the `[bench_filter]` argument doesn't have to be an exact bench name, you can use a shorthand or a partial match to profile a group of benches, e.g: `./tools/flamebench.js de v8` + +## wgpu_sync.js + +`wgpu_sync.js` streamlines updating `deno_webgpu` from +[gfx-rs/wgpu](https://github.com/gfx-rs/wgpu/). + +It essentially vendors the `deno_webgpu` tree with a few minor patches applied +on top, somewhat similar to `git subtree`. + +1. Update `COMMIT` or `V_WGPU` in `./tools/wgpu_sync.js` +2. Run `./tools/wgpu_sync.js` +3. Double check changes, possibly patch +4. Commit & send a PR with the updates diff --git a/tools/util.js b/tools/util.js index b4742f6054..fa62097d4d 100644 --- a/tools/util.js +++ b/tools/util.js @@ -7,7 +7,7 @@ import { toFileUrl, } from "../test_util/std/path/mod.ts"; export { dirname, fromFileUrl, join, resolve, toFileUrl }; -export { existsSync } from "../test_util/std/fs/mod.ts"; +export { existsSync, walk } from "../test_util/std/fs/mod.ts"; export { readLines } from "../test_util/std/io/mod.ts"; export { delay } from "../test_util/std/async/delay.ts"; diff --git a/tools/wgpu_sync.js b/tools/wgpu_sync.js new file mode 100755 index 0000000000..c5b6ffc450 --- /dev/null +++ b/tools/wgpu_sync.js @@ -0,0 +1,119 @@ +#!/usr/bin/env -S deno run --unstable --allow-read --allow-write --allow-run +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +import { join, ROOT_PATH, walk } from "./util.js"; + +// const COMMIT = "c00e471274b6c21acda89b4b13d41742c0285d71"; // Release 12 +const COMMIT = "c4aa3eaed020a640fec06b48f0a5ea93490d41bb"; // tip of PR (needs merge) +const REPO = "kvark/wgpu"; +const V_WGPU = "0.12"; +const TARGET_DIR = join(ROOT_PATH, "ext", "webgpu"); + +async function bash(subcmd, opts = {}) { + const p = Deno.run({ ...opts, cmd: ["bash", "-c", subcmd] }); + + // Exit process on failure + const { success, code } = await p.status(); + if (!success) { + Deno.exit(code); + } + // Cleanup + p.close(); +} + +async function clearTargetDir() { + await bash(`rm -r ${TARGET_DIR}/*`); +} + +async function checkoutUpstream() { + // Path of deno_webgpu inside the TAR + const tarPrefix = `${REPO.replace("/", "-")}-${ + COMMIT.slice(0, 7) + }/deno_webgpu/`; + const cmd = + `curl -L https://api.github.com/repos/${REPO}/tarball/${COMMIT} | tar -C '${TARGET_DIR}' -xzvf - --strip=2 '${tarPrefix}'`; + // console.log(cmd); + await bash(cmd); +} + +async function denoCoreVersion() { + const coreCargo = join(ROOT_PATH, "core", "Cargo.toml"); + const contents = await Deno.readTextFile(coreCargo); + return contents.match(/^version = "(\d+\.\d+\.\d+)"$/m)[1]; +} + +async function denoWebgpuVersion() { + const coreCargo = join(ROOT_PATH, "runtime", "Cargo.toml"); + const contents = await Deno.readTextFile(coreCargo); + return contents.match( + /^deno_webgpu = { version = "(\d+\.\d+\.\d+)", path = "..\/ext\/webgpu" }$/m, + )[1]; +} + +async function patchFile(path, patcher) { + const data = await Deno.readTextFile(path); + const patched = patcher(data); + await Deno.writeTextFile(path, patched); +} + +async function patchCargo() { + const vDenoCore = await denoCoreVersion(); + const vDenoWebgpu = await denoWebgpuVersion(); + await patchFile( + join(TARGET_DIR, "Cargo.toml"), + (data) => + data + .replace(/^version = .*/m, `version = "${vDenoWebgpu}"`) + .replace(`edition = "2018"`, `edition = "2021"`) + .replace( + /^deno_core \= .*$/gm, + `deno_core = { version = "${vDenoCore}", path = "../../core" }`, + ) + .replace( + /^wgpu-core \= .*$/gm, + `wgpu-core = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`, + ) + .replace( + /^wgpu-types \= .*$/gm, + `wgpu-types = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`, + ), + // .replace( + // /^wgpu-core \= .*$/gm, + // `wgpu-core = { git = "https://github.com/${REPO}", rev = "${COMMIT}", features = ["trace", "replay", "serde"] }`, + // ) + // .replace( + // /^wgpu-types \= .*$/gm, + // `wgpu-types = { git = "https://github.com/${REPO}", rev = "${COMMIT}", features = ["trace", "replay", "serde"] }`, + // ) + ); +} + +async function patchSrcLib() { + await patchFile( + join(TARGET_DIR, "src", "lib.rs"), + (data) => + data.replace(`prefix "deno:deno_webgpu",`, `prefix "deno:ext/webgpu",`), + ); +} + +async function patchCopyrights() { + const walker = walk(TARGET_DIR, { includeDirs: false }); + for await (const entry of walker) { + await patchFile( + entry.path, + (data) => + data.replace(/^\/\/ Copyright 2018-2021/, "// Copyright 2018-2022"), + ); + } +} + +async function main() { + await clearTargetDir(); + await checkoutUpstream(); + await patchCargo(); + await patchSrcLib(); + await patchCopyrights(); + await bash(join(ROOT_PATH, "tools", "format.js")); +} + +await main();