summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--ext/webgpu/00_init.js39
-rw-r--r--ext/webgpu/01_webgpu.js72
-rw-r--r--ext/webgpu/02_surface.js107
-rw-r--r--ext/webgpu/Cargo.toml3
-rw-r--r--ext/webgpu/error.rs2
-rw-r--r--ext/webgpu/lib.rs6
-rw-r--r--ext/webgpu/surface.rs11
-rw-r--r--runtime/js/98_global_scope.js40
9 files changed, 142 insertions, 140 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f4bcfcb35..5d388196b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -172,7 +172,7 @@ hkdf = "0.12.3"
# webgpu
raw-window-handle = "0.5.0"
-wgpu-core = "=0.18"
+wgpu-core = { version = "=0.18", features = ["raw-window-handle"] }
wgpu-types = "=0.18"
wgpu-hal = "=0.18"
diff --git a/ext/webgpu/00_init.js b/ext/webgpu/00_init.js
new file mode 100644
index 000000000..b559fe3db
--- /dev/null
+++ b/ext/webgpu/00_init.js
@@ -0,0 +1,39 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+import { core } from "ext:core/mod.js";
+const ops = core.ops;
+
+let webgpu;
+
+function webGPUNonEnumerable(getter) {
+ let valueIsSet = false;
+ let value;
+
+ return {
+ get() {
+ loadWebGPU();
+
+ if (valueIsSet) {
+ return value;
+ } else {
+ return getter();
+ }
+ },
+ set(v) {
+ loadWebGPU();
+
+ valueIsSet = true;
+ value = v;
+ },
+ enumerable: false,
+ configurable: true,
+ };
+}
+
+function loadWebGPU() {
+ if (!webgpu) {
+ webgpu = ops.op_lazy_load_esm("ext:deno_webgpu/01_webgpu.js");
+ }
+}
+
+export { loadWebGPU, webgpu, webGPUNonEnumerable };
diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js
index c8258621f..0dd660d42 100644
--- a/ext/webgpu/01_webgpu.js
+++ b/ext/webgpu/01_webgpu.js
@@ -7036,6 +7036,78 @@ webidl.converters["GPUSignedOffset32"] = (V, opts) =>
// TYPEDEF: GPUFlagsConstant
webidl.converters["GPUFlagsConstant"] = webidl.converters["unsigned long"];
+// 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,
+ );
+
const gpu = webidl.createBranded(GPU);
export {
_device,
diff --git a/ext/webgpu/02_surface.js b/ext/webgpu/02_surface.js
index fb767e52a..9ae7fb54d 100644
--- a/ext/webgpu/02_surface.js
+++ b/ext/webgpu/02_surface.js
@@ -11,22 +11,16 @@ const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
const { Symbol, SymbolFor, ObjectPrototypeIsPrototypeOf } = primordials;
-import {
- _device,
- assertDevice,
- createGPUTexture,
- GPUTextureUsage,
-} from "ext:deno_webgpu/01_webgpu.js";
+import { loadWebGPU, webgpu } from "ext:deno_webgpu/00_init.js";
const _surfaceRid = Symbol("[[surfaceRid]]");
const _configuration = Symbol("[[configuration]]");
const _canvas = Symbol("[[canvas]]");
const _currentTexture = Symbol("[[currentTexture]]");
+const _present = Symbol("[[present]]");
class GPUCanvasContext {
/** @type {number} */
[_surfaceRid];
- /** @type {InnerGPUDevice} */
- [_device];
[_configuration];
[_canvas];
/** @type {GPUTexture | undefined} */
@@ -50,6 +44,7 @@ class GPUCanvasContext {
context: "Argument 1",
});
+ const { _device, assertDevice } = webgpu;
this[_device] = configuration.device[_device];
this[_configuration] = configuration;
const device = assertDevice(this, {
@@ -72,6 +67,8 @@ class GPUCanvasContext {
}
unconfigure() {
+ const { _device } = webgpu;
+
webidl.assertBranded(this, GPUCanvasContextPrototype);
this[_configuration] = null;
@@ -86,6 +83,7 @@ class GPUCanvasContext {
if (this[_configuration] === null) {
throw new DOMException("context is not configured.", "InvalidStateError");
}
+ const { createGPUTexture, assertDevice } = webgpu;
const device = assertDevice(this, { prefix, context: "this" });
@@ -119,8 +117,10 @@ class GPUCanvasContext {
return texture;
}
- // Extended from spec. Required to present the texture; browser don't need this.
- present() {
+ // Required to present the texture; browser don't need this.
+ [_present]() {
+ const { assertDevice } = webgpu;
+
webidl.assertBranded(this, GPUCanvasContextPrototype);
const prefix = "Failed to execute 'present' on 'GPUCanvasContext'";
const device = assertDevice(this[_currentTexture], {
@@ -148,88 +148,17 @@ class GPUCanvasContext {
const GPUCanvasContextPrototype = GPUCanvasContext.prototype;
function createCanvasContext(options) {
+ // lazy load webgpu if needed
+ loadWebGPU();
+
const canvasContext = webidl.createBranded(GPUCanvasContext);
canvasContext[_surfaceRid] = options.surfaceRid;
canvasContext[_canvas] = options.canvas;
return canvasContext;
}
-// Converters
-
-// 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,
- );
-
-window.__bootstrap.webgpu = {
- ...window.__bootstrap.webgpu,
- GPUCanvasContext,
- createCanvasContext,
-};
+function presentGPUCanvasContext(ctx) {
+ ctx[_present]();
+}
+
+export { createCanvasContext, GPUCanvasContext, presentGPUCanvasContext };
diff --git a/ext/webgpu/Cargo.toml b/ext/webgpu/Cargo.toml
index accee5ed9..461eddf5e 100644
--- a/ext/webgpu/Cargo.toml
+++ b/ext/webgpu/Cargo.toml
@@ -13,9 +13,6 @@ description = "WebGPU implementation for Deno"
[lib]
path = "lib.rs"
-[features]
-surface = ["wgpu-core/raw-window-handle", "dep:raw-window-handle"]
-
# We make all dependencies conditional on not being wasm,
# so the whole workspace can built as wasm.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
diff --git a/ext/webgpu/error.rs b/ext/webgpu/error.rs
index be8021f87..5d8abb4a3 100644
--- a/ext/webgpu/error.rs
+++ b/ext/webgpu/error.rs
@@ -23,7 +23,6 @@ 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;
@@ -282,7 +281,6 @@ impl From<ClearError> for WebGpuError {
}
}
-#[cfg(feature = "surface")]
impl From<ConfigureSurfaceError> for WebGpuError {
fn from(err: ConfigureSurfaceError) -> Self {
WebGpuError::Validation(fmt_err(&err))
diff --git a/ext/webgpu/lib.rs b/ext/webgpu/lib.rs
index 834ac6bcc..abb36fb8d 100644
--- a/ext/webgpu/lib.rs
+++ b/ext/webgpu/lib.rs
@@ -75,7 +75,6 @@ pub mod queue;
pub mod render_pass;
pub mod sampler;
pub mod shader;
-#[cfg(feature = "surface")]
pub mod surface;
pub mod texture;
@@ -212,7 +211,12 @@ deno_core::extension!(
queue::op_webgpu_write_texture,
// shader
shader::op_webgpu_create_shader_module,
+ // surface
+ surface::op_webgpu_surface_configure,
+ surface::op_webgpu_surface_get_current_texture,
+ surface::op_webgpu_surface_present
],
+ esm = ["00_init.js", "02_surface.js"],
lazy_loaded_esm = ["01_webgpu.js"],
);
diff --git a/ext/webgpu/surface.rs b/ext/webgpu/surface.rs
index 4f243fbb1..1371c1fa4 100644
--- a/ext/webgpu/surface.rs
+++ b/ext/webgpu/surface.rs
@@ -11,17 +11,6 @@ use std::borrow::Cow;
use std::rc::Rc;
use wgpu_types::SurfaceStatus;
-deno_core::extension!(
- deno_webgpu_surface,
- deps = [deno_webidl, deno_web, deno_webgpu],
- ops = [
- op_webgpu_surface_configure,
- op_webgpu_surface_get_current_texture,
- op_webgpu_surface_present,
- ],
- esm = ["02_surface.js"],
-);
-
pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId);
impl Resource for WebGpuSurface {
fn name(&self) -> Cow<str> {
diff --git a/runtime/js/98_global_scope.js b/runtime/js/98_global_scope.js
index 14b11cbde..de8319528 100644
--- a/runtime/js/98_global_scope.js
+++ b/runtime/js/98_global_scope.js
@@ -42,6 +42,12 @@ import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js";
import * as webStorage from "ext:deno_webstorage/01_webstorage.js";
import * as prompt from "ext:runtime/41_prompt.js";
import * as imageData from "ext:deno_web/16_image_data.js";
+import {
+ loadWebGPU,
+ webgpu,
+ webGPUNonEnumerable,
+} from "ext:deno_webgpu/00_init.js";
+import * as webgpuSurface from "ext:deno_webgpu/02_surface.js";
import { unstableIds } from "ext:runtime/90_deno_ns.js";
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
@@ -189,6 +195,7 @@ unstableForWindowOrWorkerGlobalScope[unstableIds.webgpu] = {
GPUError: webGPUNonEnumerable(() => webgpu.GPUError),
GPUValidationError: webGPUNonEnumerable(() => webgpu.GPUValidationError),
GPUOutOfMemoryError: webGPUNonEnumerable(() => webgpu.GPUOutOfMemoryError),
+ GPUCanvasContext: webGPUNonEnumerable(() => webgpuSurface.GPUCanvasContext),
};
class Navigator {
@@ -229,39 +236,6 @@ const numCpus = memoizeLazy(() => ops.op_bootstrap_numcpus());
const userAgent = memoizeLazy(() => ops.op_bootstrap_user_agent());
const language = memoizeLazy(() => ops.op_bootstrap_language());
-let webgpu;
-
-function webGPUNonEnumerable(getter) {
- let valueIsSet = false;
- let value;
-
- return {
- get() {
- loadWebGPU();
-
- if (valueIsSet) {
- return value;
- } else {
- return getter();
- }
- },
- set(v) {
- loadWebGPU();
-
- valueIsSet = true;
- value = v;
- },
- enumerable: false,
- configurable: true,
- };
-}
-
-function loadWebGPU() {
- if (!webgpu) {
- webgpu = ops.op_lazy_load_esm("ext:deno_webgpu/01_webgpu.js");
- }
-}
-
ObjectDefineProperties(Navigator.prototype, {
gpu: {
configurable: true,