summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock81
-rw-r--r--Cargo.toml5
-rw-r--r--cli/tsc/dts/lib.deno_webgpu.d.ts58
-rw-r--r--ext/webgpu/Cargo.toml30
-rw-r--r--ext/webgpu/src/01_webgpu.js352
-rw-r--r--ext/webgpu/src/02_idl_types.js29
-rw-r--r--ext/webgpu/src/03_surface.js148
-rw-r--r--ext/webgpu/src/04_surface_idl_types.js86
-rw-r--r--ext/webgpu/src/binding.rs6
-rw-r--r--ext/webgpu/src/buffer.rs15
-rw-r--r--ext/webgpu/src/bundle.rs24
-rw-r--r--ext/webgpu/src/command_encoder.rs3
-rw-r--r--ext/webgpu/src/compute_pass.rs4
-rw-r--r--ext/webgpu/src/error.rs14
-rw-r--r--ext/webgpu/src/lib.rs44
-rw-r--r--ext/webgpu/src/pipeline.rs16
-rw-r--r--ext/webgpu/src/render_pass.rs4
-rw-r--r--ext/webgpu/src/sampler.rs2
-rw-r--r--ext/webgpu/src/shader.rs3
-rw-r--r--ext/webgpu/src/surface.rs137
-rw-r--r--ext/webgpu/src/texture.rs6
-rw-r--r--ext/webgpu/webgpu.idl206
-rw-r--r--runtime/js/98_global_scope.js3
-rwxr-xr-xtools/wgpu_sync.js32
24 files changed, 907 insertions, 401 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 694fec1e8..bca903286 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -123,9 +123,9 @@ dependencies = [
[[package]]
name = "ash"
-version = "0.37.0+1.3.209"
+version = "0.37.2+1.3.238"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "006ca68e0f2b03f22d6fa9f2860f85aed430d257fec20f8879b2145e7c7ae1a6"
+checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03"
dependencies = [
"libloading",
]
@@ -290,16 +290,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
-name = "bitflags_serde_shim"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25c3d626f0280ec39b33a6fc5c6c1067432b4c41e94aee40ded197a6649bf025"
-dependencies = [
- "bitflags",
- "serde",
-]
-
-[[package]]
name = "block"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -408,12 +398,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "cfg_aliases"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
-
-[[package]]
name = "chrono"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -523,12 +507,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
-name = "copyless"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
-
-[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -685,9 +663,9 @@ dependencies = [
[[package]]
name = "d3d12"
-version = "0.5.0"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759"
+checksum = "d8f0de2f5a8e7bd4a9eec0e3c781992a4ce1724f68aec7d7a3715344de8b39da"
dependencies = [
"bitflags",
"libloading",
@@ -1288,6 +1266,7 @@ name = "deno_webgpu"
version = "0.87.0"
dependencies = [
"deno_core",
+ "raw-window-handle",
"serde",
"tokio",
"wgpu-core",
@@ -2023,9 +2002,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "glow"
-version = "0.11.2"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919"
+checksum = "8edf6019dff2d92ad27c1e3ff82ad50a0aea5b01370353cc928bfdc33e95925c"
dependencies = [
"js-sys",
"slotmap",
@@ -2364,12 +2343,6 @@ dependencies = [
]
[[package]]
-name = "inplace_it"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e567468c50f3d4bc7397702e09b380139f9b9288b4e909b070571007f8b5bf78"
-
-[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2798,9 +2771,9 @@ checksum = "f13de1c3edc9a5b9dc3a1029f56e9ab3eba34640010aff4fc01044c42ef67afa"
[[package]]
name = "naga"
-version = "0.9.0"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f50357e1167a3ab92d6b3c7f4bf5f7fd13fde3f4b28bf0d5ea07b5100fdb6c0"
+checksum = "5eafe22a23b797c9bc227c6c896419b26b5bb88fa903417a3adaed08778850d5"
dependencies = [
"bit-set",
"bitflags",
@@ -3504,9 +3477,9 @@ checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6"
[[package]]
name = "raw-window-handle"
-version = "0.4.3"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41"
+checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a"
dependencies = [
"cty",
]
@@ -3553,12 +3526,6 @@ dependencies = [
]
[[package]]
-name = "renderdoc-sys"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
-
-[[package]]
name = "reqwest"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3644,9 +3611,9 @@ dependencies = [
[[package]]
name = "ron"
-version = "0.7.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
+checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff"
dependencies = [
"base64",
"bitflags",
@@ -5541,21 +5508,20 @@ dependencies = [
[[package]]
name = "wgpu-core"
-version = "0.13.2"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b92788dec9d0c1bed849a1b83f01b2ee12819bf04a79c90f68e4173f7b5ba2"
+checksum = "be1f61be28e557a6ecb2506cac06c63fae3b6d302a006f38195a7a80995abeb9"
dependencies = [
"arrayvec",
"bit-vec",
"bitflags",
- "cfg_aliases",
"codespan-reporting",
- "copyless",
"fxhash",
"log",
"naga",
"parking_lot 0.12.1",
"profiling",
+ "raw-window-handle",
"ron",
"serde",
"smallvec",
@@ -5567,9 +5533,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
-version = "0.13.2"
+version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20cbdfc3d0637dba3d5536b93adef3d26023a0b96f0e1ee5ee9560a401d9f646"
+checksum = "82e95792925fe3d58950b9a5c2a191caa145e2bc570e2d233f0d7320f6a8e814"
dependencies = [
"android_system_properties",
"arrayvec",
@@ -5584,9 +5550,9 @@ dependencies = [
"glow",
"gpu-alloc",
"gpu-descriptor",
- "inplace_it",
"js-sys",
"khronos-egl",
+ "libc",
"libloading",
"log",
"metal",
@@ -5596,7 +5562,7 @@ dependencies = [
"profiling",
"range-alloc",
"raw-window-handle",
- "renderdoc-sys",
+ "smallvec",
"thiserror",
"wasm-bindgen",
"web-sys",
@@ -5606,13 +5572,14 @@ dependencies = [
[[package]]
name = "wgpu-types"
-version = "0.13.2"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f762cbc08e1a51389859cf9c199c7aef544789cf3510889aab12c607f701604"
+checksum = "ecf8cfcbf98f94cc8bd5981544c687140cf9d3948e2ab83849367ead2cd737cf"
dependencies = [
"bitflags",
- "bitflags_serde_shim",
+ "js-sys",
"serde",
+ "web-sys",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 503f45aac..6a60dcf89 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -121,6 +121,11 @@ url = { version = "2.3.1", features = ["serde", "expose_internals"] }
uuid = { version = "=1.1.2", features = ["v4"] }
zstd = "=0.11.2"
+# webgpu
+raw-window-handle = "0.5.0"
+wgpu-core = "0.15"
+wgpu-types = "0.15"
+
# macros
proc-macro2 = "1"
quote = "1"
diff --git a/cli/tsc/dts/lib.deno_webgpu.d.ts b/cli/tsc/dts/lib.deno_webgpu.d.ts
index 0497e2417..150f16bab 100644
--- a/cli/tsc/dts/lib.deno_webgpu.d.ts
+++ b/cli/tsc/dts/lib.deno_webgpu.d.ts
@@ -22,6 +22,7 @@ declare class GPUSupportedLimits {
maxTextureDimension3D?: number;
maxTextureArrayLayers?: number;
maxBindGroups?: number;
+ maxBindingsPerBindGroup?: number;
maxDynamicUniformBuffersPerPipelineLayout?: number;
maxDynamicStorageBuffersPerPipelineLayout?: number;
maxSampledTexturesPerShaderStage?: number;
@@ -34,6 +35,7 @@ declare class GPUSupportedLimits {
minUniformBufferOffsetAlignment?: number;
minStorageBufferOffsetAlignment?: number;
maxVertexBuffers?: number;
+ maxBufferSize?: number;
maxVertexAttributes?: number;
maxVertexBufferArrayStride?: number;
maxInterStageShaderComponents?: number;
@@ -109,7 +111,6 @@ declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase {
/** @category WebGPU */
declare type GPUFeatureName =
| "depth-clip-control"
- | "depth24unorm-stencil8"
| "depth32float-stencil8"
| "pipeline-statistics-query"
| "texture-compression-bc"
@@ -139,9 +140,6 @@ declare class GPUDevice extends EventTarget implements GPUObjectBase {
readonly lost: Promise<GPUDeviceLostInfo>;
pushErrorScope(filter: GPUErrorFilter): undefined;
popErrorScope(): Promise<GPUError | null>;
- onuncapturederror:
- | ((this: GPUDevice, ev: GPUUncapturedErrorEvent) => any)
- | null;
readonly features: GPUSupportedFeatures;
readonly limits: GPUSupportedLimits;
@@ -189,6 +187,10 @@ declare class GPUDevice extends EventTarget implements GPUObjectBase {
declare class GPUBuffer implements GPUObjectBase {
label: string;
+ readonly size: number;
+ readonly usage: GPUBufferUsageFlags;
+ readonly mapState: GPUBufferMapState;
+
mapAsync(
mode: GPUMapModeFlags,
offset?: number,
@@ -201,6 +203,9 @@ declare class GPUBuffer implements GPUObjectBase {
}
/** @category WebGPU */
+declare type GPUBufferMapState = "unmapped" | "pending" | "mapped";
+
+/** @category WebGPU */
declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase {
size: number;
usage: GPUBufferUsageFlags;
@@ -239,6 +244,15 @@ declare class GPUTexture implements GPUObjectBase {
createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView;
destroy(): undefined;
+
+ readonly width: number;
+ readonly height: number;
+ readonly depthOrArrayLayers: number;
+ readonly mipLevelCount: number;
+ readonly sampleCount: number;
+ readonly dimension: GPUTextureDimension;
+ readonly format: GPUTextureFormat;
+ readonly usage: GPUTextureUsageFlags;
}
/** @category WebGPU */
@@ -249,6 +263,7 @@ declare interface GPUTextureDescriptor extends GPUObjectDescriptorBase {
dimension?: GPUTextureDimension;
format: GPUTextureFormat;
usage: GPUTextureUsageFlags;
+ viewFormats?: GPUTextureFormat[];
}
/** @category WebGPU */
@@ -337,7 +352,6 @@ declare type GPUTextureFormat =
| "depth24plus"
| "depth24plus-stencil8"
| "depth32float"
- | "depth24unorm-stencil8"
| "depth32float-stencil8"
| "bc1-rgba-unorm"
| "bc1-rgba-unorm-srgb"
@@ -815,6 +829,13 @@ declare interface GPUVertexAttribute {
}
/** @category WebGPU */
+declare interface GPUImageDataLayout {
+ offset?: number;
+ bytesPerRow?: number;
+ rowsPerImage?: number;
+}
+
+/** @category WebGPU */
declare class GPUCommandBuffer implements GPUObjectBase {
label: string;
}
@@ -884,13 +905,6 @@ declare class GPUCommandEncoder implements GPUObjectBase {
declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {}
/** @category WebGPU */
-declare interface GPUImageDataLayout {
- offset?: number;
- bytesPerRow?: number;
- rowsPerImage?: number;
-}
-
-/** @category WebGPU */
declare interface GPUImageCopyBuffer extends GPUImageDataLayout {
buffer: GPUBuffer;
}
@@ -1091,7 +1105,6 @@ declare class GPURenderPassEncoder
declare interface GPURenderPassDescriptor extends GPUObjectDescriptorBase {
colorAttachments: (GPURenderPassColorAttachment | null)[];
depthStencilAttachment?: GPURenderPassDepthStencilAttachment;
- occlusionQuerySet?: GPUQuerySet;
}
/** @category WebGPU */
@@ -1229,6 +1242,9 @@ declare class GPUQuerySet implements GPUObjectBase {
label: string;
destroy(): undefined;
+
+ readonly type: GPUQueryType;
+ readonly count: number;
}
/** @category WebGPU */
@@ -1264,9 +1280,6 @@ declare class GPUError {
}
/** @category WebGPU */
-declare type GPUErrorFilter = "out-of-memory" | "validation";
-
-/** @category WebGPU */
declare class GPUOutOfMemoryError extends GPUError {
constructor(message: string);
}
@@ -1277,18 +1290,7 @@ declare class GPUValidationError extends GPUError {
}
/** @category WebGPU */
-declare class GPUUncapturedErrorEvent extends Event {
- constructor(
- type: string,
- gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit,
- );
- readonly error: GPUError;
-}
-
-/** @category WebGPU */
-declare interface GPUUncapturedErrorEventInit extends EventInit {
- error?: GPUError;
-}
+declare type GPUErrorFilter = "out-of-memory" | "validation";
/** @category WebGPU */
declare interface GPUColorDict {
diff --git a/ext/webgpu/Cargo.toml b/ext/webgpu/Cargo.toml
index 3e1d579f9..d22eb19e7 100644
--- a/ext/webgpu/Cargo.toml
+++ b/ext/webgpu/Cargo.toml
@@ -3,16 +3,38 @@
[package]
name = "deno_webgpu"
version = "0.87.0"
-authors.workspace = true
+authors = ["the Deno authors"]
edition.workspace = true
-license.workspace = true
+license = "MIT"
readme = "README.md"
repository = "https://github.com/gfx-rs/wgpu"
description = "WebGPU implementation for Deno"
+[features]
+surface = ["wgpu-core/raw-window-handle", "dep:raw-window-handle"]
+
[dependencies]
deno_core.workspace = true
+raw-window-handle = { workspace = true, optional = true }
serde.workspace = true
tokio.workspace = true
-wgpu-core = { version = "0.13", features = ["trace", "replay", "serde"] }
-wgpu-types = { version = "0.13", features = ["trace", "replay", "serde"] }
+wgpu-types = { workspace = true, features = ["trace", "replay", "serde"] }
+
+[dependencies.wgpu-core]
+workspace = true
+features = ["trace", "replay", "serde", "strict_asserts", "wgsl", "gles"]
+
+# We want the wgpu-core Metal backend on macOS and iOS.
+[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgpu-core]
+workspace = true
+features = ["metal"]
+
+# We want the wgpu-core Direct3D backends on Windows.
+[target.'cfg(windows)'.dependencies.wgpu-core]
+workspace = true
+features = ["dx11", "dx12"]
+
+# We want the wgpu-core Vulkan backend on Unix (but not Emscripten) and Windows.
+[target.'cfg(any(windows, all(unix, not(target_arch = "emscripten"))))'.dependencies.wgpu-core]
+workspace = true
+features = ["vulkan"]
diff --git a/ext/webgpu/src/01_webgpu.js b/ext/webgpu/src/01_webgpu.js
index eb239bab8..23e8b24f0 100644
--- a/ext/webgpu/src/01_webgpu.js
+++ b/ext/webgpu/src/01_webgpu.js
@@ -57,7 +57,6 @@
const _architecture = Symbol("[[architecture]]");
const _description = Symbol("[[description]]");
const _limits = Symbol("[[limits]]");
- const _features = Symbol("[[features]]");
const _reason = Symbol("[[reason]]");
const _message = Symbol("[[message]]");
const _label = Symbol("[[label]]");
@@ -68,6 +67,15 @@
const _encoders = Symbol("[[encoders]]");
const _encoder = Symbol("[[encoder]]");
const _descriptor = Symbol("[[descriptor]]");
+ const _width = Symbol("[[width]]");
+ const _height = Symbol("[[height]]");
+ const _depthOrArrayLayers = Symbol("[[depthOrArrayLayers]]");
+ const _mipLevelCount = Symbol("[[mipLevelCount]]");
+ const _sampleCount = Symbol("[[sampleCount]]");
+ const _dimension = Symbol("[[dimension]]");
+ const _format = Symbol("[[format]]");
+ const _type = Symbol("[[type]]");
+ const _count = Symbol("[[count]]");
/**
* @param {any} self
@@ -175,10 +183,13 @@
}
}
+ const illegalConstructorKey = Symbol("illegalConstructorKey");
class GPUError extends Error {
- constructor() {
+ constructor(key = null) {
super();
- webidl.illegalConstructor();
+ if (key !== illegalConstructorKey) {
+ webidl.illegalConstructor();
+ }
}
[_message];
@@ -189,34 +200,38 @@
}
const GPUErrorPrototype = GPUError.prototype;
- class GPUOutOfMemoryError extends GPUError {
- name = "GPUOutOfMemoryError";
+ class GPUValidationError extends GPUError {
+ name = "GPUValidationError";
+ /** @param {string} message */
constructor(message) {
- const prefix = "Failed to construct 'GPUOutOfMemoryError'";
+ const prefix = "Failed to construct 'GPUValidationError'";
webidl.requiredArguments(arguments.length, 1, { prefix });
message = webidl.converters.DOMString(message, {
prefix,
context: "Argument 1",
});
- super(message);
+ super(illegalConstructorKey);
+ this[webidl.brand] = webidl.brand;
+ this[_message] = message;
}
}
- const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError.prototype;
+ const GPUValidationErrorPrototype = GPUValidationError.prototype;
- class GPUValidationError extends GPUError {
- name = "GPUValidationError";
- /** @param {string} message */
+ class GPUOutOfMemoryError extends GPUError {
+ name = "GPUOutOfMemoryError";
constructor(message) {
- const prefix = "Failed to construct 'GPUValidationError'";
+ const prefix = "Failed to construct 'GPUOutOfMemoryError'";
webidl.requiredArguments(arguments.length, 1, { prefix });
message = webidl.converters.DOMString(message, {
prefix,
context: "Argument 1",
});
- super(message);
+ super(illegalConstructorKey);
+ this[webidl.brand] = webidl.brand;
+ this[_message] = message;
}
}
- const GPUValidationErrorPrototype = GPUValidationError.prototype;
+ const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError.prototype;
class GPU {
[webidl.brand] = webidl.brand;
@@ -314,27 +329,24 @@
const requiredFeatures = descriptor.requiredFeatures ?? [];
for (let i = 0; i < requiredFeatures.length; ++i) {
const feature = requiredFeatures[i];
- if (!SetPrototypeHas(this[_adapter].features[_features], feature)) {
+ if (
+ !SetPrototypeHas(
+ this[_adapter].features[webidl.setlikeInner],
+ feature,
+ )
+ ) {
throw new TypeError(
- `${prefix}: nonGuaranteedFeatures must be a subset of the adapter features.`,
+ `${prefix}: requiredFeatures must be a subset of the adapter features.`,
);
}
}
- let requiredLimits = descriptor.requiredLimits;
- if (requiredLimits) {
- requiredLimits = {
- ...this[_adapter].limits[_limits],
- ...requiredLimits,
- };
- }
- // TODO(lucacasonato): validate requiredLimits
const { rid, features, limits } = await core.opAsync(
"op_webgpu_request_device",
this[_adapter].rid,
descriptor.label,
requiredFeatures,
- requiredLimits,
+ descriptor.requiredLimits,
);
const inner = new InnerGPUDevice({
@@ -344,9 +356,9 @@
limits: createGPUSupportedLimits(limits),
});
return createGPUDevice(
- descriptor.label ?? null,
+ descriptor.label,
inner,
- createGPUQueue(descriptor.label ?? null, inner),
+ createGPUQueue(descriptor.label, inner),
);
}
@@ -441,10 +453,10 @@
}
const GPUAdapterInfoPrototype = GPUAdapterInfo.prototype;
- function createGPUSupportedLimits(features) {
+ function createGPUSupportedLimits(limits) {
/** @type {GPUSupportedLimits} */
const adapterFeatures = webidl.createBranded(GPUSupportedLimits);
- adapterFeatures[_limits] = features;
+ adapterFeatures[_limits] = limits;
return adapterFeatures;
}
@@ -505,6 +517,14 @@
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxBindGroups;
}
+ get maxBindingsPerBindGroup() {
+ webidl.assertBranded(this, GPUSupportedLimitsPrototype);
+ return this[_limits].maxBindingsPerBindGroup;
+ }
+ get maxBufferSize() {
+ webidl.assertBranded(this, GPUSupportedLimitsPrototype);
+ return this[_limits].maxBufferSize;
+ }
get maxDynamicUniformBuffersPerPipelineLayout() {
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxDynamicUniformBuffersPerPipelineLayout;
@@ -611,7 +631,6 @@
constructor() {
webidl.illegalConstructor();
}
-
[SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${
inspect([...new SafeArrayIterator(this.values())])
@@ -923,7 +942,7 @@
};
}
const buffer = createGPUBuffer(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
descriptor.size,
@@ -955,7 +974,7 @@
device.pushError(err);
const texture = createGPUTexture(
- descriptor.label ?? null,
+ descriptor,
device,
rid,
);
@@ -975,14 +994,14 @@
context: "Argument 1",
});
const device = assertDevice(this, { prefix, context: "this" });
- const { rid, err } = ops.op_webgpu_create_sampler({
+ const { rid, err } = ops.op_webgpu_create_texture({
deviceRid: device.rid,
...descriptor,
});
device.pushError(err);
const sampler = createGPUSampler(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1006,13 +1025,13 @@
for (let i = 0; i < descriptor.entries.length; ++i) {
const entry = descriptor.entries[i];
- let count = 0;
- if (entry.buffer) count++;
- if (entry.sampler) count++;
- if (entry.texture) count++;
- if (entry.storageTexture) count++;
+ let j = 0;
+ if (entry.buffer) j++;
+ if (entry.sampler) j++;
+ if (entry.texture) j++;
+ if (entry.storageTexture) j++;
- if (count !== 1) {
+ if (j !== 1) {
throw new Error(); // TODO(@crowlKats): correct error
}
}
@@ -1025,7 +1044,7 @@
device.pushError(err);
const bindGroupLayout = createGPUBindGroupLayout(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1067,7 +1086,7 @@
device.pushError(err);
const pipelineLayout = createGPUPipelineLayout(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1162,7 +1181,7 @@
device.pushError(err);
const bindGroup = createGPUBindGroup(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1186,12 +1205,11 @@
device.rid,
descriptor.label,
descriptor.code,
- descriptor.sourceMap,
);
device.pushError(err);
const shaderModule = createGPUShaderModule(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1245,7 +1263,7 @@
device.pushError(err);
const computePipeline = createGPUComputePipeline(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1320,7 +1338,7 @@
device.pushError(err);
const renderPipeline = createGPURenderPipeline(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1357,7 +1375,7 @@
device.pushError(err);
const commandEncoder = createGPUCommandEncoder(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1382,16 +1400,14 @@
},
);
const device = assertDevice(this, { prefix, context: "this" });
- const { rid, err } = ops.op_webgpu_create_render_bundle_encoder(
- {
- deviceRid: device.rid,
- ...descriptor,
- },
- );
+ const { rid, err } = ops.op_webgpu_create_render_bundle_encoder({
+ deviceRid: device.rid,
+ ...descriptor,
+ });
device.pushError(err);
const renderBundleEncoder = createGPURenderBundleEncoder(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -1422,7 +1438,7 @@
device.pushError(err);
const querySet = createGPUQuerySet(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
descriptor,
@@ -1523,7 +1539,7 @@
* @param {GPUCommandBuffer[]} commandBuffers
*/
submit(commandBuffers) {
- webidl.assertBranded(this, GPUQueue.prototype);
+ webidl.assertBranded(this, GPUQueuePrototype);
const prefix = "Failed to execute 'submit' on 'GPUQueue'";
webidl.requiredArguments(arguments.length, 1, {
prefix,
@@ -1546,10 +1562,7 @@
return rid;
},
);
- const { err } = ops.op_webgpu_queue_submit(
- device.rid,
- commandBufferRids,
- );
+ const { err } = ops.op_webgpu_queue_submit(device.rid, commandBufferRids);
for (let i = 0; i < commandBuffers.length; ++i) {
commandBuffers[i][_rid] = undefined;
}
@@ -1557,7 +1570,7 @@
}
onSubmittedWorkDone() {
- webidl.assertBranded(this, GPUQueue.prototype);
+ webidl.assertBranded(this, GPUQueuePrototype);
return PromiseResolve();
}
@@ -1569,7 +1582,7 @@
* @param {number} [size]
*/
writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) {
- webidl.assertBranded(this, GPUQueue.prototype);
+ webidl.assertBranded(this, GPUQueuePrototype);
const prefix = "Failed to execute 'writeBuffer' on 'GPUQueue'";
webidl.requiredArguments(arguments.length, 3, { prefix });
buffer = webidl.converters["GPUBuffer"](buffer, {
@@ -1622,7 +1635,7 @@
* @param {GPUExtent3D} size
*/
writeTexture(destination, data, dataLayout, size) {
- webidl.assertBranded(this, GPUQueue.prototype);
+ webidl.assertBranded(this, GPUQueuePrototype);
const prefix = "Failed to execute 'writeTexture' on 'GPUQueue'";
webidl.requiredArguments(arguments.length, 4, { prefix });
destination = webidl.converters.GPUImageCopyTexture(destination, {
@@ -1681,6 +1694,7 @@
}
}
GPUObjectBaseMixin("GPUQueue", GPUQueue);
+ const GPUQueuePrototype = GPUQueue.prototype;
/**
* @typedef CreateGPUBufferOptions
@@ -1716,25 +1730,18 @@
class GPUBuffer {
/** @type {InnerGPUDevice} */
[_device];
-
/** @type {number} */
[_rid];
-
/** @type {number} */
[_size];
-
/** @type {number} */
[_usage];
-
- /** @type {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy"} */
+ /** @type {"mapped" | "mapped at creation" | "pending" | "unmapped" | "destroy"} */
[_state];
-
/** @type {[number, number] | null} */
[_mappingRange];
-
/** @type {[ArrayBuffer, number, number][] | null} */
[_mappedRanges];
-
/** @type {number} */
[_mapMode];
@@ -1761,13 +1768,33 @@
webidl.illegalConstructor();
}
+ get size() {
+ webidl.assertBranded(this, GPUBufferPrototype);
+ return this[_size];
+ }
+
+ get usage() {
+ webidl.assertBranded(this, GPUBufferPrototype);
+ return this[_usage];
+ }
+
+ get mapState() {
+ webidl.assertBranded(this, GPUBufferPrototype);
+ const state = this[_state];
+ if (state === "mapped at creation") {
+ return "mapped";
+ } else {
+ return state;
+ }
+ }
+
/**
* @param {number} mode
* @param {number} offset
* @param {number} [size]
*/
async mapAsync(mode, offset = 0, size) {
- webidl.assertBranded(this, GPUBuffer.prototype);
+ webidl.assertBranded(this, GPUBufferPrototype);
const prefix = "Failed to execute 'mapAsync' on 'GPUBuffer'";
webidl.requiredArguments(arguments.length, 1, { prefix });
mode = webidl.converters.GPUMapModeFlags(mode, {
@@ -1839,7 +1866,7 @@
}
this[_mapMode] = mode;
- this[_state] = "mapping pending";
+ this[_state] = "pending";
const promise = PromisePrototypeThen(
core.opAsync(
"op_webgpu_buffer_get_map_async",
@@ -1867,7 +1894,7 @@
* @param {number} size
*/
getMappedRange(offset = 0, size) {
- webidl.assertBranded(this, GPUBuffer.prototype);
+ webidl.assertBranded(this, GPUBufferPrototype);
const prefix = "Failed to execute 'getMappedRange' on 'GPUBuffer'";
offset = webidl.converters.GPUSize64(offset, {
prefix,
@@ -1922,7 +1949,7 @@
}
unmap() {
- webidl.assertBranded(this, GPUBuffer.prototype);
+ webidl.assertBranded(this, GPUBufferPrototype);
const prefix = "Failed to execute 'unmap' on 'GPUBuffer'";
const device = assertDevice(this, { prefix, context: "this" });
const bufferRid = assertResource(this, { prefix, context: "this" });
@@ -1932,7 +1959,7 @@
"OperationError",
);
}
- if (this[_state] === "mapping pending") {
+ if (this[_state] === "pending") {
// TODO(lucacasonato): this is not spec compliant.
throw new DOMException(
`${prefix}: can not unmap while mapping. This is a Deno limitation.`,
@@ -1980,7 +2007,7 @@
}
destroy() {
- webidl.assertBranded(this, GPUBuffer.prototype);
+ webidl.assertBranded(this, GPUBufferPrototype);
this[_cleanup]();
}
@@ -1993,6 +2020,7 @@
}
}
GPUObjectBaseMixin("GPUBuffer", GPUBuffer);
+ const GPUBufferPrototype = GPUBuffer.prototype;
class GPUBufferUsage {
constructor() {
@@ -2045,18 +2073,26 @@
}
/**
- * @param {string | null} label
+ * @param {GPUTextureDescriptor} descriptor
* @param {InnerGPUDevice} device
* @param {number} rid
* @returns {GPUTexture}
*/
- function createGPUTexture(label, device, rid) {
+ function createGPUTexture(descriptor, device, rid) {
/** @type {GPUTexture} */
const texture = webidl.createBranded(GPUTexture);
- texture[_label] = label;
+ texture[_label] = descriptor.label;
texture[_device] = device;
texture[_rid] = rid;
texture[_views] = [];
+ texture[_width] = descriptor.size.width;
+ texture[_height] = descriptor.size.height;
+ texture[_depthOrArrayLayers] = descriptor.size.depthOrArrayLayers;
+ texture[_mipLevelCount] = descriptor.mipLevelCount;
+ texture[_sampleCount] = descriptor.sampleCount;
+ texture[_dimension] = descriptor.dimension;
+ texture[_format] = descriptor.format;
+ texture[_usage] = descriptor.usage;
return texture;
}
@@ -2068,6 +2104,23 @@
/** @type {WeakRef<GPUTextureView>[]} */
[_views];
+ /** @type {number} */
+ [_width];
+ /** @type {number} */
+ [_height];
+ /** @type {number} */
+ [_depthOrArrayLayers];
+ /** @type {number} */
+ [_mipLevelCount];
+ /** @type {number} */
+ [_sampleCount];
+ /** @type {GPUTextureDimension} */
+ [_dimension];
+ /** @type {GPUTextureFormat} */
+ [_format];
+ /** @type {number} */
+ [_usage];
+
[_cleanup]() {
const views = this[_views];
while (views.length > 0) {
@@ -2092,7 +2145,7 @@
* @param {GPUTextureViewDescriptor} descriptor
*/
createView(descriptor = {}) {
- webidl.assertBranded(this, GPUTexture.prototype);
+ webidl.assertBranded(this, GPUTexturePrototype);
const prefix = "Failed to execute 'createView' on 'GPUTexture'";
webidl.requiredArguments(arguments.length, 0, { prefix });
descriptor = webidl.converters.GPUTextureViewDescriptor(descriptor, {
@@ -2108,7 +2161,7 @@
device.pushError(err);
const textureView = createGPUTextureView(
- descriptor.label ?? null,
+ descriptor.label,
this,
rid,
);
@@ -2117,10 +2170,50 @@
}
destroy() {
- webidl.assertBranded(this, GPUTexture.prototype);
+ webidl.assertBranded(this, GPUTexturePrototype);
this[_cleanup]();
}
+ get width() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_width];
+ }
+
+ get height() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_height];
+ }
+
+ get depthOrArrayLayers() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_depthOrArrayLayers];
+ }
+
+ get mipLevelCount() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_mipLevelCount];
+ }
+
+ get sampleCount() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_sampleCount];
+ }
+
+ get dimension() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_dimension];
+ }
+
+ get format() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_format];
+ }
+
+ get usage() {
+ webidl.assertBranded(this, GPUTexturePrototype);
+ return this[_usage];
+ }
+
[SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${
inspect({
@@ -2130,6 +2223,7 @@
}
}
GPUObjectBaseMixin("GPUTexture", GPUTexture);
+ const GPUTexturePrototype = GPUTexture.prototype;
class GPUTextureUsage {
constructor() {
@@ -2763,7 +2857,7 @@
);
const renderPassEncoder = createGPURenderPassEncoder(
- descriptor.label ?? null,
+ descriptor.label,
this,
rid,
);
@@ -2795,7 +2889,7 @@
);
const computePassEncoder = createGPUComputePassEncoder(
- descriptor.label ?? null,
+ descriptor.label,
this,
rid,
);
@@ -3310,7 +3404,7 @@
this[_rid] = undefined;
const commandBuffer = createGPUCommandBuffer(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -3573,9 +3667,7 @@
context: "encoder referenced by this",
});
const renderPassRid = assertResource(this, { prefix, context: "this" });
- ops.op_webgpu_render_pass_end_pipeline_statistics_query(
- renderPassRid,
- );
+ ops.op_webgpu_render_pass_end_pipeline_statistics_query(renderPassRid);
}
/**
@@ -3651,10 +3743,7 @@
});
return rid;
});
- ops.op_webgpu_render_pass_execute_bundles(
- renderPassRid,
- bundleRids,
- );
+ ops.op_webgpu_render_pass_execute_bundles(renderPassRid, bundleRids);
}
end() {
@@ -3747,10 +3836,7 @@
context: "encoder referenced by this",
});
const renderPassRid = assertResource(this, { prefix, context: "this" });
- ops.op_webgpu_render_pass_push_debug_group(
- renderPassRid,
- groupLabel,
- );
+ ops.op_webgpu_render_pass_push_debug_group(renderPassRid, groupLabel);
}
popDebugGroup() {
@@ -3790,10 +3876,7 @@
context: "encoder referenced by this",
});
const renderPassRid = assertResource(this, { prefix, context: "this" });
- ops.op_webgpu_render_pass_insert_debug_marker(
- renderPassRid,
- markerLabel,
- );
+ ops.op_webgpu_render_pass_insert_debug_marker(renderPassRid, markerLabel);
}
/**
@@ -3826,10 +3909,7 @@
resourceContext: "Argument 1",
selfContext: "this",
});
- ops.op_webgpu_render_pass_set_pipeline(
- renderPassRid,
- pipelineRid,
- );
+ ops.op_webgpu_render_pass_set_pipeline(renderPassRid, pipelineRid);
}
/**
@@ -4205,10 +4285,7 @@
resourceContext: "Argument 1",
selfContext: "this",
});
- ops.op_webgpu_compute_pass_set_pipeline(
- computePassRid,
- pipelineRid,
- );
+ ops.op_webgpu_compute_pass_set_pipeline(computePassRid, pipelineRid);
}
/**
@@ -4351,9 +4428,7 @@
context: "encoder referenced by this",
});
const computePassRid = assertResource(this, { prefix, context: "this" });
- ops.op_webgpu_compute_pass_end_pipeline_statistics_query(
- computePassRid,
- );
+ ops.op_webgpu_compute_pass_end_pipeline_statistics_query(computePassRid);
}
/**
@@ -4488,10 +4563,7 @@
context: "encoder referenced by this",
});
const computePassRid = assertResource(this, { prefix, context: "this" });
- ops.op_webgpu_compute_pass_push_debug_group(
- computePassRid,
- groupLabel,
- );
+ ops.op_webgpu_compute_pass_push_debug_group(computePassRid, groupLabel);
}
popDebugGroup() {
@@ -4630,7 +4702,7 @@
* @param {GPURenderBundleDescriptor} descriptor
*/
finish(descriptor = {}) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'";
descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, {
prefix,
@@ -4649,7 +4721,7 @@
this[_rid] = undefined;
const renderBundle = createGPURenderBundle(
- descriptor.label ?? null,
+ descriptor.label,
device,
rid,
);
@@ -4665,7 +4737,7 @@
dynamicOffsetsDataStart,
dynamicOffsetsDataLength,
) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'setBindGroup' on 'GPURenderBundleEncoder'";
const device = assertDevice(this, { prefix, context: "this" });
@@ -4706,7 +4778,7 @@
* @param {string} groupLabel
*/
pushDebugGroup(groupLabel) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 1, { prefix });
@@ -4726,7 +4798,7 @@
}
popDebugGroup() {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'popDebugGroup' on 'GPURenderBundleEncoder'";
assertDevice(this, { prefix, context: "this" });
@@ -4743,7 +4815,7 @@
* @param {string} markerLabel
*/
insertDebugMarker(markerLabel) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 1, { prefix });
@@ -4766,7 +4838,7 @@
* @param {GPURenderPipeline} pipeline
*/
setPipeline(pipeline) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 1, { prefix });
@@ -4801,7 +4873,7 @@
* @param {number} size
*/
setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 2, { prefix });
@@ -4851,7 +4923,7 @@
* @param {number} size
*/
setVertexBuffer(slot, buffer, offset = 0, size = 0) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 2, { prefix });
@@ -4901,7 +4973,7 @@
* @param {number} firstInstance
*/
draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 1, { prefix });
vertexCount = webidl.converters.GPUSize32(vertexCount, {
@@ -4948,7 +5020,7 @@
baseVertex = 0,
firstInstance = 0,
) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 1, { prefix });
@@ -4992,7 +5064,7 @@
* @param {number} indirectOffset
*/
drawIndirect(indirectBuffer, indirectOffset) {
- webidl.assertBranded(this, GPURenderBundleEncoder.prototype);
+ webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix =
"Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'";
webidl.requiredArguments(arguments.length, 2, { prefix });
@@ -5038,6 +5110,7 @@
}
}
GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder);
+ const GPURenderBundleEncoderPrototype = GPURenderBundleEncoder.prototype;
/**
* @param {string | null} label
@@ -5106,6 +5179,10 @@
[_rid];
/** @type {GPUQuerySetDescriptor} */
[_descriptor];
+ /** @type {GPUQueryType} */
+ [_type];
+ /** @type {number} */
+ [_count];
[_cleanup]() {
const rid = this[_rid];
@@ -5125,6 +5202,16 @@
this[_cleanup]();
}
+ get type() {
+ webidl.assertBranded(this, GPUQuerySetPrototype);
+ return this[_type]();
+ }
+
+ get count() {
+ webidl.assertBranded(this, GPUQuerySetPrototype);
+ return this[_count]();
+ }
+
[SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${
inspect({
@@ -5137,12 +5224,17 @@
const GPUQuerySetPrototype = GPUQuerySet.prototype;
window.__bootstrap.webgpu = {
+ _device,
+ assertDevice,
+ createGPUTexture,
gpu: webidl.createBranded(GPU),
GPU,
GPUAdapter,
+ GPUAdapterInfo,
GPUSupportedLimits,
GPUSupportedFeatures,
GPUDevice,
+ GPUDeviceLostInfo,
GPUQueue,
GPUBuffer,
GPUBufferUsage,
@@ -5167,7 +5259,7 @@
GPURenderBundle,
GPUQuerySet,
GPUError,
- GPUOutOfMemoryError,
GPUValidationError,
+ GPUOutOfMemoryError,
};
})(this);
diff --git a/ext/webgpu/src/02_idl_types.js b/ext/webgpu/src/02_idl_types.js
index 42986d4fd..c927f10a5 100644
--- a/ext/webgpu/src/02_idl_types.js
+++ b/ext/webgpu/src/02_idl_types.js
@@ -65,12 +65,6 @@
GPUSupportedFeatures.prototype,
);
- // ENUM: GPUPredefinedColorSpace
- webidl.converters.GPUPredefinedColorSpace = webidl.createEnumConverter(
- "GPUPredefinedColorSpace",
- ["srgb"],
- );
-
// INTERFACE: GPU
webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU.prototype);
@@ -112,7 +106,6 @@
"GPUFeatureName",
[
"depth-clip-control",
- "depth24unorm-stencil8",
"depth32float-stencil8",
"pipeline-statistics-query",
"texture-compression-bc",
@@ -148,6 +141,10 @@
webidl.converters["GPUSize32"] = (V, opts) =>
webidl.converters["unsigned long"](V, { ...opts, enforceRange: true });
+ // TYPEDEF: GPUSize64
+ webidl.converters["GPUSize64"] = (V, opts) =>
+ webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true });
+
// DICTIONARY: GPUDeviceDescriptor
const dictMembersGPUDeviceDescriptor = [
{
@@ -163,7 +160,7 @@
key: "requiredLimits",
converter: webidl.createRecordConverter(
webidl.converters["DOMString"],
- webidl.converters["GPUSize32"],
+ webidl.converters["GPUSize64"],
),
},
];
@@ -185,10 +182,6 @@
GPUBuffer.prototype,
);
- // TYPEDEF: GPUSize64
- webidl.converters["GPUSize64"] = (V, opts) =>
- webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true });
-
// TYPEDEF: GPUBufferUsageFlags
webidl.converters["GPUBufferUsageFlags"] = (V, opts) =>
webidl.converters["unsigned long"](V, { ...opts, enforceRange: true });
@@ -339,7 +332,6 @@
"depth24plus",
"depth24plus-stencil8",
"depth32float",
- "depth24unorm-stencil8",
"depth32float-stencil8",
"bc1-rgba-unorm",
"bc1-rgba-unorm-srgb",
@@ -432,6 +424,15 @@
converter: webidl.converters["GPUTextureUsageFlags"],
required: true,
},
+ {
+ key: "viewFormats",
+ converter: webidl.createSequenceConverter(
+ webidl.converters["GPUTextureFormat"],
+ ),
+ get defaultValue() {
+ return [];
+ },
+ },
];
webidl.converters["GPUTextureDescriptor"] = webidl.createDictionaryConverter(
"GPUTextureDescriptor",
@@ -911,7 +912,6 @@
converter: webidl.converters["DOMString"],
required: true,
},
- { key: "sourceMap", converter: webidl.converters["object"] },
];
webidl.converters["GPUShaderModuleDescriptor"] = webidl
.createDictionaryConverter(
@@ -1842,7 +1842,6 @@
key: "depthStencilAttachment",
converter: webidl.converters["GPURenderPassDepthStencilAttachment"],
},
- { key: "occlusionQuerySet", converter: webidl.converters["GPUQuerySet"] },
];
webidl.converters["GPURenderPassDescriptor"] = webidl
.createDictionaryConverter(
diff --git a/ext/webgpu/src/03_surface.js b/ext/webgpu/src/03_surface.js
new file mode 100644
index 000000000..0152098ea
--- /dev/null
+++ b/ext/webgpu/src/03_surface.js
@@ -0,0 +1,148 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+// @ts-check
+/// <reference path="../../core/lib.deno_core.d.ts" />
+/// <reference path="../web/internal.d.ts" />
+/// <reference path="../web/lib.deno_web.d.ts" />
+/// <reference path="./lib.deno_webgpu.d.ts" />
+
+"use strict";
+
+((window) => {
+ const core = window.Deno.core;
+ const ops = core.ops;
+ const webidl = window.__bootstrap.webidl;
+ const { Symbol } = window.__bootstrap.primordials;
+ const { _device, assertDevice, createGPUTexture } = window.__bootstrap.webgpu;
+
+ const _surfaceRid = Symbol("[[surfaceRid]]");
+ const _configuration = Symbol("[[configuration]]");
+ const _canvas = Symbol("[[canvas]]");
+ const _currentTexture = Symbol("[[currentTexture]]");
+ class GPUCanvasContext {
+ /** @type {number} */
+ [_surfaceRid];
+ /** @type {InnerGPUDevice} */
+ [_device];
+ [_configuration];
+ [_canvas];
+ /** @type {GPUTexture | undefined} */
+ [_currentTexture];
+
+ get canvas() {
+ webidl.assertBranded(this, GPUCanvasContextPrototype);
+ return this[_canvas];
+ }
+
+ constructor() {
+ webidl.illegalConstructor();
+ }
+
+ configure(configuration) {
+ webidl.assertBranded(this, GPUCanvasContextPrototype);
+ const prefix = "Failed to execute 'configure' on 'GPUCanvasContext'";
+ webidl.requiredArguments(arguments.length, 1, { prefix });
+ configuration = webidl.converters.GPUCanvasConfiguration(configuration, {
+ prefix,
+ context: "Argument 1",
+ });
+
+ this[_device] = configuration.device[_device];
+ this[_configuration] = configuration;
+ const device = assertDevice(this, {
+ prefix,
+ context: "configuration.device",
+ });
+
+ const { err } = ops.op_webgpu_surface_configure({
+ surfaceRid: this[_surfaceRid],
+ deviceRid: device.rid,
+ format: configuration.format,
+ usage: configuration.usage,
+ width: configuration.width,
+ height: configuration.height,
+ alphaMode: configuration.alphaMode,
+ });
+
+ device.pushError(err);
+ }
+
+ unconfigure() {
+ webidl.assertBranded(this, GPUCanvasContextPrototype);
+
+ this[_configuration] = null;
+ this[_device] = null;
+ }
+
+ getCurrentTexture() {
+ webidl.assertBranded(this, GPUCanvasContextPrototype);
+ const prefix =
+ "Failed to execute 'getCurrentTexture' on 'GPUCanvasContext'";
+
+ if (this[_configuration] === null) {
+ throw new DOMException(
+ "context is not configured.",
+ "InvalidStateError",
+ );
+ }
+
+ const device = assertDevice(this, { prefix, context: "this" });
+
+ if (this[_currentTexture]) {
+ return this[_currentTexture];
+ }
+
+ const { rid } = ops.op_webgpu_surface_get_current_texture(
+ device.rid,
+ this[_surfaceRid],
+ );
+
+ const texture = createGPUTexture(
+ {
+ size: {
+ width: this[_configuration].width,
+ height: this[_configuration].height,
+ depthOrArrayLayers: 1,
+ },
+ mipLevelCount: 1,
+ sampleCount: 1,
+ dimension: "2d",
+ format: this[_configuration].format,
+ usage: this[_configuration].usage,
+ },
+ device,
+ rid,
+ );
+ device.trackResource(texture);
+ this[_currentTexture] = texture;
+ return texture;
+ }
+
+ // Extended from spec. Required to present the texture; browser don't need this.
+ present() {
+ webidl.assertBranded(this, GPUCanvasContextPrototype);
+ const prefix = "Failed to execute 'present' on 'GPUCanvasContext'";
+ const device = assertDevice(this[_currentTexture], {
+ prefix,
+ context: "this",
+ });
+ ops.op_webgpu_surface_present(device.rid, this[_surfaceRid]);
+ this[_currentTexture].destroy();
+ this[_currentTexture] = undefined;
+ }
+ }
+ const GPUCanvasContextPrototype = GPUCanvasContext.prototype;
+
+ function createCanvasContext(options) {
+ const canvasContext = webidl.createBranded(GPUCanvasContext);
+ canvasContext[_surfaceRid] = options.surfaceRid;
+ canvasContext[_canvas] = options.canvas;
+ return canvasContext;
+ }
+
+ window.__bootstrap.webgpu = {
+ ...window.__bootstrap.webgpu,
+ GPUCanvasContext,
+ createCanvasContext,
+ };
+})(this);
diff --git a/ext/webgpu/src/04_surface_idl_types.js b/ext/webgpu/src/04_surface_idl_types.js
new file mode 100644
index 000000000..9dcfa767e
--- /dev/null
+++ b/ext/webgpu/src/04_surface_idl_types.js
@@ -0,0 +1,86 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+// @ts-check
+/// <reference path="../../core/lib.deno_core.d.ts" />
+/// <reference path="../web/internal.d.ts" />
+/// <reference path="../web/lib.deno_web.d.ts" />
+/// <reference path="./lib.deno_webgpu.d.ts" />
+
+"use strict";
+
+((window) => {
+ const webidl = window.__bootstrap.webidl;
+ const { GPUTextureUsage } = window.__bootstrap.webgpu;
+
+ // ENUM: GPUCanvasAlphaMode
+ webidl.converters["GPUCanvasAlphaMode"] = webidl.createEnumConverter(
+ "GPUCanvasAlphaMode",
+ [
+ "opaque",
+ "premultiplied",
+ ],
+ );
+
+ // NON-SPEC: ENUM: GPUPresentMode
+ webidl.converters["GPUPresentMode"] = webidl.createEnumConverter(
+ "GPUPresentMode",
+ [
+ "autoVsync",
+ "autoNoVsync",
+ "fifo",
+ "fifoRelaxed",
+ "immediate",
+ "mailbox",
+ ],
+ );
+
+ // DICT: GPUCanvasConfiguration
+ const dictMembersGPUCanvasConfiguration = [
+ { key: "device", converter: webidl.converters.GPUDevice, required: true },
+ {
+ key: "format",
+ converter: webidl.converters.GPUTextureFormat,
+ required: true,
+ },
+ {
+ key: "usage",
+ converter: webidl.converters["GPUTextureUsageFlags"],
+ defaultValue: GPUTextureUsage.RENDER_ATTACHMENT,
+ },
+ {
+ key: "alphaMode",
+ converter: webidl.converters["GPUCanvasAlphaMode"],
+ defaultValue: "opaque",
+ },
+
+ // Extended from spec
+ {
+ key: "presentMode",
+ converter: webidl.converters["GPUPresentMode"],
+ },
+ {
+ key: "width",
+ converter: webidl.converters["long"],
+ required: true,
+ },
+ {
+ key: "height",
+ converter: webidl.converters["long"],
+ required: true,
+ },
+ {
+ key: "viewFormats",
+ converter: webidl.createSequenceConverter(
+ webidl.converters["GPUTextureFormat"],
+ ),
+ get defaultValue() {
+ return [];
+ },
+ },
+ ];
+ webidl.converters["GPUCanvasConfiguration"] = webidl
+ .createDictionaryConverter(
+ "GPUCanvasConfiguration",
+ dictMembersGPUCanvasConfiguration,
+ );
+})(this);
diff --git a/ext/webgpu/src/binding.rs b/ext/webgpu/src/binding.rs
index 7a35db503..4c4a864fd 100644
--- a/ext/webgpu/src/binding.rs
+++ b/ext/webgpu/src/binding.rs
@@ -199,7 +199,7 @@ pub fn op_webgpu_create_bind_group_layout(
gfx_put!(device => instance.device_create_bind_group_layout(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuBindGroupLayout)
}
@@ -234,7 +234,7 @@ pub fn op_webgpu_create_pipeline_layout(
gfx_put!(device => instance.device_create_pipeline_layout(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, super::pipeline::WebGpuPipelineLayout)
}
@@ -317,6 +317,6 @@ pub fn op_webgpu_create_bind_group(
gfx_put!(device => instance.device_create_bind_group(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuBindGroup)
}
diff --git a/ext/webgpu/src/buffer.rs b/ext/webgpu/src/buffer.rs
index a10642f33..58348129e 100644
--- a/ext/webgpu/src/buffer.rs
+++ b/ext/webgpu/src/buffer.rs
@@ -13,6 +13,7 @@ use std::cell::RefCell;
use std::convert::TryFrom;
use std::rc::Rc;
use std::time::Duration;
+use wgpu_core::resource::BufferAccessResult;
use super::error::DomExceptionOperationError;
use super::error::WebGpuResult;
@@ -57,7 +58,7 @@ pub fn op_webgpu_create_buffer(
gfx_put!(device => instance.device_create_buffer(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuBuffer)
}
@@ -70,7 +71,7 @@ pub async fn op_webgpu_buffer_get_map_async(
offset: u64,
size: u64,
) -> Result<WebGpuResult, AnyError> {
- let (sender, receiver) = oneshot::channel::<Result<(), AnyError>>();
+ let (sender, receiver) = oneshot::channel::<BufferAccessResult>();
let device;
{
@@ -85,12 +86,7 @@ pub async fn op_webgpu_buffer_get_map_async(
device = device_resource.0;
let callback = Box::new(move |status| {
- sender
- .send(match status {
- wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()),
- _ => unreachable!(), // TODO
- })
- .unwrap();
+ sender.send(status).unwrap();
});
// TODO(lucacasonato): error handling
@@ -120,7 +116,8 @@ pub async fn op_webgpu_buffer_get_map_async(
{
let state = state.borrow();
let instance = state.borrow::<super::Instance>();
- gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::Wait)).unwrap();
+ gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::Wait))
+ .unwrap();
}
tokio::time::sleep(Duration::from_millis(10)).await;
}
diff --git a/ext/webgpu/src/bundle.rs b/ext/webgpu/src/bundle.rs
index 13b0d0cc7..3d0f11d89 100644
--- a/ext/webgpu/src/bundle.rs
+++ b/ext/webgpu/src/bundle.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op;
use deno_core::OpState;
@@ -108,7 +109,7 @@ pub fn op_webgpu_render_bundle_encoder_finish(
&wgpu_core::command::RenderBundleDescriptor {
label: label.map(Cow::from),
},
- std::marker::PhantomData
+ ()
) => state, WebGpuRenderBundle)
}
@@ -134,8 +135,8 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group(
// Align the data
assert!(dynamic_offsets_data.len() % std::mem::size_of::<u32>() == 0);
let (prefix, dynamic_offsets_data, suffix) =
- // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
- // multiple of 4.
+ // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
+ // multiple of 4.
unsafe { dynamic_offsets_data.align_to::<u32>() };
assert!(prefix.is_empty());
assert!(suffix.is_empty());
@@ -268,16 +269,15 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
state
.resource_table
.get::<WebGpuRenderBundleEncoder>(render_bundle_encoder_rid)?;
+ let size = Some(
+ std::num::NonZeroU64::new(size)
+ .ok_or_else(|| type_error("size must be larger than 0"))?,
+ );
render_bundle_encoder_resource
.0
.borrow_mut()
- .set_index_buffer(
- buffer_resource.0,
- index_format,
- offset,
- std::num::NonZeroU64::new(size),
- );
+ .set_index_buffer(buffer_resource.0, index_format, offset, size);
Ok(WebGpuResult::empty())
}
@@ -298,13 +298,17 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer(
state
.resource_table
.get::<WebGpuRenderBundleEncoder>(render_bundle_encoder_rid)?;
+ let size = Some(
+ std::num::NonZeroU64::new(size)
+ .ok_or_else(|| type_error("size must be larger than 0"))?,
+ );
wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer(
&mut render_bundle_encoder_resource.0.borrow_mut(),
slot,
buffer_resource.0,
offset,
- std::num::NonZeroU64::new(size),
+ size,
);
Ok(WebGpuResult::empty())
diff --git a/ext/webgpu/src/command_encoder.rs b/ext/webgpu/src/command_encoder.rs
index e552a14e0..eb534f6bc 100644
--- a/ext/webgpu/src/command_encoder.rs
+++ b/ext/webgpu/src/command_encoder.rs
@@ -49,7 +49,7 @@ pub fn op_webgpu_create_command_encoder(
gfx_put!(device => instance.device_create_command_encoder(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuCommandEncoder)
}
@@ -84,7 +84,6 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
label: Option<String>,
color_attachments: Vec<Option<GpuRenderPassColorAttachment>>,
depth_stencil_attachment: Option<GpuRenderPassDepthStencilAttachment>,
- _occlusion_query_set: Option<u32>, // not yet implemented
) -> Result<WebGpuResult, AnyError> {
let command_encoder_resource = state
.resource_table
diff --git a/ext/webgpu/src/compute_pass.rs b/ext/webgpu/src/compute_pass.rs
index 71f9dfe3b..8132b450c 100644
--- a/ext/webgpu/src/compute_pass.rs
+++ b/ext/webgpu/src/compute_pass.rs
@@ -194,8 +194,8 @@ pub fn op_webgpu_compute_pass_set_bind_group(
// Align the data
assert!(dynamic_offsets_data_start % std::mem::size_of::<u32>() == 0);
let (prefix, dynamic_offsets_data, suffix) =
- // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
- // multiple of 4.
+ // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
+ // multiple of 4.
unsafe { dynamic_offsets_data.align_to::<u32>() };
assert!(prefix.is_empty());
assert!(suffix.is_empty());
diff --git a/ext/webgpu/src/error.rs b/ext/webgpu/src/error.rs
index 55ef223a1..41d7d6cf3 100644
--- a/ext/webgpu/src/error.rs
+++ b/ext/webgpu/src/error.rs
@@ -5,7 +5,6 @@ use serde::Serialize;
use std::convert::From;
use std::error::Error;
use std::fmt;
-use std::fmt::Write;
use wgpu_core::binding_model::CreateBindGroupError;
use wgpu_core::binding_model::CreateBindGroupLayoutError;
use wgpu_core::binding_model::CreatePipelineLayoutError;
@@ -24,6 +23,8 @@ use wgpu_core::device::DeviceError;
use wgpu_core::pipeline::CreateComputePipelineError;
use wgpu_core::pipeline::CreateRenderPipelineError;
use wgpu_core::pipeline::CreateShaderModuleError;
+#[cfg(feature = "surface")]
+use wgpu_core::present::ConfigureSurfaceError;
use wgpu_core::resource::BufferAccessError;
use wgpu_core::resource::CreateBufferError;
use wgpu_core::resource::CreateQuerySetError;
@@ -36,9 +37,7 @@ fn fmt_err(err: &(dyn Error + 'static)) -> String {
let mut e = err.source();
while let Some(source) = e {
- // No error possible, unwrap is fine here.
- // https://github.com/rust-lang/rust/blob/1.47.0/library/alloc/src/string.rs#L2414-L2427
- write!(output, ": {source}").unwrap();
+ output.push_str(&format!(": {source}"));
e = source.source();
}
@@ -281,6 +280,13 @@ impl From<ClearError> for WebGpuError {
}
}
+#[cfg(feature = "surface")]
+impl From<ConfigureSurfaceError> for WebGpuError {
+ fn from(err: ConfigureSurfaceError) -> Self {
+ WebGpuError::Validation(fmt_err(&err))
+ }
+}
+
#[derive(Debug)]
pub struct DomExceptionOperationError {
pub msg: String,
diff --git a/ext/webgpu/src/lib.rs b/ext/webgpu/src/lib.rs
index d1fb55dbf..d4fd5660a 100644
--- a/ext/webgpu/src/lib.rs
+++ b/ext/webgpu/src/lib.rs
@@ -1,5 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+#![warn(unsafe_op_in_unsafe_fn)]
+
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
@@ -25,13 +27,22 @@ mod macros {
macro_rules! gfx_select {
($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {
match $id.backend() {
- #[cfg(not(target_os = "macos"))]
+ #[cfg(any(
+ all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")),
+ feature = "vulkan-portability"
+ ))]
wgpu_types::Backend::Vulkan => $global.$method::<wgpu_core::api::Vulkan>( $($param),* ),
- #[cfg(target_os = "macos")]
+ #[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
wgpu_types::Backend::Metal => $global.$method::<wgpu_core::api::Metal>( $($param),* ),
- #[cfg(windows)]
+ #[cfg(all(not(target_arch = "wasm32"), windows))]
wgpu_types::Backend::Dx12 => $global.$method::<wgpu_core::api::Dx12>( $($param),* ),
- #[cfg(all(unix, not(target_os = "macos")))]
+ #[cfg(all(not(target_arch = "wasm32"), windows))]
+ wgpu_types::Backend::Dx11 => $global.$method::<wgpu_core::api::Dx11>( $($param),* ),
+ #[cfg(any(
+ all(unix, not(target_os = "macos"), not(target_os = "ios")),
+ feature = "angle",
+ target_arch = "wasm32"
+ ))]
wgpu_types::Backend::Gl => $global.$method::<wgpu_core::api::Gles>( $($param),+ ),
other => panic!("Unexpected backend {:?}", other),
}
@@ -65,6 +76,8 @@ pub mod queue;
pub mod render_pass;
pub mod sampler;
pub mod shader;
+#[cfg(feature = "surface")]
+pub mod surface;
pub mod texture;
pub struct Unstable(pub bool);
@@ -79,7 +92,8 @@ fn check_unstable(state: &OpState, api_name: &str) {
}
}
-type Instance = wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>;
+pub type Instance =
+ wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>;
struct WebGpuAdapter(wgpu_core::id::AdapterId);
impl Resource for WebGpuAdapter {
@@ -128,9 +142,6 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) {
return_features.push("depth-clip-control");
}
- if features.contains(wgpu_types::Features::DEPTH24UNORM_STENCIL8) {
- return_features.push("depth24unorm-stencil8");
- }
if features.contains(wgpu_types::Features::DEPTH32FLOAT_STENCIL8) {
return_features.push("depth32float-stencil8");
}
@@ -243,7 +254,10 @@ pub async fn op_webgpu_request_adapter(
state.put(wgpu_core::hub::Global::new(
"webgpu",
wgpu_core::hub::IdentityManagerFactory,
- backends,
+ wgpu_types::InstanceDescriptor {
+ backends,
+ dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc,
+ },
));
state.borrow::<Instance>()
};
@@ -255,9 +269,7 @@ pub async fn op_webgpu_request_adapter(
};
let res = instance.request_adapter(
&descriptor,
- wgpu_core::instance::AdapterInputs::Mask(backends, |_| {
- std::marker::PhantomData
- }),
+ wgpu_core::instance::AdapterInputs::Mask(backends, |_| ()),
);
let adapter = match res {
@@ -295,10 +307,6 @@ impl From<GpuRequiredFeatures> for wgpu_types::Features {
required_features.0.contains("depth-clip-control"),
);
features.set(
- wgpu_types::Features::DEPTH24UNORM_STENCIL8,
- required_features.0.contains("depth24unorm-stencil8"),
- );
- features.set(
wgpu_types::Features::DEPTH32FLOAT_STENCIL8,
required_features.0.contains("depth32float-stencil8"),
);
@@ -427,7 +435,7 @@ pub async fn op_webgpu_request_device(
adapter,
&descriptor,
std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new),
- std::marker::PhantomData
+ ()
));
if let Some(err) = maybe_err {
return Err(DomExceptionOperationError::new(&err.to_string()).into());
@@ -553,7 +561,7 @@ pub fn op_webgpu_create_query_set(
gfx_put!(device => instance.device_create_query_set(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuQuerySet)
}
diff --git a/ext/webgpu/src/pipeline.rs b/ext/webgpu/src/pipeline.rs
index ba90eedf0..2e728d8d9 100644
--- a/ext/webgpu/src/pipeline.rs
+++ b/ext/webgpu/src/pipeline.rs
@@ -102,8 +102,8 @@ pub fn op_webgpu_create_compute_pipeline(
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
Some(wgpu_core::device::ImplicitPipelineIds {
- root_id: std::marker::PhantomData,
- group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS],
+ root_id: (),
+ group_ids: &[(); MAX_BIND_GROUPS],
})
}
};
@@ -111,7 +111,7 @@ pub fn op_webgpu_create_compute_pipeline(
let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline(
device,
&descriptor,
- std::marker::PhantomData,
+ (),
implicit_pipelines
));
@@ -142,7 +142,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
.get::<WebGpuComputePipeline>(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, index, std::marker::PhantomData));
+ let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, ()));
let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));
@@ -376,8 +376,8 @@ pub fn op_webgpu_create_render_pipeline(
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
Some(wgpu_core::device::ImplicitPipelineIds {
- root_id: std::marker::PhantomData,
- group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS],
+ root_id: (),
+ group_ids: &[(); MAX_BIND_GROUPS],
})
}
};
@@ -385,7 +385,7 @@ pub fn op_webgpu_create_render_pipeline(
let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline(
device,
&descriptor,
- std::marker::PhantomData,
+ (),
implicit_pipelines
));
@@ -408,7 +408,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout(
.get::<WebGpuRenderPipeline>(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, index, std::marker::PhantomData));
+ let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, index, ()));
let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));
diff --git a/ext/webgpu/src/render_pass.rs b/ext/webgpu/src/render_pass.rs
index 85440b18d..ee38091bc 100644
--- a/ext/webgpu/src/render_pass.rs
+++ b/ext/webgpu/src/render_pass.rs
@@ -254,8 +254,8 @@ pub fn op_webgpu_render_pass_set_bind_group(
// Align the data
assert_eq!(dynamic_offsets_data_start % std::mem::size_of::<u32>(), 0);
let (prefix, dynamic_offsets_data, suffix) =
- // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
- // multiple of 4.
+ // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a
+ // multiple of 4.
unsafe { dynamic_offsets_data.align_to::<u32>() };
assert!(prefix.is_empty());
assert!(suffix.is_empty());
diff --git a/ext/webgpu/src/sampler.rs b/ext/webgpu/src/sampler.rs
index f2f1037f1..b377f6835 100644
--- a/ext/webgpu/src/sampler.rs
+++ b/ext/webgpu/src/sampler.rs
@@ -65,6 +65,6 @@ pub fn op_webgpu_create_sampler(
gfx_put!(device => instance.device_create_sampler(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuSampler)
}
diff --git a/ext/webgpu/src/shader.rs b/ext/webgpu/src/shader.rs
index f45ab4400..242cb85ba 100644
--- a/ext/webgpu/src/shader.rs
+++ b/ext/webgpu/src/shader.rs
@@ -22,7 +22,6 @@ pub fn op_webgpu_create_shader_module(
device_rid: ResourceId,
label: Option<String>,
code: String,
- _source_map: Option<()>, // not yet implemented
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
@@ -41,6 +40,6 @@ pub fn op_webgpu_create_shader_module(
device,
&descriptor,
source,
- std::marker::PhantomData
+ ()
) => state, WebGpuShaderModule)
}
diff --git a/ext/webgpu/src/surface.rs b/ext/webgpu/src/surface.rs
new file mode 100644
index 000000000..1adebb53a
--- /dev/null
+++ b/ext/webgpu/src/surface.rs
@@ -0,0 +1,137 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+use super::WebGpuResult;
+use deno_core::error::AnyError;
+use deno_core::include_js_files;
+use deno_core::op;
+use deno_core::Extension;
+use deno_core::OpState;
+use deno_core::Resource;
+use deno_core::ResourceId;
+use serde::Deserialize;
+use std::borrow::Cow;
+use wgpu_types::SurfaceStatus;
+
+pub fn init_surface(unstable: bool) -> Extension {
+ Extension::builder("deno_webgpu_surface")
+ .dependencies(vec!["deno_webidl", "deno_web", "deno_webgpu"])
+ .js(include_js_files!(
+ prefix "deno:deno_webgpu",
+ "03_surface.js",
+ "04_surface_idl_types.js",
+ ))
+ .ops(vec![
+ op_webgpu_surface_configure::decl(),
+ op_webgpu_surface_get_current_texture::decl(),
+ op_webgpu_surface_present::decl(),
+ ])
+ .state(move |state| {
+ // TODO: check & possibly streamline this
+ // Unstable might be able to be OpMiddleware
+ // let unstable_checker = state.borrow::<super::UnstableChecker>();
+ // let unstable = unstable_checker.unstable;
+ state.put(super::Unstable(unstable));
+ Ok(())
+ })
+ .build()
+}
+
+pub struct WebGpuSurface(pub wgpu_core::id::SurfaceId);
+impl Resource for WebGpuSurface {
+ fn name(&self) -> Cow<str> {
+ "webGPUSurface".into()
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SurfaceConfigureArgs {
+ surface_rid: ResourceId,
+ device_rid: ResourceId,
+ format: wgpu_types::TextureFormat,
+ usage: u32,
+ width: u32,
+ height: u32,
+ present_mode: Option<wgpu_types::PresentMode>,
+ alpha_mode: wgpu_types::CompositeAlphaMode,
+ view_formats: Vec<wgpu_types::TextureFormat>,
+}
+
+#[op]
+pub fn op_webgpu_surface_configure(
+ state: &mut OpState,
+ args: SurfaceConfigureArgs,
+) -> 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 surface_resource = state
+ .resource_table
+ .get::<WebGpuSurface>(args.surface_rid)?;
+ let surface = surface_resource.0;
+
+ let conf = wgpu_types::SurfaceConfiguration::<Vec<wgpu_types::TextureFormat>> {
+ usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage),
+ format: args.format,
+ width: args.width,
+ height: args.height,
+ present_mode: args.present_mode.unwrap_or_default(),
+ alpha_mode: args.alpha_mode,
+ view_formats: args.view_formats,
+ };
+
+ let err =
+ gfx_select!(device => instance.surface_configure(surface, device, &conf));
+
+ Ok(WebGpuResult::maybe_err(err))
+}
+
+#[op]
+pub fn op_webgpu_surface_get_current_texture(
+ state: &mut OpState,
+ device_rid: ResourceId,
+ surface_rid: ResourceId,
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(device_rid)?;
+ let device = device_resource.0;
+ let surface_resource =
+ state.resource_table.get::<WebGpuSurface>(surface_rid)?;
+ let surface = surface_resource.0;
+
+ let output =
+ gfx_select!(device => instance.surface_get_current_texture(surface, ()))?;
+
+ match output.status {
+ SurfaceStatus::Good | SurfaceStatus::Suboptimal => {
+ let id = output.texture_id.unwrap();
+ let rid = state.resource_table.add(crate::texture::WebGpuTexture(id));
+ Ok(WebGpuResult::rid(rid))
+ }
+ _ => Err(AnyError::msg("Invalid Surface Status")),
+ }
+}
+
+#[op]
+pub fn op_webgpu_surface_present(
+ state: &mut OpState,
+ device_rid: ResourceId,
+ surface_rid: ResourceId,
+) -> Result<(), AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(device_rid)?;
+ let device = device_resource.0;
+ let surface_resource =
+ state.resource_table.get::<WebGpuSurface>(surface_rid)?;
+ let surface = surface_resource.0;
+
+ let _ = gfx_select!(device => instance.surface_present(surface))?;
+
+ Ok(())
+}
diff --git a/ext/webgpu/src/texture.rs b/ext/webgpu/src/texture.rs
index 9a6a1e939..c4b36c288 100644
--- a/ext/webgpu/src/texture.rs
+++ b/ext/webgpu/src/texture.rs
@@ -34,6 +34,7 @@ pub struct CreateTextureArgs {
dimension: wgpu_types::TextureDimension,
format: wgpu_types::TextureFormat,
usage: u32,
+ view_formats: Vec<wgpu_types::TextureFormat>,
}
#[op]
@@ -55,12 +56,13 @@ pub fn op_webgpu_create_texture(
dimension: args.dimension,
format: args.format,
usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage),
+ view_formats: args.view_formats,
};
gfx_put!(device => instance.device_create_texture(
device,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuTexture)
}
@@ -109,6 +111,6 @@ pub fn op_webgpu_create_texture_view(
gfx_put!(texture => instance.texture_create_view(
texture,
&descriptor,
- std::marker::PhantomData
+ ()
) => state, WebGpuTextureView)
}
diff --git a/ext/webgpu/webgpu.idl b/ext/webgpu/webgpu.idl
index cda505715..4b8865e30 100644
--- a/ext/webgpu/webgpu.idl
+++ b/ext/webgpu/webgpu.idl
@@ -13,6 +13,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension3D;
readonly attribute unsigned long maxTextureArrayLayers;
readonly attribute unsigned long maxBindGroups;
+ readonly attribute unsigned long maxBindingsPerBindGroup;
readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout;
readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout;
readonly attribute unsigned long maxSampledTexturesPerShaderStage;
@@ -25,6 +26,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long minUniformBufferOffsetAlignment;
readonly attribute unsigned long minStorageBufferOffsetAlignment;
readonly attribute unsigned long maxVertexBuffers;
+ readonly attribute unsigned long long maxBufferSize;
readonly attribute unsigned long maxVertexAttributes;
readonly attribute unsigned long maxVertexBufferArrayStride;
readonly attribute unsigned long maxInterStageShaderComponents;
@@ -43,14 +45,10 @@ interface GPUSupportedFeatures {
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUAdapterInfo {
- readonly attribute DOMString vendor;
- readonly attribute DOMString architecture;
- readonly attribute DOMString device;
- readonly attribute DOMString description;
-};
-
-enum GPUPredefinedColorSpace {
- "srgb",
+ readonly attribute DOMString vendor;
+ readonly attribute DOMString architecture;
+ readonly attribute DOMString device;
+ readonly attribute DOMString description;
};
interface mixin NavigatorGPU {
@@ -71,7 +69,7 @@ dictionary GPURequestAdapterOptions {
enum GPUPowerPreference {
"low-power",
- "high-performance",
+ "high-performance"
};
[Exposed=(Window, DedicatedWorker), SecureContext]
@@ -91,7 +89,6 @@ dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
enum GPUFeatureName {
"depth-clip-control",
- "depth24unorm-stencil8",
"depth32float-stencil8",
"texture-compression-bc",
"texture-compression-etc2",
@@ -133,6 +130,11 @@ GPUDevice includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBuffer {
+ readonly attribute GPUSize64 size;
+ readonly attribute GPUBufferUsageFlags usage;
+
+ readonly attribute GPUBufferMapState mapState;
+
Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
undefined unmap();
@@ -141,6 +143,12 @@ interface GPUBuffer {
};
GPUBuffer includes GPUObjectBase;
+enum GPUBufferMapState {
+ "unmapped",
+ "pending",
+ "mapped"
+};
+
dictionary GPUBufferDescriptor : GPUObjectDescriptorBase {
required GPUSize64 size;
required GPUBufferUsageFlags usage;
@@ -174,6 +182,15 @@ interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
undefined destroy();
+
+ readonly attribute GPUIntegerCoordinate width;
+ readonly attribute GPUIntegerCoordinate height;
+ readonly attribute GPUIntegerCoordinate depthOrArrayLayers;
+ readonly attribute GPUIntegerCoordinate mipLevelCount;
+ readonly attribute GPUSize32 sampleCount;
+ readonly attribute GPUTextureDimension dimension;
+ readonly attribute GPUTextureFormat format;
+ readonly attribute GPUTextureUsageFlags usage;
};
GPUTexture includes GPUObjectBase;
@@ -184,12 +201,13 @@ dictionary GPUTextureDescriptor : GPUObjectDescriptorBase {
GPUTextureDimension dimension = "2d";
required GPUTextureFormat format;
required GPUTextureUsageFlags usage;
+ sequence<GPUTextureFormat> viewFormats = [];
};
enum GPUTextureDimension {
"1d",
"2d",
- "3d",
+ "3d"
};
typedef [EnforceRange] unsigned long GPUTextureUsageFlags;
@@ -223,13 +241,13 @@ enum GPUTextureViewDimension {
"2d-array",
"cube",
"cube-array",
- "3d",
+ "3d"
};
enum GPUTextureAspect {
"all",
"stencil-only",
- "depth-only",
+ "depth-only"
};
enum GPUTextureFormat {
@@ -287,9 +305,6 @@ enum GPUTextureFormat {
"depth24plus-stencil8",
"depth32float",
- // "depth24unorm-stencil8" feature
- "depth24unorm-stencil8",
-
// "depth32float-stencil8" feature
"depth32float-stencil8",
@@ -352,7 +367,7 @@ enum GPUTextureFormat {
"astc-12x10-unorm",
"astc-12x10-unorm-srgb",
"astc-12x12-unorm",
- "astc-12x12-unorm-srgb",
+ "astc-12x12-unorm-srgb"
};
[Exposed=(Window, DedicatedWorker), SecureContext]
@@ -376,17 +391,17 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
enum GPUAddressMode {
"clamp-to-edge",
"repeat",
- "mirror-repeat",
+ "mirror-repeat"
};
enum GPUFilterMode {
"nearest",
- "linear",
+ "linear"
};
enum GPUMipmapFilterMode {
"nearest",
- "linear",
+ "linear"
};
enum GPUCompareFunction {
@@ -397,7 +412,7 @@ enum GPUCompareFunction {
"greater",
"not-equal",
"greater-equal",
- "always",
+ "always"
};
[Exposed=(Window, DedicatedWorker), SecureContext]
@@ -430,7 +445,7 @@ namespace GPUShaderStage {
enum GPUBufferBindingType {
"uniform",
"storage",
- "read-only-storage",
+ "read-only-storage"
};
dictionary GPUBufferBindingLayout {
@@ -442,7 +457,7 @@ dictionary GPUBufferBindingLayout {
enum GPUSamplerBindingType {
"filtering",
"non-filtering",
- "comparison",
+ "comparison"
};
dictionary GPUSamplerBindingLayout {
@@ -454,7 +469,7 @@ enum GPUTextureSampleType {
"unfilterable-float",
"depth",
"sint",
- "uint",
+ "uint"
};
dictionary GPUTextureBindingLayout {
@@ -464,7 +479,7 @@ dictionary GPUTextureBindingLayout {
};
enum GPUStorageTextureAccess {
- "write-only",
+ "write-only"
};
dictionary GPUStorageTextureBindingLayout {
@@ -513,13 +528,12 @@ GPUShaderModule includes GPUObjectBase;
dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
required USVString code;
- object sourceMap;
};
enum GPUCompilationMessageType {
"error",
"warning",
- "info",
+ "info"
};
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
@@ -555,7 +569,7 @@ dictionary GPUProgrammableStage {
record<USVString, GPUPipelineConstantValue> constants;
};
-typedef double GPUPipelineConstantValue; // May represent WGSL’s bool, f32, i32, u32.
+typedef double GPUPipelineConstantValue; // May represent WGSL’s bool, f32, i32, u32, and f16 if enabled.
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUComputePipeline {
@@ -596,18 +610,18 @@ enum GPUPrimitiveTopology {
"line-list",
"line-strip",
"triangle-list",
- "triangle-strip",
+ "triangle-strip"
};
enum GPUFrontFace {
"ccw",
- "cw",
+ "cw"
};
enum GPUCullMode {
"none",
"front",
- "back",
+ "back"
};
dictionary GPUMultisampleState {
@@ -661,7 +675,7 @@ enum GPUBlendFactor {
"one-minus-dst-alpha",
"src-alpha-saturated",
"constant",
- "one-minus-constant",
+ "one-minus-constant"
};
enum GPUBlendOperation {
@@ -669,7 +683,7 @@ enum GPUBlendOperation {
"subtract",
"reverse-subtract",
"min",
- "max",
+ "max"
};
dictionary GPUDepthStencilState {
@@ -704,12 +718,12 @@ enum GPUStencilOperation {
"increment-clamp",
"decrement-clamp",
"increment-wrap",
- "decrement-wrap",
+ "decrement-wrap"
};
enum GPUIndexFormat {
"uint16",
- "uint32",
+ "uint32"
};
enum GPUVertexFormat {
@@ -742,12 +756,12 @@ enum GPUVertexFormat {
"sint32",
"sint32x2",
"sint32x3",
- "sint32x4",
+ "sint32x4"
};
enum GPUVertexStepMode {
"vertex",
- "instance",
+ "instance"
};
dictionary GPUVertexState : GPUProgrammableStage {
@@ -767,6 +781,23 @@ dictionary GPUVertexAttribute {
required GPUIndex32 shaderLocation;
};
+dictionary GPUImageDataLayout {
+ GPUSize64 offset = 0;
+ GPUSize32 bytesPerRow;
+ GPUSize32 rowsPerImage;
+};
+
+dictionary GPUImageCopyBuffer : GPUImageDataLayout {
+ required GPUBuffer buffer;
+};
+
+dictionary GPUImageCopyTexture {
+ required GPUTexture texture;
+ GPUIntegerCoordinate mipLevel = 0;
+ GPUOrigin3D origin = {};
+ GPUTextureAspect aspect = "all";
+};
+
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCommandBuffer {
};
@@ -828,31 +859,14 @@ GPUCommandEncoder includes GPUDebugCommandsMixin;
dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
};
-dictionary GPUImageDataLayout {
- GPUSize64 offset = 0;
- GPUSize32 bytesPerRow;
- GPUSize32 rowsPerImage;
-};
-
-dictionary GPUImageCopyBuffer : GPUImageDataLayout {
- required GPUBuffer buffer;
-};
-
-dictionary GPUImageCopyTexture {
- required GPUTexture texture;
- GPUIntegerCoordinate mipLevel = 0;
- GPUOrigin3D origin = {};
- GPUTextureAspect aspect = "all";
-};
-
interface mixin GPUBindingCommandsMixin {
undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup,
- optional sequence<GPUBufferDynamicOffset> dynamicOffsets = []);
+ optional sequence<GPUBufferDynamicOffset> dynamicOffsets = []);
undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup,
- Uint32Array dynamicOffsetsData,
- GPUSize64 dynamicOffsetsDataStart,
- GPUSize32 dynamicOffsetsDataLength);
+ Uint32Array dynamicOffsetsData,
+ GPUSize64 dynamicOffsetsDataStart,
+ GPUSize32 dynamicOffsetsDataLength);
};
interface mixin GPUDebugCommandsMixin {
@@ -885,8 +899,8 @@ dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase {
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderPassEncoder {
undefined setViewport(float x, float y,
- float width, float height,
- float minDepth, float maxDepth);
+ float width, float height,
+ float minDepth, float maxDepth);
undefined setScissorRect(GPUIntegerCoordinate x, GPUIntegerCoordinate y,
GPUIntegerCoordinate width, GPUIntegerCoordinate height);
@@ -914,7 +928,6 @@ GPURenderPassEncoder includes GPURenderCommandsMixin;
dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase {
required sequence<GPURenderPassColorAttachment?> colorAttachments;
GPURenderPassDepthStencilAttachment depthStencilAttachment;
- GPUQuerySet occlusionQuerySet;
};
dictionary GPURenderPassColorAttachment {
@@ -942,15 +955,15 @@ dictionary GPURenderPassDepthStencilAttachment {
enum GPULoadOp {
"load",
- "clear",
+ "clear"
};
enum GPUStoreOp {
"store",
- "discard",
+ "discard"
};
-dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
+dictionary GPURenderPassLayout : GPUObjectDescriptorBase {
required sequence<GPUTextureFormat?> colorFormats;
GPUTextureFormat depthStencilFormat;
GPUSize32 sampleCount = 1;
@@ -963,11 +976,11 @@ interface mixin GPURenderCommandsMixin {
undefined setVertexBuffer(GPUIndex32 slot, GPUBuffer buffer, optional GPUSize64 offset = 0, optional GPUSize64 size);
undefined draw(GPUSize32 vertexCount, optional GPUSize32 instanceCount = 1,
- optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0);
+ optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0);
undefined drawIndexed(GPUSize32 indexCount, optional GPUSize32 instanceCount = 1,
- optional GPUSize32 firstIndex = 0,
- optional GPUSignedOffset32 baseVertex = 0,
- optional GPUSize32 firstInstance = 0);
+ optional GPUSize32 firstIndex = 0,
+ optional GPUSignedOffset32 baseVertex = 0,
+ optional GPUSize32 firstInstance = 0);
undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
@@ -1020,6 +1033,9 @@ GPUQueue includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUQuerySet {
undefined destroy();
+
+ readonly attribute GPUQueryType type;
+ readonly attribute GPUSize32 count;
};
GPUQuerySet includes GPUObjectBase;
@@ -1032,7 +1048,7 @@ dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
enum GPUQueryType {
"occlusion",
"pipeline-statistics",
- "timestamp",
+ "timestamp"
};
enum GPUPipelineStatisticName {
@@ -1043,8 +1059,31 @@ enum GPUPipelineStatisticName {
"compute-shader-invocations",
};
+[Exposed=(Window, DedicatedWorker), SecureContext]
+interface GPUCanvasContext {
+ readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
+
+ undefined configure(GPUCanvasConfiguration configuration);
+ undefined unconfigure();
+
+ GPUTexture getCurrentTexture();
+};
+
+enum GPUCanvasAlphaMode {
+ "opaque",
+ "premultiplied"
+};
+
+dictionary GPUCanvasConfiguration {
+ required GPUDevice device;
+ required GPUTextureFormat format;
+ GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.RENDER_ATTACHMENT
+ GPUCanvasAlphaMode alphaMode = "opaque";
+ sequence<GPUTextureFormat> viewFormats = [];
+};
+
enum GPUDeviceLostReason {
- "destroyed",
+ "destroyed"
};
[Exposed=(Window, DedicatedWorker), SecureContext]
@@ -1057,44 +1096,31 @@ partial interface GPUDevice {
readonly attribute Promise<GPUDeviceLostInfo> lost;
};
-enum GPUErrorFilter {
- "out-of-memory",
- "validation",
-};
-
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUError {
readonly attribute DOMString message;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
-interface GPUOutOfMemoryError : GPUError {
+interface GPUValidationError : GPUError {
constructor(DOMString message);
};
[Exposed=(Window, DedicatedWorker), SecureContext]
-interface GPUValidationError : GPUError {
+interface GPUOutOfMemoryError : GPUError {
constructor(DOMString message);
};
+enum GPUErrorFilter {
+ "validation",
+ "out-of-memory"
+};
+
partial interface GPUDevice {
undefined pushErrorScope(GPUErrorFilter filter);
Promise<GPUError?> popErrorScope();
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
-interface GPUUncapturedErrorEvent : Event {
- constructor(
- DOMString type,
- GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict
- );
- readonly attribute GPUError error;
-};
-
-dictionary GPUUncapturedErrorEventInit : EventInit {
- required GPUError error;
-};
-
partial interface GPUDevice {
[Exposed=(Window, DedicatedWorker)]
attribute EventHandler onuncapturederror;
diff --git a/runtime/js/98_global_scope.js b/runtime/js/98_global_scope.js
index 5a3dfffb0..499538a32 100644
--- a/runtime/js/98_global_scope.js
+++ b/runtime/js/98_global_scope.js
@@ -144,8 +144,10 @@
GPU: util.nonEnumerable(webgpu.GPU),
GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter),
+ GPUAdapterInfo: util.nonEnumerable(webgpu.GPUAdapterInfo),
GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits),
GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures),
+ GPUDeviceLostInfo: util.nonEnumerable(webgpu.GPUDeviceLostInfo),
GPUDevice: util.nonEnumerable(webgpu.GPUDevice),
GPUQueue: util.nonEnumerable(webgpu.GPUQueue),
GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer),
@@ -170,6 +172,7 @@
GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder),
GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle),
GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet),
+ GPUError: util.nonEnumerable(webgpu.GPUError),
GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError),
GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError),
};
diff --git a/tools/wgpu_sync.js b/tools/wgpu_sync.js
index ba3267042..6c6130d39 100755
--- a/tools/wgpu_sync.js
+++ b/tools/wgpu_sync.js
@@ -3,9 +3,9 @@
import { join, ROOT_PATH } from "./util.js";
-const COMMIT = "076df1a56812eee01614b7a3a4c88798012e79ab";
+const COMMIT = "659f6977051345e4e06ab4832c6f7d268f25a1ad";
const REPO = "gfx-rs/wgpu";
-const V_WGPU = "0.13";
+const V_WGPU = "0.15";
const TARGET_DIR = join(ROOT_PATH, "ext", "webgpu");
async function bash(subcmd, opts = {}) {
@@ -59,21 +59,25 @@ async function patchCargo() {
data
.replace(/^version = .*/m, `version = "${vDenoWebgpu}"`)
.replace(
- /^wgpu-core \= .*$/gm,
- `wgpu-core = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`,
+ /^repository.workspace = true/m,
+ `repository = "https://github.com/gfx-rs/wgpu"`,
)
.replace(
- /^wgpu-types \= .*$/gm,
- `wgpu-types = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`,
+ /^serde = { workspace = true, features = ["derive"] }/m,
+ `serde.workspace = true`,
+ )
+ .replace(
+ /^tokio = { workspace = true, features = ["full"] }/m,
+ `tokio.workspace = true`,
),
- // .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 patchFile(
+ join(ROOT_PATH, "Cargo.toml"),
+ (data) =>
+ data
+ .replace(/^wgpu-core = .*/m, `wgpu-core = "${V_WGPU}"`)
+ .replace(/^wgpu-types = .*/m, `wgpu-types = "${V_WGPU}"`),
);
}