1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-25 00:29:09 -05:00

revert(#13402): experiment: wgpu sync (#13439)

This commit is contained in:
Aaron O'Mullan 2022-01-20 15:23:53 +01:00 committed by GitHub
parent 1cc38f5155
commit 3ab68bd0a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1904 additions and 704 deletions

94
Cargo.lock generated
View file

@ -136,9 +136,9 @@ dependencies = [
[[package]] [[package]]
name = "ash" name = "ash"
version = "0.35.0+1.2.203" version = "0.33.3+1.2.191"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a7638ce84f8c84d6fd6faa63aa267574d345181ba591c0eeb5550d4c30cd600" checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219"
dependencies = [ dependencies = [
"libloading", "libloading",
] ]
@ -283,16 +283,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 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]] [[package]]
name = "block" name = "block"
version = "0.1.6" version = "0.1.6"
@ -1438,6 +1428,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "fixedbitset"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e"
[[package]] [[package]]
name = "flaky_test" name = "flaky_test"
version = "0.1.0" version = "0.1.0"
@ -1801,12 +1797,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hexf-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]] [[package]]
name = "hmac" name = "hmac"
version = "0.11.0" version = "0.11.0"
@ -2317,7 +2307,8 @@ dependencies = [
[[package]] [[package]]
name = "metal" name = "metal"
version = "0.23.1" version = "0.23.1"
source = "git+https://github.com/gfx-rs/metal-rs?rev=140c8f4#140c8f4e39001ae154f153ffc767da6c0c9d7f06" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"block", "block",
@ -2367,17 +2358,17 @@ dependencies = [
[[package]] [[package]]
name = "naga" name = "naga"
version = "0.8.0" version = "0.6.3"
source = "git+https://github.com/gfx-rs/naga?rev=a1840be#a1840beb1a96c9a49980fe3efa8e2f3dcd88abe6" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c5859e55c51da10b98e7a73068e0a0c5da7bbcae4fc38f86043d0c6d1b917cf"
dependencies = [ dependencies = [
"bit-set", "bit-set",
"bitflags", "bitflags",
"codespan-reporting", "codespan-reporting",
"hexf-parse", "fxhash",
"indexmap",
"log", "log",
"num-traits", "num-traits",
"rustc-hash", "petgraph 0.6.0",
"serde", "serde",
"spirv", "spirv",
"thiserror", "thiserror",
@ -2669,7 +2660,17 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [ dependencies = [
"fixedbitset", "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",
"indexmap", "indexmap",
] ]
@ -3037,6 +3038,16 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" 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]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"
version = "0.4.2" version = "0.4.2"
@ -3172,9 +3183,9 @@ dependencies = [
[[package]] [[package]]
name = "ron" name = "ron"
version = "0.7.0" version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"bitflags", "bitflags",
@ -3719,7 +3730,7 @@ dependencies = [
"is-macro", "is-macro",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
"petgraph", "petgraph 0.5.1",
"radix_fmt", "radix_fmt",
"relative-path", "relative-path",
"retain_mut", "retain_mut",
@ -4070,7 +4081,7 @@ checksum = "1d53bbcbb4b055c547f283af1f84211f425b95ac59e02d8b70c94b8a63a4704f"
dependencies = [ dependencies = [
"ahash", "ahash",
"indexmap", "indexmap",
"petgraph", "petgraph 0.5.1",
"swc_common", "swc_common",
] ]
@ -4082,7 +4093,7 @@ checksum = "83b42a8b13068dd90dec954ec44576d5922914687bc34277f3b0f8d0bbeb4e83"
dependencies = [ dependencies = [
"ahash", "ahash",
"auto_impl", "auto_impl",
"petgraph", "petgraph 0.5.1",
"swc_fast_graph", "swc_fast_graph",
"tracing", "tracing",
] ]
@ -4892,13 +4903,13 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.12.0" version = "0.10.4"
source = "git+https://github.com/gfx-rs/wgpu?rev=cdd480a89c9e3b681d9d174e65082d2bdbc903ef#cdd480a89c9e3b681d9d174e65082d2bdbc903ef" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f963c62473a36e3cef6c58181f2ed6d0d38d2043d970dbed46cb197190090c99"
dependencies = [ dependencies = [
"arrayvec 0.7.2", "arrayvec 0.7.2",
"bitflags", "bitflags",
"cfg_aliases", "cfg_aliases",
"codespan-reporting",
"copyless", "copyless",
"fxhash", "fxhash",
"log", "log",
@ -4915,8 +4926,9 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-hal" name = "wgpu-hal"
version = "0.12.0" version = "0.10.7"
source = "git+https://github.com/gfx-rs/wgpu?rev=cdd480a89c9e3b681d9d174e65082d2bdbc903ef#cdd480a89c9e3b681d9d174e65082d2bdbc903ef" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27cd894b17bff1958ee93da1cc991fd64bf99667746d4bd2a7403855f4d37fe2"
dependencies = [ dependencies = [
"arrayvec 0.7.2", "arrayvec 0.7.2",
"ash", "ash",
@ -4931,7 +4943,6 @@ dependencies = [
"gpu-alloc", "gpu-alloc",
"gpu-descriptor", "gpu-descriptor",
"inplace_it", "inplace_it",
"js-sys",
"khronos-egl", "khronos-egl",
"libloading", "libloading",
"log", "log",
@ -4939,24 +4950,21 @@ dependencies = [
"naga", "naga",
"objc", "objc",
"parking_lot", "parking_lot",
"profiling",
"range-alloc", "range-alloc",
"raw-window-handle", "raw-window-handle 0.3.4",
"renderdoc-sys", "renderdoc-sys",
"thiserror", "thiserror",
"wasm-bindgen",
"web-sys",
"wgpu-types", "wgpu-types",
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]] [[package]]
name = "wgpu-types" name = "wgpu-types"
version = "0.12.0" version = "0.10.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=cdd480a89c9e3b681d9d174e65082d2bdbc903ef#cdd480a89c9e3b681d9d174e65082d2bdbc903ef" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25feb2fbf24ab3219a9f10890ceb8e1ef02b13314ed89d64a9ae99dcad883e18"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"bitflags_serde_shim",
"serde", "serde",
] ]

View file

@ -82,7 +82,7 @@ fn create_compiler_snapshot(
op_crate_libs.insert("deno.url", deno_url::get_declaration()); 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.web", deno_web::get_declaration());
op_crate_libs.insert("deno.fetch", deno_fetch::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.websocket", deno_websocket::get_declaration());
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration()); op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration()); op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
@ -322,7 +322,7 @@ fn main() {
); );
println!( println!(
"cargo:rustc-env=DENO_WEBGPU_LIB_PATH={}", "cargo:rustc-env=DENO_WEBGPU_LIB_PATH={}",
deno_webgpu_get_declaration().display() deno_webgpu::get_declaration().display()
); );
println!( println!(
"cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}", "cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}",
@ -369,11 +369,6 @@ 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<PathBuf> { fn get_js_files(d: &str) -> Vec<PathBuf> {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut js_files = std::fs::read_dir(d) let mut js_files = std::fs::read_dir(d)

View file

@ -1,10 +1,9 @@
[[block]]
struct PrimeIndices { struct PrimeIndices {
data: [[stride(4)]] array<u32>; data: [[stride(4)]] array<u32>;
}; // this is used as both input and output for convenience }; // this is used as both input and output for convenience
[[group(0), binding(0)]] [[group(0), binding(0)]]
var<storage, read_write> v_indices: PrimeIndices; var<storage, read_write> v_indices: PrimeIndices;
// The Collatz Conjecture states that for any integer n: // The Collatz Conjecture states that for any integer n:
// If n is even, n = n/2 // If n is even, n = n/2
// If n is odd, n = 3n+1 // If n is odd, n = 3n+1
@ -26,14 +25,12 @@ fn collatz_iterations(n_base: u32) -> u32{
if (n >= 1431655765u) { // 0x55555555u if (n >= 1431655765u) { // 0x55555555u
return 4294967295u; // 0xffffffffu return 4294967295u; // 0xffffffffu
} }
n = 3u * n + 1u; n = 3u * n + 1u;
} }
i = i + 1u; i = i + 1u;
} }
return i; return i;
} }
[[stage(compute), workgroup_size(1)]] [[stage(compute), workgroup_size(1)]]
fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) { fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) {
v_indices.data[global_id.x] = collatz_iterations(v_indices.data[global_id.x]); v_indices.data[global_id.x] = collatz_iterations(v_indices.data[global_id.x]);

View file

@ -33,14 +33,13 @@ Deno.test({
const stagingBuffer = device.createBuffer({ const stagingBuffer = device.createBuffer({
size: size, size: size,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, usage: 1 | 8,
}); });
const storageBuffer = device.createBuffer({ const storageBuffer = device.createBuffer({
label: "Storage Buffer", label: "Storage Buffer",
size: size, size: size,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | usage: 0x80 | 8 | 4,
GPUBufferUsage.COPY_SRC,
mappedAtCreation: true, mappedAtCreation: true,
}); });

View file

@ -3060,48 +3060,6 @@
device.pushError(err); 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 * @param {string} groupLabel
*/ */
@ -3245,7 +3203,7 @@
prefix, prefix,
context: "Argument 3", context: "Argument 3",
}); });
destination = webidl.converters.GPUBuffer(destination, { destination = webidl.converters.GPUQuerySet(destination, {
prefix, prefix,
context: "Argument 4", context: "Argument 4",
}); });
@ -4569,10 +4527,15 @@
webidl.illegalConstructor(); webidl.illegalConstructor();
} }
get executionTime() {
throw new Error("Not yet implemented");
}
[SymbolFor("Deno.privateCustomInspect")](inspect) { [SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${ return `${this.constructor.name} ${
inspect({ inspect({
label: this.label, label: this.label,
// TODO(crowlKats): executionTime
}) })
}`; }`;
} }

View file

@ -111,35 +111,28 @@
webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
"GPUFeatureName", "GPUFeatureName",
[ [
"depth-clip-control", "depth-clamping",
"depth24unorm-stencil8", "depth24unorm-stencil8",
"depth32float-stencil8", "depth32float-stencil8",
"pipeline-statistics-query", "pipeline-statistics-query",
"texture-compression-bc", "texture-compression-bc",
"texture-compression-etc2",
"texture-compression-astc",
"timestamp-query", "timestamp-query",
"indirect-first-instance",
// extended from spec // extended from spec
"mappable-primary-buffers", "mappable-primary-buffers",
"texture-binding-array", "sampled-texture-binding-array",
"buffer-binding-array", "sampled-texture-array-dynamic-indexing",
"storage-resource-binding-array", "sampled-texture-array-non-uniform-indexing",
"sampled-texture-and-storage-buffer-array-non-uniform-indexing",
"uniform-buffer-and-storage-buffer-texture-non-uniform-indexing",
"unsized-binding-array", "unsized-binding-array",
"multi-draw-indirect", "multi-draw-indirect",
"multi-draw-indirect-count", "multi-draw-indirect-count",
"push-constants", "push-constants",
"address-mode-clamp-to-border", "address-mode-clamp-to-border",
"non-fill-polygon-mode",
"texture-compression-etc2",
"texture-compression-astc-ldr",
"texture-adapter-specific-format-features", "texture-adapter-specific-format-features",
"shader-float64", "shader-float64",
"vertex-attribute-64bit", "vertex-attribute-64bit",
"conservative-rasterization",
"vertex-writable-storage",
"clear-commands",
"spirv-shader-passthrough",
"shader-primitive-index",
], ],
); );
@ -355,44 +348,6 @@
"bc6h-rgb-float", "bc6h-rgb-float",
"bc7-rgba-unorm", "bc7-rgba-unorm",
"bc7-rgba-unorm-srgb", "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", "depth24unorm-stencil8",
"depth32float-stencil8", "depth32float-stencil8",
], ],
@ -1176,7 +1131,7 @@
defaultValue: "none", defaultValue: "none",
}, },
{ {
key: "unclippedDepth", key: "clampDepth",
converter: webidl.converters["boolean"], converter: webidl.converters["boolean"],
defaultValue: false, defaultValue: false,
}, },
@ -1503,7 +1458,13 @@
); );
// DICTIONARY: GPUCommandEncoderDescriptor // DICTIONARY: GPUCommandEncoderDescriptor
const dictMembersGPUCommandEncoderDescriptor = []; const dictMembersGPUCommandEncoderDescriptor = [
{
key: "measureExecutionTime",
converter: webidl.converters["boolean"],
defaultValue: false,
},
];
webidl.converters["GPUCommandEncoderDescriptor"] = webidl webidl.converters["GPUCommandEncoderDescriptor"] = webidl
.createDictionaryConverter( .createDictionaryConverter(
"GPUCommandEncoderDescriptor", "GPUCommandEncoderDescriptor",

View file

@ -7,12 +7,15 @@ authors = ["the Deno authors"]
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"
repository = "https://github.com/gfx-rs/wgpu" repository = "https://github.com/denoland/deno"
description = "WebGPU implementation for Deno" description = "WebGPU implementation for Deno"
[lib]
path = "lib.rs"
[dependencies] [dependencies]
deno_core = { version = "0.114.0", path = "../../core" } deno_core = { version = "0.114.0", path = "../../core" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0.129", features = ["derive"] }
tokio = { version = "1.10", features = ["full"] } tokio = { version = "1.10.1", features = ["full"] }
wgpu-core = { git = "https://github.com/gfx-rs/wgpu", rev = "cdd480a89c9e3b681d9d174e65082d2bdbc903ef", features = ["trace", "replay", "serde"] } wgpu-core = { version = "0.10.1", features = ["trace"] }
wgpu-types = { git = "https://github.com/gfx-rs/wgpu", rev = "cdd480a89c9e3b681d9d174e65082d2bdbc903ef", features = ["trace", "replay", "serde"] } wgpu-types = "0.10.0"

View file

@ -5,7 +5,8 @@ use deno_core::ResourceId;
use deno_core::{OpState, Resource}; use deno_core::{OpState, Resource};
use serde::Deserialize; use serde::Deserialize;
use std::borrow::Cow; use std::borrow::Cow;
use std::convert::{TryFrom, TryInto};
use crate::texture::{GpuTextureFormat, GpuTextureViewDimension};
use super::error::WebGpuResult; use super::error::WebGpuResult;
@ -58,14 +59,41 @@ impl From<GpuBufferBindingType> for wgpu_types::BufferBindingType {
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct GpuSamplerBindingLayout { struct GpuSamplerBindingLayout {
r#type: wgpu_types::SamplerBindingType, r#type: GpuSamplerBindingType,
}
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuSamplerBindingType {
Filtering,
NonFiltering,
Comparison,
}
impl From<GpuSamplerBindingType> 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,
},
}
}
} }
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct GpuTextureBindingLayout { struct GpuTextureBindingLayout {
sample_type: GpuTextureSampleType, sample_type: GpuTextureSampleType,
view_dimension: wgpu_types::TextureViewDimension, view_dimension: GpuTextureViewDimension,
multisampled: bool, multisampled: bool,
} }
@ -99,8 +127,8 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout { struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess, access: GpuStorageTextureAccess,
format: wgpu_types::TextureFormat, format: GpuTextureFormat,
view_dimension: wgpu_types::TextureViewDimension, view_dimension: GpuTextureViewDimension,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -149,19 +177,17 @@ impl TryFrom<GpuBindingType> for wgpu_types::BindingType {
has_dynamic_offset: buffer.has_dynamic_offset, has_dynamic_offset: buffer.has_dynamic_offset,
min_binding_size: std::num::NonZeroU64::new(buffer.min_binding_size), min_binding_size: std::num::NonZeroU64::new(buffer.min_binding_size),
}, },
GpuBindingType::Sampler(sampler) => { GpuBindingType::Sampler(sampler) => sampler.r#type.into(),
wgpu_types::BindingType::Sampler(sampler.r#type)
}
GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture { GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture {
sample_type: texture.sample_type.into(), sample_type: texture.sample_type.into(),
view_dimension: texture.view_dimension, view_dimension: texture.view_dimension.into(),
multisampled: texture.multisampled, multisampled: texture.multisampled,
}, },
GpuBindingType::StorageTexture(storage_texture) => { GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture { wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(), access: storage_texture.access.into(),
format: storage_texture.format, format: storage_texture.format.try_into()?,
view_dimension: storage_texture.view_dimension, view_dimension: storage_texture.view_dimension.into(),
} }
} }
}; };

View file

@ -9,6 +9,9 @@ use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::pipeline::GpuIndexFormat;
use crate::texture::GpuTextureFormat;
use super::error::WebGpuResult; use super::error::WebGpuResult;
struct WebGpuRenderBundleEncoder( struct WebGpuRenderBundleEncoder(
@ -32,8 +35,8 @@ impl Resource for WebGpuRenderBundle {
pub struct CreateRenderBundleEncoderArgs { pub struct CreateRenderBundleEncoderArgs {
device_rid: ResourceId, device_rid: ResourceId,
label: Option<String>, label: Option<String>,
color_formats: Vec<wgpu_types::TextureFormat>, color_formats: Vec<GpuTextureFormat>,
depth_stencil_format: Option<wgpu_types::TextureFormat>, depth_stencil_format: Option<GpuTextureFormat>,
sample_count: u32, sample_count: u32,
depth_read_only: bool, depth_read_only: bool,
stencil_read_only: bool, stencil_read_only: bool,
@ -52,12 +55,12 @@ pub fn op_webgpu_create_render_bundle_encoder(
let mut color_formats = vec![]; let mut color_formats = vec![];
for format in args.color_formats { for format in args.color_formats {
color_formats.push(format); color_formats.push(format.try_into()?);
} }
let depth_stencil = if let Some(format) = args.depth_stencil_format { let depth_stencil = if let Some(format) = args.depth_stencil_format {
Some(wgpu_types::RenderBundleDepthStencil { Some(wgpu_types::RenderBundleDepthStencil {
format, format: format.try_into()?,
depth_read_only: args.depth_read_only, depth_read_only: args.depth_read_only,
stencil_read_only: args.stencil_read_only, stencil_read_only: args.stencil_read_only,
}) })
@ -70,7 +73,6 @@ pub fn op_webgpu_create_render_bundle_encoder(
color_formats: Cow::from(color_formats), color_formats: Cow::from(color_formats),
sample_count: args.sample_count, sample_count: args.sample_count,
depth_stencil, depth_stencil,
multiview: None,
}; };
let res = let res =
@ -299,7 +301,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline(
pub struct RenderBundleEncoderSetIndexBufferArgs { pub struct RenderBundleEncoderSetIndexBufferArgs {
render_bundle_encoder_rid: ResourceId, render_bundle_encoder_rid: ResourceId,
buffer: ResourceId, buffer: ResourceId,
index_format: wgpu_types::IndexFormat, index_format: GpuIndexFormat,
offset: u64, offset: u64,
size: u64, size: u64,
} }
@ -322,7 +324,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
.borrow_mut() .borrow_mut()
.set_index_buffer( .set_index_buffer(
buffer_resource.0, buffer_resource.0,
args.index_format, args.index_format.into(),
args.offset, args.offset,
std::num::NonZeroU64::new(args.size), std::num::NonZeroU64::new(args.size),
); );

View file

@ -8,6 +8,8 @@ use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use crate::texture::GpuTextureAspect;
use super::error::WebGpuResult; use super::error::WebGpuResult;
pub(crate) struct WebGpuCommandEncoder( pub(crate) struct WebGpuCommandEncoder(
@ -63,8 +65,8 @@ pub fn op_webgpu_create_command_encoder(
pub struct GpuRenderPassColorAttachment { pub struct GpuRenderPassColorAttachment {
view: ResourceId, view: ResourceId,
resolve_target: Option<ResourceId>, resolve_target: Option<ResourceId>,
load_op: GpuLoadOp<wgpu_types::Color>, load_op: GpuLoadOp<super::render_pass::GpuColor>,
store_op: wgpu_core::command::StoreOp, store_op: GpuStoreOp,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -74,15 +76,31 @@ enum GpuLoadOp<T> {
Clear(T), Clear(T),
} }
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuStoreOp {
Store,
Discard,
}
impl From<GpuStoreOp> 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)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct GpuRenderPassDepthStencilAttachment { struct GpuRenderPassDepthStencilAttachment {
view: ResourceId, view: ResourceId,
depth_load_op: GpuLoadOp<f32>, depth_load_op: GpuLoadOp<f32>,
depth_store_op: wgpu_core::command::StoreOp, depth_store_op: GpuStoreOp,
depth_read_only: bool, depth_read_only: bool,
stencil_load_op: GpuLoadOp<u32>, stencil_load_op: GpuLoadOp<u32>,
stencil_store_op: wgpu_core::command::StoreOp, stencil_store_op: GpuStoreOp,
stencil_read_only: bool, stencil_read_only: bool,
} }
@ -129,14 +147,19 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
channel: match color_attachment.load_op { channel: match color_attachment.load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel { GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load, load_op: wgpu_core::command::LoadOp::Load,
store_op: color_attachment.store_op, store_op: color_attachment.store_op.into(),
clear_value: Default::default(), clear_value: Default::default(),
read_only: false, read_only: false,
}, },
GpuLoadOp::Clear(color) => wgpu_core::command::PassChannel { GpuLoadOp::Clear(color) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear, load_op: wgpu_core::command::LoadOp::Clear,
store_op: color_attachment.store_op, store_op: color_attachment.store_op.into(),
clear_value: color, clear_value: wgpu_types::Color {
r: color.r,
g: color.g,
b: color.b,
a: color.a,
},
read_only: false, read_only: false,
}, },
}, },
@ -159,13 +182,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
depth: match attachment.depth_load_op { depth: match attachment.depth_load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel { GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load, load_op: wgpu_core::command::LoadOp::Load,
store_op: attachment.depth_store_op, store_op: attachment.depth_store_op.into(),
clear_value: 0.0, clear_value: 0.0,
read_only: attachment.depth_read_only, read_only: attachment.depth_read_only,
}, },
GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear, load_op: wgpu_core::command::LoadOp::Clear,
store_op: attachment.depth_store_op, store_op: attachment.depth_store_op.into(),
clear_value: value, clear_value: value,
read_only: attachment.depth_read_only, read_only: attachment.depth_read_only,
}, },
@ -173,13 +196,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
stencil: match attachment.stencil_load_op { stencil: match attachment.stencil_load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel { GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load, load_op: wgpu_core::command::LoadOp::Load,
store_op: attachment.stencil_store_op, store_op: attachment.stencil_store_op.into(),
clear_value: 0, clear_value: 0,
read_only: attachment.stencil_read_only, read_only: attachment.stencil_read_only,
}, },
GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear, load_op: wgpu_core::command::LoadOp::Clear,
store_op: attachment.stencil_store_op, store_op: attachment.stencil_store_op.into(),
clear_value: value, clear_value: value,
read_only: attachment.stencil_read_only, read_only: attachment.stencil_read_only,
}, },
@ -292,13 +315,31 @@ pub struct GpuImageCopyBuffer {
rows_per_image: Option<u32>, rows_per_image: Option<u32>,
} }
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuOrigin3D {
pub x: u32,
pub y: u32,
pub z: u32,
}
impl From<GpuOrigin3D> 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)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct GpuImageCopyTexture { pub struct GpuImageCopyTexture {
pub texture: ResourceId, pub texture: ResourceId,
pub mip_level: u32, pub mip_level: u32,
pub origin: wgpu_types::Origin3d, pub origin: GpuOrigin3D,
pub aspect: wgpu_types::TextureAspect, pub aspect: GpuTextureAspect,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -307,7 +348,7 @@ pub struct CommandEncoderCopyBufferToTextureArgs {
command_encoder_rid: ResourceId, command_encoder_rid: ResourceId,
source: GpuImageCopyBuffer, source: GpuImageCopyBuffer,
destination: GpuImageCopyTexture, destination: GpuImageCopyTexture,
copy_size: wgpu_types::Extent3d, copy_size: super::texture::GpuExtent3D,
} }
pub fn op_webgpu_command_encoder_copy_buffer_to_texture( pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
@ -340,14 +381,14 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
let destination = wgpu_core::command::ImageCopyTexture { let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0, texture: destination_texture_resource.0,
mip_level: args.destination.mip_level, mip_level: args.destination.mip_level,
origin: args.destination.origin, origin: args.destination.origin.into(),
aspect: args.destination.aspect, aspect: args.destination.aspect.into(),
}; };
gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture( gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture(
command_encoder, command_encoder,
&source, &source,
&destination, &destination,
&args.copy_size &args.copy_size.into()
)) ))
} }
@ -357,7 +398,7 @@ pub struct CommandEncoderCopyTextureToBufferArgs {
command_encoder_rid: ResourceId, command_encoder_rid: ResourceId,
source: GpuImageCopyTexture, source: GpuImageCopyTexture,
destination: GpuImageCopyBuffer, destination: GpuImageCopyBuffer,
copy_size: wgpu_types::Extent3d, copy_size: super::texture::GpuExtent3D,
} }
pub fn op_webgpu_command_encoder_copy_texture_to_buffer( pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
@ -382,8 +423,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
let source = wgpu_core::command::ImageCopyTexture { let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0, texture: source_texture_resource.0,
mip_level: args.source.mip_level, mip_level: args.source.mip_level,
origin: args.source.origin, origin: args.source.origin.into(),
aspect: args.source.aspect, aspect: args.source.aspect.into(),
}; };
let destination = wgpu_core::command::ImageCopyBuffer { let destination = wgpu_core::command::ImageCopyBuffer {
buffer: destination_buffer_resource.0, buffer: destination_buffer_resource.0,
@ -401,7 +442,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
command_encoder, command_encoder,
&source, &source,
&destination, &destination,
&args.copy_size &args.copy_size.into()
)) ))
} }
@ -411,7 +452,7 @@ pub struct CommandEncoderCopyTextureToTextureArgs {
command_encoder_rid: ResourceId, command_encoder_rid: ResourceId,
source: GpuImageCopyTexture, source: GpuImageCopyTexture,
destination: GpuImageCopyTexture, destination: GpuImageCopyTexture,
copy_size: wgpu_types::Extent3d, copy_size: super::texture::GpuExtent3D,
} }
pub fn op_webgpu_command_encoder_copy_texture_to_texture( pub fn op_webgpu_command_encoder_copy_texture_to_texture(
@ -436,51 +477,20 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture(
let source = wgpu_core::command::ImageCopyTexture { let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0, texture: source_texture_resource.0,
mip_level: args.source.mip_level, mip_level: args.source.mip_level,
origin: args.source.origin, origin: args.source.origin.into(),
aspect: args.source.aspect, aspect: args.source.aspect.into(),
}; };
let destination = wgpu_core::command::ImageCopyTexture { let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0, texture: destination_texture_resource.0,
mip_level: args.destination.mip_level, mip_level: args.destination.mip_level,
origin: args.destination.origin, origin: args.destination.origin.into(),
aspect: args.destination.aspect, aspect: args.destination.aspect.into(),
}; };
gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture( gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture(
command_encoder, command_encoder,
&source, &source,
&destination, &destination,
&args.copy_size &args.copy_size.into()
))
}
#[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<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(args.command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let destination_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(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)
)) ))
} }

View file

@ -8,7 +8,6 @@ use wgpu_core::binding_model::CreateBindGroupError;
use wgpu_core::binding_model::CreateBindGroupLayoutError; use wgpu_core::binding_model::CreateBindGroupLayoutError;
use wgpu_core::binding_model::CreatePipelineLayoutError; use wgpu_core::binding_model::CreatePipelineLayoutError;
use wgpu_core::binding_model::GetBindGroupLayoutError; use wgpu_core::binding_model::GetBindGroupLayoutError;
use wgpu_core::command::ClearError;
use wgpu_core::command::CommandEncoderError; use wgpu_core::command::CommandEncoderError;
use wgpu_core::command::ComputePassError; use wgpu_core::command::ComputePassError;
use wgpu_core::command::CopyError; use wgpu_core::command::CopyError;
@ -259,12 +258,6 @@ impl From<QueueWriteError> for WebGpuError {
} }
} }
impl From<ClearError> for WebGpuError {
fn from(err: ClearError) -> Self {
WebGpuError::Validation(err.to_string())
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct DomExceptionOperationError { pub struct DomExceptionOperationError {
pub msg: String, pub msg: String,

View file

@ -92,15 +92,12 @@ declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase {
} }
declare type GPUFeatureName = declare type GPUFeatureName =
| "depth-clip-control" | "depth-clamping"
| "depth24unorm-stencil8" | "depth24unorm-stencil8"
| "depth32float-stencil8" | "depth32float-stencil8"
| "pipeline-statistics-query" | "pipeline-statistics-query"
| "texture-compression-bc" | "texture-compression-bc"
| "texture-compression-etc2"
| "texture-compression-astc"
| "timestamp-query" | "timestamp-query"
| "indirect-first-instance"
// extended from spec // extended from spec
| "mappable-primary-buffers" | "mappable-primary-buffers"
| "sampled-texture-binding-array" | "sampled-texture-binding-array"
@ -111,6 +108,9 @@ declare type GPUFeatureName =
| "multi-draw-indirect-count" | "multi-draw-indirect-count"
| "push-constants" | "push-constants"
| "address-mode-clamp-to-border" | "address-mode-clamp-to-border"
| "non-fill-polygon-mode"
| "texture-compression-etc2"
| "texture-compression-astc-ldr"
| "texture-adapter-specific-format-features" | "texture-adapter-specific-format-features"
| "shader-float64" | "shader-float64"
| "vertex-attribute-64bit"; | "vertex-attribute-64bit";
@ -314,44 +314,6 @@ declare type GPUTextureFormat =
| "bc6h-rgb-float" | "bc6h-rgb-float"
| "bc7-rgba-unorm" | "bc7-rgba-unorm"
| "bc7-rgba-unorm-srgb" | "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" | "depth24unorm-stencil8"
| "depth32float-stencil8"; | "depth32float-stencil8";
@ -557,7 +519,7 @@ declare interface GPUPrimitiveState {
stripIndexFormat?: GPUIndexFormat; stripIndexFormat?: GPUIndexFormat;
frontFace?: GPUFrontFace; frontFace?: GPUFrontFace;
cullMode?: GPUCullMode; cullMode?: GPUCullMode;
unclippedDepth?: boolean; clampDepth?: boolean;
} }
declare type GPUFrontFace = "ccw" | "cw"; declare type GPUFrontFace = "ccw" | "cw";
@ -596,9 +558,9 @@ declare class GPUColorWrite {
} }
declare interface GPUBlendComponent { declare interface GPUBlendComponent {
operation: GPUBlendOperation;
srcFactor: GPUBlendFactor; srcFactor: GPUBlendFactor;
dstFactor: GPUBlendFactor; dstFactor: GPUBlendFactor;
operation: GPUBlendOperation;
} }
declare type GPUBlendFactor = declare type GPUBlendFactor =
@ -711,6 +673,8 @@ declare interface GPUVertexAttribute {
declare class GPUCommandBuffer implements GPUObjectBase { declare class GPUCommandBuffer implements GPUObjectBase {
label: string | null; label: string | null;
readonly executionTime: Promise<number>;
} }
declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {} declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {}
@ -749,12 +713,6 @@ declare class GPUCommandEncoder implements GPUObjectBase {
copySize: GPUExtent3D, copySize: GPUExtent3D,
): undefined; ): undefined;
clearBuffer(
destination: GPUBuffer,
destinationOffset: number,
size: number,
): undefined;
pushDebugGroup(groupLabel: string): undefined; pushDebugGroup(groupLabel: string): undefined;
popDebugGroup(): undefined; popDebugGroup(): undefined;
insertDebugMarker(markerLabel: string): undefined; insertDebugMarker(markerLabel: string): undefined;
@ -772,7 +730,9 @@ declare class GPUCommandEncoder implements GPUObjectBase {
finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer; finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer;
} }
declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {} declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {
measureExecutionTime?: boolean;
}
declare interface GPUImageDataLayout { declare interface GPUImageDataLayout {
offset?: number; offset?: number;

View file

@ -14,6 +14,7 @@ use serde::Serialize;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
pub use wgpu_core; pub use wgpu_core;
pub use wgpu_types; pub use wgpu_types;
@ -124,11 +125,15 @@ pub fn init(unstable: bool) -> Extension {
.build() .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> { fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
let mut return_features: Vec<&'static str> = vec![]; let mut return_features: Vec<&'static str> = vec![];
if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { if features.contains(wgpu_types::Features::DEPTH_CLAMPING) {
return_features.push("depth-clip-control"); return_features.push("depth-clamping");
} }
if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) {
return_features.push("pipeline-statistics-query"); return_features.push("pipeline-statistics-query");
@ -136,18 +141,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) {
return_features.push("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) { if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) {
return_features.push("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 // extended from spec
if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) {
@ -162,14 +158,10 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) { if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) {
return_features.push("storage-resource-binding-array"); return_features.push("storage-resource-binding-array");
} }
if features.contains( if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING) {
wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
) {
return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing"); return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing");
} }
if features.contains( if features.contains(wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) {
wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
) {
return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"); return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing");
} }
if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) {
@ -187,6 +179,15 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) {
return_features.push("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 if features
.contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES)
{ {
@ -204,8 +205,8 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) { if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) {
return_features.push("vertex-writable-storage"); return_features.push("vertex-writable-storage");
} }
if features.contains(wgpu_types::Features::CLEAR_TEXTURE) { if features.contains(wgpu_types::Features::CLEAR_COMMANDS) {
return_features.push("clear-texture"); return_features.push("clear-commands");
} }
if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) { if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) {
return_features.push("spirv-shader-passthrough"); return_features.push("spirv-shader-passthrough");
@ -217,11 +218,28 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
return_features return_features
} }
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuPowerPreference {
LowPower,
HighPerformance,
}
impl From<GpuPowerPreference> 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)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RequestAdapterArgs { pub struct RequestAdapterArgs {
power_preference: Option<wgpu_types::PowerPreference>, power_preference: Option<GpuPowerPreference>,
force_fallback_adapter: bool,
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -248,35 +266,31 @@ pub async fn op_webgpu_request_adapter(
) -> Result<GpuAdapterDeviceOrErr, AnyError> { ) -> Result<GpuAdapterDeviceOrErr, AnyError> {
let mut state = state.borrow_mut(); let mut state = state.borrow_mut();
check_unstable(&state, "navigator.gpu.requestAdapter"); 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>() { let instance = if let Some(instance) = state.try_borrow::<Instance>() {
instance instance
} else { } else {
state.put(wgpu_core::hub::Global::new( state.put(wgpu_core::hub::Global::new(
"webgpu", "webgpu",
wgpu_core::hub::IdentityManagerFactory, wgpu_core::hub::IdentityManagerFactory,
backends, wgpu_types::Backends::PRIMARY,
)); ));
state.borrow::<Instance>() state.borrow::<Instance>()
}; };
let descriptor = wgpu_core::instance::RequestAdapterOptions { let descriptor = wgpu_core::instance::RequestAdapterOptions {
power_preference: match args.power_preference { power_preference: match args.power_preference {
Some(power_preference) => power_preference, Some(power_preference) => power_preference.into(),
None => PowerPreference::default(), None => PowerPreference::default(),
}, },
force_fallback_adapter: args.force_fallback_adapter, // TODO(lucacasonato): respect forceFallbackAdapter
compatible_surface: None, // windowless compatible_surface: None, // windowless
}; };
let res = instance.request_adapter( let res = instance.request_adapter(
&descriptor, &descriptor,
wgpu_core::instance::AdapterInputs::Mask(backends, |_| { wgpu_core::instance::AdapterInputs::Mask(
std::marker::PhantomData wgpu_types::Backends::PRIMARY,
}), |_| std::marker::PhantomData,
),
); );
let adapter = match res { let adapter = match res {
@ -305,13 +319,116 @@ pub async fn op_webgpu_request_adapter(
})) }))
} }
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuLimits {
max_texture_dimension_1d: Option<u32>,
max_texture_dimension_2d: Option<u32>,
max_texture_dimension_3d: Option<u32>,
max_texture_array_layers: Option<u32>,
max_bind_groups: Option<u32>,
max_dynamic_uniform_buffers_per_pipeline_layout: Option<u32>,
max_dynamic_storage_buffers_per_pipeline_layout: Option<u32>,
max_sampled_textures_per_shader_stage: Option<u32>,
max_samplers_per_shader_stage: Option<u32>,
max_storage_buffers_per_shader_stage: Option<u32>,
max_storage_textures_per_shader_stage: Option<u32>,
max_uniform_buffers_per_shader_stage: Option<u32>,
max_uniform_buffer_binding_size: Option<u32>, // TODO(@crowlkats): u64
max_storage_buffer_binding_size: Option<u32>, // TODO(@crowlkats): u64
// min_uniform_buffer_offset_alignment: Option<u32>,
// min_storage_buffer_offset_alignment: Option<u32>,
max_vertex_buffers: Option<u32>,
max_vertex_attributes: Option<u32>,
max_vertex_buffer_array_stride: Option<u32>,
// max_inter_stage_shader_components: Option<u32>,
// max_compute_workgroup_storage_size: Option<u32>,
// max_compute_invocations_per_workgroup: Option<u32>,
// max_compute_workgroup_size_x: Option<u32>,
// max_compute_workgroup_size_y: Option<u32>,
// max_compute_workgroup_size_z: Option<u32>,
// max_compute_workgroups_per_dimension: Option<u32>,
}
impl From<GpuLimits> 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)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RequestDeviceArgs { pub struct RequestDeviceArgs {
adapter_rid: ResourceId, adapter_rid: ResourceId,
label: Option<String>, label: Option<String>,
required_features: Option<GpuRequiredFeatures>, required_features: Option<GpuRequiredFeatures>,
required_limits: Option<wgpu_types::Limits>, required_limits: Option<GpuLimits>,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -320,120 +437,101 @@ pub struct GpuRequiredFeatures(HashSet<String>);
impl From<GpuRequiredFeatures> for wgpu_types::Features { impl From<GpuRequiredFeatures> for wgpu_types::Features {
fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features { fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features {
let mut features: wgpu_types::Features = wgpu_types::Features::empty(); let mut features: wgpu_types::Features = wgpu_types::Features::empty();
features.set(
wgpu_types::Features::DEPTH_CLIP_CONTROL, if required_features.0.contains("depth-clamping") {
required_features.0.contains("depth-clip-control"), features.set(wgpu_types::Features::DEPTH_CLAMPING, true);
); }
features.set( if required_features.0.contains("pipeline-statistics-query") {
wgpu_types::Features::PIPELINE_STATISTICS_QUERY, features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true);
required_features.0.contains("pipeline-statistics-query"), }
); if required_features.0.contains("texture-compression-bc") {
features.set( features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true);
wgpu_types::Features::TEXTURE_COMPRESSION_BC, }
required_features.0.contains("texture-compression-bc"), if required_features.0.contains("timestamp-query") {
); features.set(wgpu_types::Features::TIMESTAMP_QUERY, true);
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 // extended from spec
features.set( if required_features.0.contains("mappable-primary-buffers") {
wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true);
required_features.0.contains("mappable-primary-buffers"), }
); if required_features.0.contains("texture-binding-array") {
features.set( features.set(wgpu_types::Features::TEXTURE_BINDING_ARRAY, true);
wgpu_types::Features::TEXTURE_BINDING_ARRAY, }
required_features.0.contains("texture-binding-array"), if required_features.0.contains("buffer-binding-array") {
); features.set(wgpu_types::Features::BUFFER_BINDING_ARRAY, true);
features.set( }
wgpu_types::Features::BUFFER_BINDING_ARRAY, if required_features
required_features.0.contains("buffer-binding-array"),
);
features.set(
wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY,
required_features
.0 .0
.contains("storage-resource-binding-array"), .contains("storage-resource-binding-array")
); {
features.set( features.set(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, true);
wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, }
required_features if required_features
.0 .0
.contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"), .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing")
); {
features.set( features.set(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, true);
wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, }
required_features 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 .0
.contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"), .contains("texture-adapter-specific-format-features")
); {
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( features.set(
wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
required_features true,
.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_TEXTURE,
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"),
); );
}
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 features
} }
@ -677,10 +775,6 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, 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_webgpu_command_encoder_push_debug_group",
op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group), op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group),
@ -801,22 +895,6 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
"op_webgpu_compute_pass_dispatch_indirect", "op_webgpu_compute_pass_dispatch_indirect",
op_sync(compute_pass::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_webgpu_compute_pass_end_pass",
op_sync(compute_pass::op_webgpu_compute_pass_end_pass), op_sync(compute_pass::op_webgpu_compute_pass_end_pass),

791
ext/webgpu/pipeline.rs Normal file
View file

@ -0,0 +1,791 @@
// 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<str> {
"webGPUPipelineLayout".into()
}
}
pub(crate) struct WebGpuComputePipeline(
pub(crate) wgpu_core::id::ComputePipelineId,
);
impl Resource for WebGpuComputePipeline {
fn name(&self) -> Cow<str> {
"webGPUComputePipeline".into()
}
}
pub(crate) struct WebGpuRenderPipeline(
pub(crate) wgpu_core::id::RenderPipelineId,
);
impl Resource for WebGpuRenderPipeline {
fn name(&self) -> Cow<str> {
"webGPURenderPipeline".into()
}
}
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum GpuIndexFormat {
Uint16,
Uint32,
}
impl From<GpuIndexFormat> 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<GPUStencilOperation> 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<GpuBlendFactor> 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<GpuBlendOperation> 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<GpuPrimitiveTopology> 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<GpuFrontFace> 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<GpuCullMode> for Option<wgpu_types::Face> {
fn from(value: GpuCullMode) -> Option<wgpu_types::Face> {
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<String, GPUPipelineConstantValue>
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateComputePipelineArgs {
device_rid: ResourceId,
label: Option<String>,
layout: Option<ResourceId>,
compute: GpuProgrammableStage,
}
pub fn op_webgpu_create_compute_pipeline(
state: &mut OpState,
args: CreateComputePipelineArgs,
_: (),
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let pipeline_layout = if let Some(rid) = args.layout {
let id = state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
Some(id.0)
} else {
None
};
let compute_shader_module_resource =
state
.resource_table
.get::<super::shader::WebGpuShaderModule>(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<WebGpuError>,
}
pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
state: &mut OpState,
args: ComputePipelineGetBindGroupLayoutArgs,
_: (),
) -> Result<PipelineLayout, AnyError> {
let instance = state.borrow::<super::Instance>();
let compute_pipeline_resource = state
.resource_table
.get::<WebGpuComputePipeline>(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<GpuIndexFormat>,
front_face: GpuFrontFace,
cull_mode: GpuCullMode,
clamp_depth: bool,
}
impl From<GpuPrimitiveState> 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<GpuBlendComponent> 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<GpuBlendState> 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<GpuBlendState>,
write_mask: u32,
}
impl TryFrom<GpuColorTargetState> for wgpu_types::ColorTargetState {
type Error = AnyError;
fn try_from(
state: GpuColorTargetState,
) -> Result<wgpu_types::ColorTargetState, AnyError> {
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<GpuStencilFaceState> 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<GpuDepthStencilState> for wgpu_types::DepthStencilState {
type Error = AnyError;
fn try_from(
state: GpuDepthStencilState,
) -> Result<wgpu_types::DepthStencilState, AnyError> {
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<GpuVertexAttribute> 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<GpuVertexFormat> 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<GpuVertexStepMode> 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<GpuVertexAttribute>,
}
impl<'a> From<GpuVertexBufferLayout>
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<Option<GpuVertexBufferLayout>>,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuMultisampleState {
count: u32,
mask: u64,
alpha_to_coverage_enabled: bool,
}
impl From<GpuMultisampleState> 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<GpuColorTargetState>,
module: u32,
entry_point: String,
// TODO(lucacasonato): constants
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateRenderPipelineArgs {
device_rid: ResourceId,
label: Option<String>,
layout: Option<ResourceId>,
vertex: GpuVertexState,
primitive: GpuPrimitiveState,
depth_stencil: Option<GpuDepthStencilState>,
multisample: GpuMultisampleState,
fragment: Option<GpuFragmentState>,
}
pub fn op_webgpu_create_render_pipeline(
state: &mut OpState,
args: CreateRenderPipelineArgs,
_: (),
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let layout = if let Some(rid) = args.layout {
let pipeline_layout_resource =
state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
Some(pipeline_layout_resource.0)
} else {
None
};
let vertex_shader_module_resource =
state
.resource_table
.get::<super::shader::WebGpuShaderModule>(args.vertex.module)?;
let fragment = if let Some(fragment) = args.fragment {
let fragment_shader_module_resource =
state
.resource_table
.get::<super::shader::WebGpuShaderModule>(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<PipelineLayout, AnyError> {
let instance = state.borrow::<super::Instance>();
let render_pipeline_resource = state
.resource_table
.get::<WebGpuRenderPipeline>(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),
})
}

View file

@ -108,7 +108,7 @@ pub struct QueueWriteTextureArgs {
queue_rid: ResourceId, queue_rid: ResourceId,
destination: super::command_encoder::GpuImageCopyTexture, destination: super::command_encoder::GpuImageCopyTexture,
data_layout: GpuImageDataLayout, data_layout: GpuImageDataLayout,
size: wgpu_types::Extent3d, size: super::texture::GpuExtent3D,
} }
pub fn op_webgpu_write_texture( pub fn op_webgpu_write_texture(
@ -127,8 +127,8 @@ pub fn op_webgpu_write_texture(
let destination = wgpu_core::command::ImageCopyTexture { let destination = wgpu_core::command::ImageCopyTexture {
texture: texture_resource.0, texture: texture_resource.0,
mip_level: args.destination.mip_level, mip_level: args.destination.mip_level,
origin: args.destination.origin, origin: args.destination.origin.into(),
aspect: args.destination.aspect, aspect: args.destination.aspect.into(),
}; };
let data_layout = args.data_layout.into(); let data_layout = args.data_layout.into();
@ -137,6 +137,6 @@ pub fn op_webgpu_write_texture(
&destination, &destination,
&*zero_copy, &*zero_copy,
&data_layout, &data_layout,
&args.size &args.size.into()
)) ))
} }

View file

@ -9,6 +9,8 @@ use serde::Deserialize;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use crate::pipeline::GpuIndexFormat;
use super::error::WebGpuResult; use super::error::WebGpuResult;
pub(crate) struct WebGpuRenderPass( pub(crate) struct WebGpuRenderPass(
@ -84,11 +86,20 @@ pub fn op_webgpu_render_pass_set_scissor_rect(
Ok(WebGpuResult::empty()) 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)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RenderPassSetBlendConstantArgs { pub struct RenderPassSetBlendConstantArgs {
render_pass_rid: ResourceId, render_pass_rid: ResourceId,
color: wgpu_types::Color, color: GpuColor,
} }
pub fn op_webgpu_render_pass_set_blend_constant( pub fn op_webgpu_render_pass_set_blend_constant(
@ -102,7 +113,12 @@ pub fn op_webgpu_render_pass_set_blend_constant(
wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant( wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant(
&mut render_pass_resource.0.borrow_mut(), &mut render_pass_resource.0.borrow_mut(),
&args.color, &wgpu_types::Color {
r: args.color.r,
g: args.color.g,
b: args.color.b,
a: args.color.a,
},
); );
Ok(WebGpuResult::empty()) Ok(WebGpuResult::empty())
@ -450,7 +466,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
pub struct RenderPassSetIndexBufferArgs { pub struct RenderPassSetIndexBufferArgs {
render_pass_rid: ResourceId, render_pass_rid: ResourceId,
buffer: u32, buffer: u32,
index_format: wgpu_types::IndexFormat, index_format: GpuIndexFormat,
offset: u64, offset: u64,
size: Option<u64>, size: Option<u64>,
} }
@ -478,7 +494,7 @@ pub fn op_webgpu_render_pass_set_index_buffer(
render_pass_resource.0.borrow_mut().set_index_buffer( render_pass_resource.0.borrow_mut().set_index_buffer(
buffer_resource.0, buffer_resource.0,
args.index_format, args.index_format.into(),
args.offset, args.offset,
size, size,
); );

132
ext/webgpu/sampler.rs Normal file
View file

@ -0,0 +1,132 @@
// 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<str> {
"webGPUSampler".into()
}
}
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuAddressMode {
ClampToEdge,
Repeat,
MirrorRepeat,
}
impl From<GpuAddressMode> 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<GpuFilterMode> 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<GpuCompareFunction> 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<String>,
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<GpuCompareFunction>,
max_anisotropy: u8,
}
pub fn op_webgpu_create_sampler(
state: &mut OpState,
args: CreateSamplerArgs,
_: (),
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(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)
}

View file

@ -40,7 +40,6 @@ pub fn op_webgpu_create_shader_module(
let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor {
label: args.label.map(Cow::from), label: args.label.map(Cow::from),
shader_bound_checks: wgpu_types::ShaderBoundChecks::default(),
}; };
gfx_put!(device => instance.device_create_shader_module( gfx_put!(device => instance.device_create_shader_module(

419
ext/webgpu/texture.rs Normal file
View file

@ -0,0 +1,419 @@
// 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<str> {
"webGPUTexture".into()
}
}
pub(crate) struct WebGpuTextureView(pub(crate) wgpu_core::id::TextureViewId);
impl Resource for WebGpuTextureView {
fn name(&self) -> Cow<str> {
"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<GpuTextureFormat> for wgpu_types::TextureFormat {
type Error = AnyError;
fn try_from(value: GpuTextureFormat) -> Result<Self, Self::Error> {
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<GpuTextureViewDimension> 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<GpuTextureDimension> 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<GpuTextureAspect> 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<GpuExtent3D> 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<String>,
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<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(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<String>,
format: Option<GpuTextureFormat>,
dimension: Option<GpuTextureViewDimension>,
aspect: GpuTextureAspect,
base_mip_level: u32,
mip_level_count: Option<u32>,
base_array_layer: u32,
array_layer_count: Option<u32>,
}
pub fn op_webgpu_create_texture_view(
state: &mut OpState,
args: CreateTextureViewArgs,
_: (),
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let texture_resource = state
.resource_table
.get::<WebGpuTexture>(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)
}

View file

@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase {
USVString label; USVString label;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUSupportedLimits { interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension1D; readonly attribute unsigned long maxTextureDimension1D;
readonly attribute unsigned long maxTextureDimension2D; readonly attribute unsigned long maxTextureDimension2D;
@ -36,7 +36,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxComputeWorkgroupsPerDimension; readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUSupportedFeatures { interface GPUSupportedFeatures {
readonly setlike<DOMString>; readonly setlike<DOMString>;
}; };
@ -46,12 +46,12 @@ enum GPUPredefinedColorSpace {
}; };
interface mixin NavigatorGPU { interface mixin NavigatorGPU {
[SameObject, SecureContext] readonly attribute GPU gpu; [SameObject] readonly attribute GPU gpu;
}; };
Navigator includes NavigatorGPU; Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU; WorkerNavigator includes NavigatorGPU;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPU { interface GPU {
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {}); Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
}; };
@ -63,10 +63,10 @@ dictionary GPURequestAdapterOptions {
enum GPUPowerPreference { enum GPUPowerPreference {
"low-power", "low-power",
"high-performance", "high-performance"
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUAdapter { interface GPUAdapter {
readonly attribute DOMString name; readonly attribute DOMString name;
[SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedFeatures features;
@ -82,18 +82,15 @@ dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
}; };
enum GPUFeatureName { enum GPUFeatureName {
"depth-clip-control", "depth-clamping",
"depth24unorm-stencil8", "depth24unorm-stencil8",
"depth32float-stencil8", "depth32float-stencil8",
"pipeline-statistics-query", "pipeline-statistics-query",
"texture-compression-bc", "texture-compression-bc",
"texture-compression-etc2",
"texture-compression-astc",
"timestamp-query", "timestamp-query",
"indirect-first-instance",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUDevice : EventTarget { interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits; [SameObject] readonly attribute GPUSupportedLimits limits;
@ -123,7 +120,7 @@ interface GPUDevice : EventTarget {
}; };
GPUDevice includes GPUObjectBase; GPUDevice includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUBuffer { interface GPUBuffer {
Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
@ -161,7 +158,7 @@ interface GPUMapMode {
const GPUFlagsConstant WRITE = 0x0002; const GPUFlagsConstant WRITE = 0x0002;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUTexture { interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@ -194,7 +191,7 @@ interface GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUTextureView { interface GPUTextureView {
}; };
GPUTextureView includes GPUObjectBase; GPUTextureView includes GPUObjectBase;
@ -215,13 +212,13 @@ enum GPUTextureViewDimension {
"2d-array", "2d-array",
"cube", "cube",
"cube-array", "cube-array",
"3d", "3d"
}; };
enum GPUTextureAspect { enum GPUTextureAspect {
"all", "all",
"stencil-only", "stencil-only",
"depth-only", "depth-only"
}; };
enum GPUTextureFormat { enum GPUTextureFormat {
@ -296,50 +293,6 @@ enum GPUTextureFormat {
"bc7-rgba-unorm", "bc7-rgba-unorm",
"bc7-rgba-unorm-srgb", "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" feature
"depth24unorm-stencil8", "depth24unorm-stencil8",
@ -347,7 +300,7 @@ enum GPUTextureFormat {
"depth32float-stencil8", "depth32float-stencil8",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUSampler { interface GPUSampler {
}; };
GPUSampler includes GPUObjectBase; GPUSampler includes GPUObjectBase;
@ -368,12 +321,12 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
enum GPUAddressMode { enum GPUAddressMode {
"clamp-to-edge", "clamp-to-edge",
"repeat", "repeat",
"mirror-repeat", "mirror-repeat"
}; };
enum GPUFilterMode { enum GPUFilterMode {
"nearest", "nearest",
"linear", "linear"
}; };
enum GPUCompareFunction { enum GPUCompareFunction {
@ -384,10 +337,10 @@ enum GPUCompareFunction {
"greater", "greater",
"not-equal", "not-equal",
"greater-equal", "greater-equal",
"always", "always"
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUBindGroupLayout { interface GPUBindGroupLayout {
}; };
GPUBindGroupLayout includes GPUObjectBase; GPUBindGroupLayout includes GPUObjectBase;
@ -460,7 +413,7 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d"; GPUTextureViewDimension viewDimension = "2d";
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUBindGroup { interface GPUBindGroup {
}; };
GPUBindGroup includes GPUObjectBase; GPUBindGroup includes GPUObjectBase;
@ -483,7 +436,7 @@ dictionary GPUBufferBinding {
GPUSize64 size; GPUSize64 size;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUPipelineLayout { interface GPUPipelineLayout {
}; };
GPUPipelineLayout includes GPUObjectBase; GPUPipelineLayout includes GPUObjectBase;
@ -492,7 +445,7 @@ dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase {
required sequence<GPUBindGroupLayout> bindGroupLayouts; required sequence<GPUBindGroupLayout> bindGroupLayouts;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUShaderModule { interface GPUShaderModule {
Promise<GPUCompilationInfo> compilationInfo(); Promise<GPUCompilationInfo> compilationInfo();
}; };
@ -506,10 +459,10 @@ dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
enum GPUCompilationMessageType { enum GPUCompilationMessageType {
"error", "error",
"warning", "warning",
"info", "info"
}; };
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] [Exposed=(Window, DedicatedWorker), Serializable]
interface GPUCompilationMessage { interface GPUCompilationMessage {
readonly attribute DOMString message; readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type; readonly attribute GPUCompilationMessageType type;
@ -519,7 +472,7 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length; readonly attribute unsigned long long length;
}; };
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] [Exposed=(Window, DedicatedWorker), Serializable]
interface GPUCompilationInfo { interface GPUCompilationInfo {
readonly attribute FrozenArray<GPUCompilationMessage> messages; readonly attribute FrozenArray<GPUCompilationMessage> messages;
}; };
@ -540,7 +493,7 @@ dictionary GPUProgrammableStage {
typedef double GPUPipelineConstantValue; // May represent WGSLs bool, f32, i32, u32. typedef double GPUPipelineConstantValue; // May represent WGSLs bool, f32, i32, u32.
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUComputePipeline { interface GPUComputePipeline {
}; };
GPUComputePipeline includes GPUObjectBase; GPUComputePipeline includes GPUObjectBase;
@ -550,7 +503,7 @@ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
required GPUProgrammableStage compute; required GPUProgrammableStage compute;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPURenderPipeline { interface GPURenderPipeline {
}; };
GPURenderPipeline includes GPUObjectBase; GPURenderPipeline includes GPUObjectBase;
@ -569,7 +522,7 @@ enum GPUPrimitiveTopology {
"line-list", "line-list",
"line-strip", "line-strip",
"triangle-list", "triangle-list",
"triangle-strip", "triangle-strip"
}; };
dictionary GPUPrimitiveState { dictionary GPUPrimitiveState {
@ -578,19 +531,19 @@ dictionary GPUPrimitiveState {
GPUFrontFace frontFace = "ccw"; GPUFrontFace frontFace = "ccw";
GPUCullMode cullMode = "none"; GPUCullMode cullMode = "none";
// Requires "depth-clip-control" feature. // Enable depth clamping (requires "depth-clamping" feature)
boolean unclippedDepth = false; boolean clampDepth = false;
}; };
enum GPUFrontFace { enum GPUFrontFace {
"ccw", "ccw",
"cw", "cw"
}; };
enum GPUCullMode { enum GPUCullMode {
"none", "none",
"front", "front",
"back", "back"
}; };
dictionary GPUMultisampleState { dictionary GPUMultisampleState {
@ -599,7 +552,7 @@ dictionary GPUMultisampleState {
boolean alphaToCoverageEnabled = false; boolean alphaToCoverageEnabled = false;
}; };
dictionary GPUFragmentState : GPUProgrammableStage { dictionary GPUFragmentState: GPUProgrammableStage {
required sequence<GPUColorTargetState> targets; required sequence<GPUColorTargetState> targets;
}; };
@ -626,9 +579,9 @@ interface GPUColorWrite {
}; };
dictionary GPUBlendComponent { dictionary GPUBlendComponent {
GPUBlendOperation operation = "add";
GPUBlendFactor srcFactor = "one"; GPUBlendFactor srcFactor = "one";
GPUBlendFactor dstFactor = "zero"; GPUBlendFactor dstFactor = "zero";
GPUBlendOperation operation = "add";
}; };
enum GPUBlendFactor { enum GPUBlendFactor {
@ -644,7 +597,7 @@ enum GPUBlendFactor {
"one-minus-dst-alpha", "one-minus-dst-alpha",
"src-alpha-saturated", "src-alpha-saturated",
"constant", "constant",
"one-minus-constant", "one-minus-constant"
}; };
enum GPUBlendOperation { enum GPUBlendOperation {
@ -652,7 +605,7 @@ enum GPUBlendOperation {
"subtract", "subtract",
"reverse-subtract", "reverse-subtract",
"min", "min",
"max", "max"
}; };
dictionary GPUDepthStencilState { dictionary GPUDepthStencilState {
@ -687,12 +640,12 @@ enum GPUStencilOperation {
"increment-clamp", "increment-clamp",
"decrement-clamp", "decrement-clamp",
"increment-wrap", "increment-wrap",
"decrement-wrap", "decrement-wrap"
}; };
enum GPUIndexFormat { enum GPUIndexFormat {
"uint16", "uint16",
"uint32", "uint32"
}; };
enum GPUVertexFormat { enum GPUVertexFormat {
@ -730,10 +683,10 @@ enum GPUVertexFormat {
enum GPUVertexStepMode { enum GPUVertexStepMode {
"vertex", "vertex",
"instance", "instance"
}; };
dictionary GPUVertexState : GPUProgrammableStage { dictionary GPUVertexState: GPUProgrammableStage {
sequence<GPUVertexBufferLayout?> buffers = []; sequence<GPUVertexBufferLayout?> buffers = [];
}; };
@ -750,15 +703,16 @@ dictionary GPUVertexAttribute {
required GPUIndex32 shaderLocation; required GPUIndex32 shaderLocation;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUCommandBuffer { interface GPUCommandBuffer {
readonly attribute Promise<double> executionTime;
}; };
GPUCommandBuffer includes GPUObjectBase; GPUCommandBuffer includes GPUObjectBase;
dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase { dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUCommandEncoder { interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@ -785,11 +739,6 @@ interface GPUCommandEncoder {
GPUImageCopyTexture destination, GPUImageCopyTexture destination,
GPUExtent3D copySize); GPUExtent3D copySize);
undefined clearBuffer(
GPUBuffer destination,
GPUSize64 destinationOffset,
GPUSize64 size);
undefined pushDebugGroup(USVString groupLabel); undefined pushDebugGroup(USVString groupLabel);
undefined popDebugGroup(); undefined popDebugGroup();
undefined insertDebugMarker(USVString markerLabel); undefined insertDebugMarker(USVString markerLabel);
@ -808,6 +757,7 @@ interface GPUCommandEncoder {
GPUCommandEncoder includes GPUObjectBase; GPUCommandEncoder includes GPUObjectBase;
dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase { dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
boolean measureExecutionTime = false;
}; };
dictionary GPUImageDataLayout { dictionary GPUImageDataLayout {
@ -841,7 +791,7 @@ interface mixin GPUProgrammablePassEncoder {
undefined insertDebugMarker(USVString markerLabel); undefined insertDebugMarker(USVString markerLabel);
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUComputePassEncoder { interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline); undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1); undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1);
@ -877,7 +827,7 @@ interface mixin GPURenderEncoderBase {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPURenderPassEncoder { interface GPURenderPassEncoder {
undefined setViewport(float x, float y, undefined setViewport(float x, float y,
float width, float height, float width, float height,
@ -931,12 +881,12 @@ dictionary GPURenderPassDepthStencilAttachment {
}; };
enum GPULoadOp { enum GPULoadOp {
"load", "load"
}; };
enum GPUStoreOp { enum GPUStoreOp {
"store", "store",
"discard", "discard"
}; };
dictionary GPURenderPassLayout: GPUObjectDescriptorBase { dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
@ -945,7 +895,7 @@ dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
GPUSize32 sampleCount = 1; GPUSize32 sampleCount = 1;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPURenderBundle { interface GPURenderBundle {
}; };
GPURenderBundle includes GPUObjectBase; GPURenderBundle includes GPUObjectBase;
@ -953,7 +903,7 @@ GPURenderBundle includes GPUObjectBase;
dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase { dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase {
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPURenderBundleEncoder { interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
}; };
@ -966,7 +916,7 @@ dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout {
boolean stencilReadOnly = false; boolean stencilReadOnly = false;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUQueue { interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> commandBuffers); undefined submit(sequence<GPUCommandBuffer> commandBuffers);
@ -987,7 +937,7 @@ interface GPUQueue {
}; };
GPUQueue includes GPUObjectBase; GPUQueue includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUQuerySet { interface GPUQuerySet {
undefined destroy(); undefined destroy();
}; };
@ -1002,7 +952,7 @@ dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
enum GPUQueryType { enum GPUQueryType {
"occlusion", "occlusion",
"pipeline-statistics", "pipeline-statistics",
"timestamp", "timestamp"
}; };
enum GPUPipelineStatisticName { enum GPUPipelineStatisticName {
@ -1010,14 +960,14 @@ enum GPUPipelineStatisticName {
"clipper-invocations", "clipper-invocations",
"clipper-primitives-out", "clipper-primitives-out",
"fragment-shader-invocations", "fragment-shader-invocations",
"compute-shader-invocations", "compute-shader-invocations"
}; };
enum GPUDeviceLostReason { enum GPUDeviceLostReason {
"destroyed", "destroyed",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUDeviceLostInfo { interface GPUDeviceLostInfo {
readonly attribute (GPUDeviceLostReason or undefined) reason; readonly attribute (GPUDeviceLostReason or undefined) reason;
readonly attribute DOMString message; readonly attribute DOMString message;
@ -1029,15 +979,15 @@ partial interface GPUDevice {
enum GPUErrorFilter { enum GPUErrorFilter {
"out-of-memory", "out-of-memory",
"validation", "validation"
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUOutOfMemoryError { interface GPUOutOfMemoryError {
constructor(); constructor();
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, DedicatedWorker)]
interface GPUValidationError { interface GPUValidationError {
constructor(DOMString message); constructor(DOMString message);
readonly attribute DOMString message; readonly attribute DOMString message;
@ -1050,7 +1000,9 @@ partial interface GPUDevice {
Promise<GPUError?> popErrorScope(); Promise<GPUError?> popErrorScope();
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [
Exposed=(Window, DedicatedWorker)
]
interface GPUUncapturedErrorEvent : Event { interface GPUUncapturedErrorEvent : Event {
constructor( constructor(
DOMString type, DOMString type,
@ -1108,4 +1060,3 @@ dictionary GPUExtent3DDict {
GPUIntegerCoordinate depthOrArrayLayers = 1; GPUIntegerCoordinate depthOrArrayLayers = 1;
}; };
typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D; typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D;

View file

@ -59,16 +59,3 @@ 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 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: can use a shorthand or a partial match to profile a group of benches, e.g:
`./tools/flamebench.js de v8` `./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` 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

View file

@ -1,90 +0,0 @@
#!/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 } from "./util.js";
// const COMMIT = "c00e471274b6c21acda89b4b13d41742c0285d71"; // Release 12
const COMMIT = "cdd480a89c9e3b681d9d174e65082d2bdbc903ef"; // tip
const REPO = "gfx-rs/wgpu";
// const V_WGPU = "0.12.0";
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 = `gfx-rs-wgpu-${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 patchCargo() {
const vDenoCore = await denoCoreVersion();
const webgpuCargo = join(ROOT_PATH, "ext", "webgpu", "Cargo.toml");
const data = await Deno.readTextFile(webgpuCargo);
// Patch ext/webgpu/Cargo.toml's contents
const patched = data
.replace(`version = "0.17.0"`, `version = "0.33.0"`)
.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"] }`,
);
await Deno.writeTextFile(webgpuCargo, patched);
}
async function patchSrcLib() {
const srcLib = join(ROOT_PATH, "ext", "webgpu", "src", "lib.rs");
const data = await Deno.readTextFile(srcLib);
// Patch ext/webgpu/src/lib.rs's contents
const patched = data
.replace(`prefix "deno:deno_webgpu",`, `prefix "deno:ext/webgpu",`);
await Deno.writeTextFile(srcLib, patched);
}
async function main() {
await clearTargetDir();
await checkoutUpstream();
await patchCargo();
await patchSrcLib();
await bash(join(ROOT_PATH, "tools", "format.js"));
}
await main();