chore: update deno (#5469)

* chore: update deno

* update spec

* more error handling

* cleanup queue

* fix

* fix byow

Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>

* fix

* fix

* fix

* fixes

* fix cts

* clean

---------

Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
This commit is contained in:
Leo Kettmeir 2024-04-02 11:36:04 -07:00 committed by GitHub
parent 5bab673926
commit d828f27de4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 1067 additions and 409 deletions

2
Cargo.lock generated
View File

@ -1077,7 +1077,7 @@ dependencies = [
[[package]] [[package]]
name = "deno_webgpu" name = "deno_webgpu"
version = "0.85.0" version = "0.110.0"
dependencies = [ dependencies = [
"deno_core", "deno_core",
"raw-window-handle 0.6.0", "raw-window-handle 0.6.0",

View File

@ -170,7 +170,7 @@ deno_core = "0.272.0"
deno_url = "0.143.0" deno_url = "0.143.0"
deno_web = "0.174.0" deno_web = "0.174.0"
deno_webidl = "0.143.0" deno_webidl = "0.143.0"
deno_webgpu = { version = "0.85.0", path = "./deno_webgpu" } deno_webgpu = { version = "0.110.0", path = "./deno_webgpu" }
tokio = "1.36.0" tokio = "1.36.0"
termcolor = "1.4.1" termcolor = "1.4.1"

View File

@ -26,8 +26,9 @@ import { Console } from "ext:deno_console/01_console.js";
import * as url from "ext:deno_url/00_url.js"; import * as url from "ext:deno_url/00_url.js";
import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js";
import * as performance from "ext:deno_web/15_performance.js"; import * as performance from "ext:deno_web/15_performance.js";
import * as webgpu from "ext:deno_webgpu/01_webgpu.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js";
import * as imageData from "ext:deno_web/16_image_data.js"; import * as imageData from "ext:deno_web/16_image_data.js";
const webgpu = loadWebGPU();
// imports needed to pass module evaluation // imports needed to pass module evaluation
import "ext:deno_url/01_urlpattern.js"; import "ext:deno_url/01_urlpattern.js";
@ -39,6 +40,7 @@ import "ext:deno_web/10_filereader.js";
import "ext:deno_web/12_location.js"; import "ext:deno_web/12_location.js";
import "ext:deno_web/13_message_port.js"; import "ext:deno_web/13_message_port.js";
import "ext:deno_web/14_compression.js"; import "ext:deno_web/14_compression.js";
import "ext:deno_webgpu/02_surface.js";
let globalThis_; let globalThis_;

View File

@ -29,6 +29,9 @@ mod native {
.ok_or_else(|| anyhow!("missing specifier in first command line argument"))?; .ok_or_else(|| anyhow!("missing specifier in first command line argument"))?;
let specifier = resolve_url_or_path(&url, &env::current_dir()?)?; let specifier = resolve_url_or_path(&url, &env::current_dir()?)?;
let mut feature_checker = deno_core::FeatureChecker::default();
feature_checker.enable_feature(deno_webgpu::UNSTABLE_FEATURE_NAME);
let options = RuntimeOptions { let options = RuntimeOptions {
module_loader: Some(Rc::new(deno_core::FsModuleLoader)), module_loader: Some(Rc::new(deno_core::FsModuleLoader)),
get_error_class_fn: Some(&get_error_class_name), get_error_class_fn: Some(&get_error_class_name),
@ -40,9 +43,10 @@ mod native {
Arc::new(BlobStore::default()), Arc::new(BlobStore::default()),
None, None,
), ),
deno_webgpu::deno_webgpu::init_ops_and_esm(true), deno_webgpu::deno_webgpu::init_ops_and_esm(),
cts_runner::init_ops_and_esm(), cts_runner::init_ops_and_esm(),
], ],
feature_checker: Some(Arc::new(feature_checker)),
..Default::default() ..Default::default()
}; };
let mut js_runtime = JsRuntime::new(options); let mut js_runtime = JsRuntime::new(options);

7
deno_webgpu/00_init.js Normal file
View File

@ -0,0 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { core } from "ext:core/mod.js";
const loadWebGPU = core.createLazyLoader("ext:deno_webgpu/01_webgpu.js");
export { loadWebGPU };

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// @ts-check // @ts-check
/// <reference path="../../core/lib.deno_core.d.ts" /> /// <reference path="../../core/lib.deno_core.d.ts" />
@ -6,27 +6,32 @@
/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="../web/lib.deno_web.d.ts" />
/// <reference path="./lib.deno_webgpu.d.ts" /> /// <reference path="./lib.deno_webgpu.d.ts" />
const core = globalThis.Deno.core; import { primordials } from "ext:core/mod.js";
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials;
const { Symbol } = primordials;
import { import {
_device, op_webgpu_surface_configure,
assertDevice, op_webgpu_surface_create,
createGPUTexture, op_webgpu_surface_get_current_texture,
GPUTextureUsage, op_webgpu_surface_present,
} from "ext:deno_webgpu/01_webgpu.js"; } from "ext:core/ops";
const {
ObjectPrototypeIsPrototypeOf,
Symbol,
SymbolFor,
TypeError,
} = primordials;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
import { loadWebGPU } from "ext:deno_webgpu/00_init.js";
const _surfaceRid = Symbol("[[surfaceRid]]"); const _surfaceRid = Symbol("[[surfaceRid]]");
const _configuration = Symbol("[[configuration]]"); const _configuration = Symbol("[[configuration]]");
const _canvas = Symbol("[[canvas]]"); const _canvas = Symbol("[[canvas]]");
const _currentTexture = Symbol("[[currentTexture]]"); const _currentTexture = Symbol("[[currentTexture]]");
const _present = Symbol("[[present]]");
class GPUCanvasContext { class GPUCanvasContext {
/** @type {number} */ /** @type {number} */
[_surfaceRid]; [_surfaceRid];
/** @type {InnerGPUDevice} */
[_device];
[_configuration]; [_configuration];
[_canvas]; [_canvas];
/** @type {GPUTexture | undefined} */ /** @type {GPUTexture | undefined} */
@ -50,11 +55,15 @@ class GPUCanvasContext {
context: "Argument 1", context: "Argument 1",
}); });
const { _device, assertDevice } = loadWebGPU();
this[_device] = configuration.device[_device]; this[_device] = configuration.device[_device];
this[_configuration] = configuration; this[_configuration] = configuration;
const device = assertDevice(this, { prefix, context: "configuration.device" }); const device = assertDevice(this, {
prefix,
context: "configuration.device",
});
const { err } = ops.op_webgpu_surface_configure({ const { err } = op_webgpu_surface_configure({
surfaceRid: this[_surfaceRid], surfaceRid: this[_surfaceRid],
deviceRid: device.rid, deviceRid: device.rid,
format: configuration.format, format: configuration.format,
@ -69,6 +78,8 @@ class GPUCanvasContext {
} }
unconfigure() { unconfigure() {
const { _device } = loadWebGPU();
webidl.assertBranded(this, GPUCanvasContextPrototype); webidl.assertBranded(this, GPUCanvasContextPrototype);
this[_configuration] = null; this[_configuration] = null;
@ -77,11 +88,13 @@ class GPUCanvasContext {
getCurrentTexture() { getCurrentTexture() {
webidl.assertBranded(this, GPUCanvasContextPrototype); webidl.assertBranded(this, GPUCanvasContextPrototype);
const prefix = "Failed to execute 'getCurrentTexture' on 'GPUCanvasContext'"; const prefix =
"Failed to execute 'getCurrentTexture' on 'GPUCanvasContext'";
if (this[_configuration] === null) { if (this[_configuration] === null) {
throw new DOMException("context is not configured.", "InvalidStateError"); throw new DOMException("context is not configured.", "InvalidStateError");
} }
const { createGPUTexture, assertDevice } = loadWebGPU();
const device = assertDevice(this, { prefix, context: "this" }); const device = assertDevice(this, { prefix, context: "this" });
@ -89,7 +102,10 @@ class GPUCanvasContext {
return this[_currentTexture]; return this[_currentTexture];
} }
const { rid } = ops.op_webgpu_surface_get_current_texture(device.rid, this[_surfaceRid]); const { rid } = op_webgpu_surface_get_current_texture(
device.rid,
this[_surfaceRid],
);
const texture = createGPUTexture( const texture = createGPUTexture(
{ {
@ -112,102 +128,66 @@ class GPUCanvasContext {
return texture; return texture;
} }
// Extended from spec. Required to present the texture; browser don't need this. // Required to present the texture; browser don't need this.
present() { [_present]() {
const { assertDevice } = loadWebGPU();
webidl.assertBranded(this, GPUCanvasContextPrototype); webidl.assertBranded(this, GPUCanvasContextPrototype);
const prefix = "Failed to execute 'present' on 'GPUCanvasContext'"; const prefix = "Failed to execute 'present' on 'GPUCanvasContext'";
const device = assertDevice(this[_currentTexture], { prefix, context: "this" }); const device = assertDevice(this[_currentTexture], {
ops.op_webgpu_surface_present(device.rid, this[_surfaceRid]); prefix,
context: "this",
});
op_webgpu_surface_present(device.rid, this[_surfaceRid]);
this[_currentTexture].destroy(); this[_currentTexture].destroy();
this[_currentTexture] = undefined; this[_currentTexture] = undefined;
} }
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
return inspect(
createFilteredInspectProxy({
object: this,
evaluate: ObjectPrototypeIsPrototypeOf(GPUCanvasContextPrototype, this),
keys: [
"canvas",
],
}),
inspectOptions,
);
}
} }
const GPUCanvasContextPrototype = GPUCanvasContext.prototype; const GPUCanvasContextPrototype = GPUCanvasContext.prototype;
function createCanvasContext(options) { function createCanvasContext(options) {
// lazy load webgpu if needed
const canvasContext = webidl.createBranded(GPUCanvasContext); const canvasContext = webidl.createBranded(GPUCanvasContext);
canvasContext[_surfaceRid] = options.surfaceRid; canvasContext[_surfaceRid] = options.surfaceRid;
canvasContext[_canvas] = options.canvas; canvasContext[_canvas] = options.canvas;
return canvasContext; return canvasContext;
} }
// Converters // External webgpu surfaces
// ENUM: GPUCanvasAlphaMode // TODO(@littledivy): This will extend `OffscreenCanvas` when we add it.
webidl.converters["GPUCanvasAlphaMode"] = webidl.createEnumConverter( class UnsafeWindowSurface {
"GPUCanvasAlphaMode", #ctx;
[ #surfaceRid;
"opaque",
"premultiplied",
],
);
// NON-SPEC: ENUM: GPUPresentMode constructor(system, win, display) {
webidl.converters["GPUPresentMode"] = webidl.createEnumConverter( this.#surfaceRid = op_webgpu_surface_create(system, win, display);
"GPUPresentMode", }
[
"autoVsync",
"autoNoVsync",
"fifo",
"fifoRelaxed",
"immediate",
"mailbox",
],
);
// DICT: GPUCanvasConfiguration getContext(context) {
const dictMembersGPUCanvasConfiguration = [ if (context !== "webgpu") {
{ key: "device", converter: webidl.converters.GPUDevice, required: true }, throw new TypeError("Only 'webgpu' context is supported.");
{ }
key: "format", this.#ctx = createCanvasContext({ surfaceRid: this.#surfaceRid });
converter: webidl.converters.GPUTextureFormat, return this.#ctx;
required: true, }
},
{
key: "usage",
converter: webidl.converters["GPUTextureUsageFlags"],
defaultValue: GPUTextureUsage.RENDER_ATTACHMENT,
},
{
key: "alphaMode",
converter: webidl.converters["GPUCanvasAlphaMode"],
defaultValue: "opaque",
},
// Extended from spec present() {
{ this.#ctx[_present]();
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,
);
export { GPUCanvasContext, UnsafeWindowSurface };
window.__bootstrap.webgpu = {
...window.__bootstrap.webgpu,
GPUCanvasContext,
createCanvasContext,
};

View File

@ -1,8 +1,8 @@
# Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. # Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
[package] [package]
name = "deno_webgpu" name = "deno_webgpu"
version = "0.85.0" version = "0.110.0"
authors = ["the Deno authors"] authors = ["the Deno authors"]
edition.workspace = true edition.workspace = true
license = "MIT" license = "MIT"
@ -13,9 +13,6 @@ description = "WebGPU implementation for Deno"
[lib] [lib]
path = "lib.rs" path = "lib.rs"
[features]
surface = ["wgpu-core/raw-window-handle", "dep:raw-window-handle"]
# We make all dependencies conditional on not being wasm, # We make all dependencies conditional on not being wasm,
# so the whole workspace can built as wasm. # so the whole workspace can built as wasm.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
@ -23,11 +20,11 @@ deno_core.workspace = true
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
wgpu-types = { workspace = true, features = ["serde"] } wgpu-types = { workspace = true, features = ["serde"] }
raw-window-handle = { workspace = true, optional = true } raw-window-handle = { workspace = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgpu-core] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgpu-core]
workspace = true workspace = true
features = ["trace", "replay", "serde", "strict_asserts", "wgsl", "gles"] features = ["raw-window-handle", "trace", "replay", "serde", "strict_asserts", "wgsl", "gles"]
# We want the wgpu-core Metal backend on macOS and iOS. # We want the wgpu-core Metal backend on macOS and iOS.
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgpu-core] [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgpu-core]

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright 2018-2023 the Deno authors Copyright 2018-2024 the Deno authors
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -2,8 +2,8 @@
This op crate implements the WebGPU API as defined in This op crate implements the WebGPU API as defined in
https://gpuweb.github.io/gpuweb/ in Deno. The implementation targets the spec https://gpuweb.github.io/gpuweb/ in Deno. The implementation targets the spec
draft as of February 22, 2021. The spec is still very much in flux. This op draft as of March 31, 2024. The spec is still very much in flux. This extension
crate tries to stay up to date with the spec, but is constrained by the features tries to stay up to date with the spec, but is constrained by the features
implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu). implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu).
The spec is still very bare bones, and is still missing many details. As the The spec is still very bare bones, and is still missing many details. As the

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
@ -112,25 +112,11 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout { struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess, access: wgpu_types::StorageTextureAccess,
format: wgpu_types::TextureFormat, format: wgpu_types::TextureFormat,
view_dimension: wgpu_types::TextureViewDimension, view_dimension: wgpu_types::TextureViewDimension,
} }
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuStorageTextureAccess {
WriteOnly,
}
impl From<GpuStorageTextureAccess> for wgpu_types::StorageTextureAccess {
fn from(access: GpuStorageTextureAccess) -> Self {
match access {
GpuStorageTextureAccess::WriteOnly => wgpu_types::StorageTextureAccess::WriteOnly,
}
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct GpuBindGroupLayoutEntry { pub struct GpuBindGroupLayoutEntry {
@ -165,7 +151,7 @@ impl From<GpuBindingType> for wgpu_types::BindingType {
}, },
GpuBindingType::StorageTexture(storage_texture) => { GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture { wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(), access: storage_texture.access,
format: storage_texture.format, format: storage_texture.format,
view_dimension: storage_texture.view_dimension, view_dimension: storage_texture.view_dimension,
} }

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
@ -163,6 +163,7 @@ pub fn op_webgpu_buffer_get_mapped_range(
)) ))
.map_err(|e| DomExceptionOperationError::new(&e.to_string()))?; .map_err(|e| DomExceptionOperationError::new(&e.to_string()))?;
// SAFETY: guarantee to be safe from wgpu
let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, range_size as usize) }; let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, range_size as usize) };
buf.copy_from_slice(slice); buf.copy_from_slice(slice);
@ -189,6 +190,7 @@ pub fn op_webgpu_buffer_unmap(
let buffer = buffer_resource.1; let buffer = buffer_resource.1;
if let Some(buf) = buf { if let Some(buf) = buf {
// SAFETY: guarantee to be safe from wgpu
let slice = unsafe { std::slice::from_raw_parts_mut(mapped_resource.0, mapped_resource.1) }; let slice = unsafe { std::slice::from_raw_parts_mut(mapped_resource.0, mapped_resource.1) };
slice.copy_from_slice(buf); slice.copy_from_slice(buf);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;

115
deno_webgpu/byow.rs Normal file
View File

@ -0,0 +1,115 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use deno_core::ResourceId;
use std::ffi::c_void;
use std::ptr::NonNull;
use crate::surface::WebGpuSurface;
#[op2(fast)]
#[smi]
pub fn op_webgpu_surface_create(
state: &mut OpState,
#[string] system: &str,
p1: *const c_void,
p2: *const c_void,
) -> Result<ResourceId, AnyError> {
let instance = state.borrow::<super::Instance>();
// Security note:
//
// The `p1` and `p2` parameters are pointers to platform-specific window
// handles.
//
// The code below works under the assumption that:
//
// - handles can only be created by the FFI interface which
// enforces --allow-ffi.
//
// - `*const c_void` deserizalizes null and v8::External.
//
// - Only FFI can export v8::External to user code.
if p1.is_null() {
return Err(type_error("Invalid parameters"));
}
let (win_handle, display_handle) = raw_window(system, p1, p2)?;
let surface = unsafe { instance.instance_create_surface(display_handle, win_handle, None)? };
let rid = state
.resource_table
.add(WebGpuSurface(instance.clone(), surface));
Ok(rid)
}
type RawHandles = (
raw_window_handle::RawWindowHandle,
raw_window_handle::RawDisplayHandle,
);
#[cfg(target_os = "macos")]
fn raw_window(
system: &str,
_ns_window: *const c_void,
ns_view: *const c_void,
) -> Result<RawHandles, AnyError> {
if system != "cocoa" {
return Err(type_error("Invalid system on macOS"));
}
let win_handle =
raw_window_handle::RawWindowHandle::AppKit(raw_window_handle::AppKitWindowHandle::new(
NonNull::new(ns_view as *mut c_void).ok_or(type_error("ns_view is null"))?,
));
let display_handle =
raw_window_handle::RawDisplayHandle::AppKit(raw_window_handle::AppKitDisplayHandle::new());
Ok((win_handle, display_handle))
}
#[cfg(target_os = "windows")]
fn raw_window(
system: &str,
window: *const c_void,
hinstance: *const c_void,
) -> Result<RawHandles, AnyError> {
use raw_window_handle::WindowsDisplayHandle;
if system != "win32" {
return Err(type_error("Invalid system on Windows"));
}
let win_handle = {
let mut handle = raw_window_handle::Win32WindowHandle::new();
handle.hwnd = window as *mut c_void;
handle.hinstance = hinstance as *mut c_void;
raw_window_handle::RawWindowHandle::Win32(handle)
};
let display_handle = raw_window_handle::RawDisplayHandle::Windows(WindowsDisplayHandle::new());
Ok((win_handle, display_handle))
}
#[cfg(target_os = "linux")]
fn raw_window(
system: &str,
window: *const c_void,
display: *const c_void,
) -> Result<RawHandles, AnyError> {
if system != "x11" {
return Err(type_error("Invalid system on Linux"));
}
let win_handle = raw_window_handle::RawWindowHandle::Xlib(
raw_window_handle::XlibWindowHandle::new(window as *mut c_void as _),
);
let display_handle = raw_window_handle::RawDisplayHandle::Xlib(
raw_window_handle::XlibDisplayHandle::new(NonNull::new(display as *mut c_void), 0),
);
Ok((win_handle, display_handle))
}

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::WebGpuQuerySet; use crate::WebGpuQuerySet;
use deno_core::error::AnyError; use deno_core::error::AnyError;

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;

View File

@ -1,4 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::ResourceId; use deno_core::ResourceId;
use serde::Serialize; use serde::Serialize;
@ -23,7 +24,6 @@ use wgpu_core::device::DeviceError;
use wgpu_core::pipeline::CreateComputePipelineError; use wgpu_core::pipeline::CreateComputePipelineError;
use wgpu_core::pipeline::CreateRenderPipelineError; use wgpu_core::pipeline::CreateRenderPipelineError;
use wgpu_core::pipeline::CreateShaderModuleError; use wgpu_core::pipeline::CreateShaderModuleError;
#[cfg(feature = "surface")]
use wgpu_core::present::ConfigureSurfaceError; use wgpu_core::present::ConfigureSurfaceError;
use wgpu_core::resource::BufferAccessError; use wgpu_core::resource::BufferAccessError;
use wgpu_core::resource::CreateBufferError; use wgpu_core::resource::CreateBufferError;
@ -87,6 +87,7 @@ pub enum WebGpuError {
Lost, Lost,
OutOfMemory, OutOfMemory,
Validation(String), Validation(String),
Internal,
} }
impl From<CreateBufferError> for WebGpuError { impl From<CreateBufferError> for WebGpuError {
@ -277,7 +278,6 @@ impl From<ClearError> for WebGpuError {
} }
} }
#[cfg(feature = "surface")]
impl From<ConfigureSurfaceError> for WebGpuError { impl From<ConfigureSurfaceError> for WebGpuError {
fn from(err: ConfigureSurfaceError) -> Self { fn from(err: ConfigureSurfaceError) -> Self {
WebGpuError::Validation(fmt_err(&err)) WebGpuError::Validation(fmt_err(&err))

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
#![cfg(not(target_arch = "wasm32"))] #![cfg(not(target_arch = "wasm32"))]
#![warn(unsafe_op_in_unsafe_fn)] #![warn(unsafe_op_in_unsafe_fn)]
@ -19,6 +19,8 @@ pub use wgpu_types;
use error::DomExceptionOperationError; use error::DomExceptionOperationError;
use error::WebGpuResult; use error::WebGpuResult;
pub const UNSTABLE_FEATURE_NAME: &str = "webgpu";
#[macro_use] #[macro_use]
mod macros { mod macros {
macro_rules! gfx_select { macro_rules! gfx_select {
@ -71,6 +73,7 @@ mod macros {
pub mod binding; pub mod binding;
pub mod buffer; pub mod buffer;
pub mod bundle; pub mod bundle;
pub mod byow;
pub mod command_encoder; pub mod command_encoder;
pub mod compute_pass; pub mod compute_pass;
pub mod error; pub mod error;
@ -79,23 +82,9 @@ pub mod queue;
pub mod render_pass; pub mod render_pass;
pub mod sampler; pub mod sampler;
pub mod shader; pub mod shader;
#[cfg(feature = "surface")]
pub mod surface; pub mod surface;
pub mod texture; pub mod texture;
pub struct Unstable(pub bool);
fn check_unstable(state: &OpState, api_name: &str) {
let unstable = state.borrow::<Unstable>();
if !unstable.0 {
eprintln!(
"Unstable API '{}'. The --unstable flag must be provided.",
api_name
);
std::process::exit(70);
}
}
pub type Instance = std::sync::Arc<wgpu_core::global::Global>; pub type Instance = std::sync::Arc<wgpu_core::global::Global>;
struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId); struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId);
@ -224,12 +213,15 @@ deno_core::extension!(
queue::op_webgpu_write_texture, queue::op_webgpu_write_texture,
// shader // shader
shader::op_webgpu_create_shader_module, shader::op_webgpu_create_shader_module,
// surface
surface::op_webgpu_surface_configure,
surface::op_webgpu_surface_get_current_texture,
surface::op_webgpu_surface_present,
// byow
byow::op_webgpu_surface_create,
], ],
esm = ["01_webgpu.js"], esm = ["00_init.js", "02_surface.js"],
options = { unstable: bool }, lazy_loaded_esm = ["01_webgpu.js"],
state = |state, options| {
state.put(Unstable(options.unstable));
},
); );
fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
@ -377,29 +369,45 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
#[derive(Serialize)] #[derive(Serialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum GpuAdapterDeviceOrErr { pub enum GpuAdapterResOrErr {
Error { err: String }, Error { err: String },
Features(GpuAdapterDevice), Features(GpuAdapterRes),
} }
#[derive(Serialize)] #[derive(Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct GpuAdapterDevice { pub struct GpuAdapterRes {
rid: ResourceId, rid: ResourceId,
limits: wgpu_types::Limits, limits: wgpu_types::Limits,
features: Vec<&'static str>, features: Vec<&'static str>,
is_software: bool, is_software: bool,
} }
#[op2(async)] #[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuDeviceRes {
rid: ResourceId,
queue_rid: ResourceId,
limits: wgpu_types::Limits,
features: Vec<&'static str>,
is_software: bool,
}
#[op2]
#[serde] #[serde]
pub async fn op_webgpu_request_adapter( pub fn op_webgpu_request_adapter(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
#[serde] power_preference: Option<wgpu_types::PowerPreference>, #[serde] power_preference: Option<wgpu_types::PowerPreference>,
force_fallback_adapter: bool, force_fallback_adapter: bool,
) -> Result<GpuAdapterDeviceOrErr, AnyError> { ) -> Result<GpuAdapterResOrErr, AnyError> {
let mut state = state.borrow_mut(); let mut state = state.borrow_mut();
check_unstable(&state, "navigator.gpu.requestAdapter");
// TODO(bartlomieju): replace with `state.feature_checker.check_or_exit`
// once we phase out `check_or_exit_with_legacy_fallback`
state
.feature_checker
.check_or_exit_with_legacy_fallback(UNSTABLE_FEATURE_NAME, "navigator.gpu.requestAdapter");
let backends = std::env::var("DENO_WEBGPU_BACKEND").map_or_else( let backends = std::env::var("DENO_WEBGPU_BACKEND").map_or_else(
|_| wgpu_types::Backends::all(), |_| wgpu_types::Backends::all(),
|s| wgpu_core::instance::parse_backends_from_comma_list(&s), |s| wgpu_core::instance::parse_backends_from_comma_list(&s),
@ -432,7 +440,7 @@ pub async fn op_webgpu_request_adapter(
let adapter = match res { let adapter = match res {
Ok(adapter) => adapter, Ok(adapter) => adapter,
Err(err) => { Err(err) => {
return Ok(GpuAdapterDeviceOrErr::Error { return Ok(GpuAdapterResOrErr::Error {
err: err.to_string(), err: err.to_string(),
}) })
} }
@ -445,7 +453,7 @@ pub async fn op_webgpu_request_adapter(
let rid = state.resource_table.add(WebGpuAdapter(instance, adapter)); let rid = state.resource_table.add(WebGpuAdapter(instance, adapter));
Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice { Ok(GpuAdapterResOrErr::Features(GpuAdapterRes {
rid, rid,
features, features,
limits: adapter_limits, limits: adapter_limits,
@ -649,15 +657,15 @@ impl From<GpuRequiredFeatures> for wgpu_types::Features {
} }
} }
#[op2(async)] #[op2]
#[serde] #[serde]
pub async fn op_webgpu_request_device( pub fn op_webgpu_request_device(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
#[smi] adapter_rid: ResourceId, #[smi] adapter_rid: ResourceId,
#[string] label: String, #[string] label: String,
#[serde] required_features: GpuRequiredFeatures, #[serde] required_features: GpuRequiredFeatures,
#[serde] required_limits: Option<wgpu_types::Limits>, #[serde] required_limits: Option<wgpu_types::Limits>,
) -> Result<GpuAdapterDevice, AnyError> { ) -> Result<GpuDeviceRes, AnyError> {
let mut state = state.borrow_mut(); let mut state = state.borrow_mut();
let adapter_resource = state.resource_table.get::<WebGpuAdapter>(adapter_rid)?; let adapter_resource = state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
let adapter = adapter_resource.1; let adapter = adapter_resource.1;
@ -669,7 +677,7 @@ pub async fn op_webgpu_request_device(
required_limits: required_limits.unwrap_or_default(), required_limits: required_limits.unwrap_or_default(),
}; };
let (device, _queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device( let (device, queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
adapter, adapter,
&descriptor, &descriptor,
std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new),
@ -685,10 +693,15 @@ pub async fn op_webgpu_request_device(
let limits = gfx_select!(device => instance.device_limits(device))?; let limits = gfx_select!(device => instance.device_limits(device))?;
let instance = instance.clone(); let instance = instance.clone();
let instance2 = instance.clone();
let rid = state.resource_table.add(WebGpuDevice(instance, device)); let rid = state.resource_table.add(WebGpuDevice(instance, device));
let queue_rid = state
.resource_table
.add(queue::WebGpuQueue(instance2, queue));
Ok(GpuAdapterDevice { Ok(GpuDeviceRes {
rid, rid,
queue_rid,
features, features,
limits, limits,
// TODO(lucacasonato): report correctly from wgpu // TODO(lucacasonato): report correctly from wgpu
@ -705,9 +718,9 @@ pub struct GPUAdapterInfo {
description: String, description: String,
} }
#[op2(async)] #[op2]
#[serde] #[serde]
pub async fn op_webgpu_request_adapter_info( pub fn op_webgpu_request_adapter_info(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
#[smi] adapter_rid: ResourceId, #[smi] adapter_rid: ResourceId,
) -> Result<GPUAdapterInfo, AnyError> { ) -> Result<GPUAdapterInfo, AnyError> {

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
@ -74,7 +74,7 @@ pub enum GPUPipelineLayoutOrGPUAutoLayoutMode {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct GpuProgrammableStage { pub struct GpuProgrammableStage {
module: ResourceId, module: ResourceId,
entry_point: String, entry_point: Option<String>,
// constants: HashMap<String, GPUPipelineConstantValue> // constants: HashMap<String, GPUPipelineConstantValue>
} }
@ -110,7 +110,7 @@ pub fn op_webgpu_create_compute_pipeline(
layout: pipeline_layout, layout: pipeline_layout,
stage: wgpu_core::pipeline::ProgrammableStageDescriptor { stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: compute_shader_module_resource.1, module: compute_shader_module_resource.1,
entry_point: Some(Cow::from(compute.entry_point)), entry_point: compute.entry_point.map(Cow::from),
// TODO(lucacasonato): support args.compute.constants // TODO(lucacasonato): support args.compute.constants
}, },
}; };

View File

@ -1,16 +1,28 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::command_encoder::WebGpuCommandBuffer; use crate::command_encoder::WebGpuCommandBuffer;
use crate::Instance;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
use deno_core::OpState; use deno_core::OpState;
use deno_core::Resource; use deno_core::Resource;
use deno_core::ResourceId; use deno_core::ResourceId;
use serde::Deserialize; use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult; use super::error::WebGpuResult;
type WebGpuQueue = super::WebGpuDevice; pub struct WebGpuQueue(pub Instance, pub wgpu_core::id::QueueId);
impl Resource for WebGpuQueue {
fn name(&self) -> Cow<str> {
"webGPUQueue".into()
}
fn close(self: Rc<Self>) {
gfx_select!(self.1 => self.0.queue_drop(self.1));
}
}
#[op2] #[op2]
#[serde] #[serde]
@ -19,7 +31,7 @@ pub fn op_webgpu_queue_submit(
#[smi] queue_rid: ResourceId, #[smi] queue_rid: ResourceId,
#[serde] command_buffers: Vec<ResourceId>, #[serde] command_buffers: Vec<ResourceId>,
) -> Result<WebGpuResult, AnyError> { ) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>(); let instance = state.borrow::<Instance>();
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?; let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
let queue = queue_resource.1; let queue = queue_resource.1;
@ -32,7 +44,7 @@ pub fn op_webgpu_queue_submit(
}) })
.collect::<Result<Vec<_>, AnyError>>()?; .collect::<Result<Vec<_>, AnyError>>()?;
let maybe_err = gfx_select!(queue => instance.queue_submit(queue.transmute(), &ids)).err(); let maybe_err = gfx_select!(queue => instance.queue_submit(queue, &ids)).err();
for rid in command_buffers { for rid in command_buffers {
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?; let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
@ -71,7 +83,7 @@ pub fn op_webgpu_write_buffer(
#[number] size: Option<usize>, #[number] size: Option<usize>,
#[buffer] buf: &[u8], #[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> { ) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>(); let instance = state.borrow::<Instance>();
let buffer_resource = state let buffer_resource = state
.resource_table .resource_table
.get::<super::buffer::WebGpuBuffer>(buffer)?; .get::<super::buffer::WebGpuBuffer>(buffer)?;
@ -84,7 +96,7 @@ pub fn op_webgpu_write_buffer(
None => &buf[data_offset..], None => &buf[data_offset..],
}; };
let maybe_err = gfx_select!(queue => instance.queue_write_buffer( let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
queue.transmute(), queue,
buffer, buffer,
buffer_offset, buffer_offset,
data data
@ -104,7 +116,7 @@ pub fn op_webgpu_write_texture(
#[serde] size: wgpu_types::Extent3d, #[serde] size: wgpu_types::Extent3d,
#[buffer] buf: &[u8], #[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> { ) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>(); let instance = state.borrow::<Instance>();
let texture_resource = state let texture_resource = state
.resource_table .resource_table
.get::<super::texture::WebGpuTexture>(destination.texture)?; .get::<super::texture::WebGpuTexture>(destination.texture)?;
@ -120,7 +132,7 @@ pub fn op_webgpu_write_texture(
let data_layout = data_layout.into(); let data_layout = data_layout.into();
gfx_ok!(queue => instance.queue_write_texture( gfx_ok!(queue => instance.queue_write_texture(
queue.transmute(), queue,
&destination, &destination,
buf, buf,
&data_layout, &data_layout,

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use super::WebGpuResult; use super::WebGpuResult;
use deno_core::error::AnyError; use deno_core::error::AnyError;
@ -11,21 +11,6 @@ use std::borrow::Cow;
use std::rc::Rc; use std::rc::Rc;
use wgpu_types::SurfaceStatus; 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"],
options = { unstable: bool },
state = |state, options| {
state.put(super::Unstable(options.unstable));
},
);
pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId); pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId);
impl Resource for WebGpuSurface { impl Resource for WebGpuSurface {
fn name(&self) -> Cow<str> { fn name(&self) -> Cow<str> {

View File

@ -1,4 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;

View File

@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase {
USVString label = ""; USVString label = "";
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUSupportedLimits { interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension1D; readonly attribute unsigned long maxTextureDimension1D;
readonly attribute unsigned long maxTextureDimension2D; readonly attribute unsigned long maxTextureDimension2D;
@ -30,6 +30,8 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxVertexAttributes; readonly attribute unsigned long maxVertexAttributes;
readonly attribute unsigned long maxVertexBufferArrayStride; readonly attribute unsigned long maxVertexBufferArrayStride;
readonly attribute unsigned long maxInterStageShaderComponents; readonly attribute unsigned long maxInterStageShaderComponents;
readonly attribute unsigned long maxColorAttachments;
readonly attribute unsigned long maxColorAttachmentBytesPerSample;
readonly attribute unsigned long maxComputeWorkgroupStorageSize; readonly attribute unsigned long maxComputeWorkgroupStorageSize;
readonly attribute unsigned long maxComputeInvocationsPerWorkgroup; readonly attribute unsigned long maxComputeInvocationsPerWorkgroup;
readonly attribute unsigned long maxComputeWorkgroupSizeX; readonly attribute unsigned long maxComputeWorkgroupSizeX;
@ -38,12 +40,12 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxComputeWorkgroupsPerDimension; readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUSupportedFeatures { interface GPUSupportedFeatures {
readonly setlike<DOMString>; readonly setlike<DOMString>;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUAdapterInfo { interface GPUAdapterInfo {
readonly attribute DOMString vendor; readonly attribute DOMString vendor;
readonly attribute DOMString architecture; readonly attribute DOMString architecture;
@ -57,9 +59,10 @@ interface mixin NavigatorGPU {
Navigator includes NavigatorGPU; Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU; WorkerNavigator includes NavigatorGPU;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPU { interface GPU {
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {}); Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
GPUTextureFormat getPreferredCanvasFormat();
}; };
dictionary GPURequestAdapterOptions { dictionary GPURequestAdapterOptions {
@ -72,14 +75,14 @@ enum GPUPowerPreference {
"high-performance", "high-performance",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUAdapter { interface GPUAdapter {
[SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits; [SameObject] readonly attribute GPUSupportedLimits limits;
readonly attribute boolean isFallbackAdapter; readonly attribute boolean isFallbackAdapter;
Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {}); Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {});
Promise<GPUAdapterInfo> requestAdapterInfo(optional sequence<DOMString> unmaskHints = []); Promise<GPUAdapterInfo> requestAdapterInfo();
}; };
dictionary GPUDeviceDescriptor dictionary GPUDeviceDescriptor
@ -141,7 +144,7 @@ enum GPUFeatureName {
"shader-early-depth-test", "shader-early-depth-test",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUDevice : EventTarget { interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits; [SameObject] readonly attribute GPUSupportedLimits limits;
@ -171,7 +174,7 @@ interface GPUDevice : EventTarget {
}; };
GPUDevice includes GPUObjectBase; GPUDevice includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUBuffer { interface GPUBuffer {
readonly attribute GPUSize64Out size; readonly attribute GPUSize64Out size;
readonly attribute GPUFlagsConstant usage; readonly attribute GPUFlagsConstant usage;
@ -200,7 +203,7 @@ dictionary GPUBufferDescriptor
}; };
typedef [EnforceRange] unsigned long GPUBufferUsageFlags; typedef [EnforceRange] unsigned long GPUBufferUsageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
namespace GPUBufferUsage { namespace GPUBufferUsage {
const GPUFlagsConstant MAP_READ = 0x0001; const GPUFlagsConstant MAP_READ = 0x0001;
const GPUFlagsConstant MAP_WRITE = 0x0002; const GPUFlagsConstant MAP_WRITE = 0x0002;
@ -215,13 +218,13 @@ namespace GPUBufferUsage {
}; };
typedef [EnforceRange] unsigned long GPUMapModeFlags; typedef [EnforceRange] unsigned long GPUMapModeFlags;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
namespace GPUMapMode { namespace GPUMapMode {
const GPUFlagsConstant READ = 0x0001; const GPUFlagsConstant READ = 0x0001;
const GPUFlagsConstant WRITE = 0x0002; const GPUFlagsConstant WRITE = 0x0002;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUTexture { interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@ -256,7 +259,7 @@ enum GPUTextureDimension {
}; };
typedef [EnforceRange] unsigned long GPUTextureUsageFlags; typedef [EnforceRange] unsigned long GPUTextureUsageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
namespace GPUTextureUsage { namespace GPUTextureUsage {
const GPUFlagsConstant COPY_SRC = 0x01; const GPUFlagsConstant COPY_SRC = 0x01;
const GPUFlagsConstant COPY_DST = 0x02; const GPUFlagsConstant COPY_DST = 0x02;
@ -265,7 +268,7 @@ namespace GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUTextureView { interface GPUTextureView {
}; };
GPUTextureView includes GPUObjectBase; GPUTextureView includes GPUObjectBase;
@ -328,6 +331,7 @@ enum GPUTextureFormat {
"bgra8unorm-srgb", "bgra8unorm-srgb",
// Packed 32-bit formats // Packed 32-bit formats
"rgb9e5ufloat", "rgb9e5ufloat",
"rgb10a2uint",
"rgb10a2unorm", "rgb10a2unorm",
"rg11b10ufloat", "rg11b10ufloat",
@ -416,7 +420,7 @@ enum GPUTextureFormat {
"astc-12x12-unorm-srgb", "astc-12x12-unorm-srgb",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUSampler { interface GPUSampler {
}; };
GPUSampler includes GPUObjectBase; GPUSampler includes GPUObjectBase;
@ -462,7 +466,7 @@ enum GPUCompareFunction {
"always", "always",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUBindGroupLayout { interface GPUBindGroupLayout {
}; };
GPUBindGroupLayout includes GPUObjectBase; GPUBindGroupLayout includes GPUObjectBase;
@ -483,7 +487,7 @@ dictionary GPUBindGroupLayoutEntry {
}; };
typedef [EnforceRange] unsigned long GPUShaderStageFlags; typedef [EnforceRange] unsigned long GPUShaderStageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
namespace GPUShaderStage { namespace GPUShaderStage {
const GPUFlagsConstant VERTEX = 0x1; const GPUFlagsConstant VERTEX = 0x1;
const GPUFlagsConstant FRAGMENT = 0x2; const GPUFlagsConstant FRAGMENT = 0x2;
@ -528,6 +532,8 @@ dictionary GPUTextureBindingLayout {
enum GPUStorageTextureAccess { enum GPUStorageTextureAccess {
"write-only", "write-only",
"read-only",
"read-write",
}; };
dictionary GPUStorageTextureBindingLayout { dictionary GPUStorageTextureBindingLayout {
@ -536,7 +542,7 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d"; GPUTextureViewDimension viewDimension = "2d";
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUBindGroup { interface GPUBindGroup {
}; };
GPUBindGroup includes GPUObjectBase; GPUBindGroup includes GPUObjectBase;
@ -560,7 +566,7 @@ dictionary GPUBufferBinding {
GPUSize64 size; GPUSize64 size;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUPipelineLayout { interface GPUPipelineLayout {
}; };
GPUPipelineLayout includes GPUObjectBase; GPUPipelineLayout includes GPUObjectBase;
@ -570,7 +576,7 @@ dictionary GPUPipelineLayoutDescriptor
required sequence<GPUBindGroupLayout> bindGroupLayouts; required sequence<GPUBindGroupLayout> bindGroupLayouts;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUShaderModule { interface GPUShaderModule {
}; };
GPUShaderModule includes GPUObjectBase; GPUShaderModule includes GPUObjectBase;
@ -586,7 +592,7 @@ enum GPUCompilationMessageType {
"info", "info",
}; };
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] [Exposed=(Window, Worker), Serializable, SecureContext]
interface GPUCompilationMessage { interface GPUCompilationMessage {
readonly attribute DOMString message; readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type; readonly attribute GPUCompilationMessageType type;
@ -596,11 +602,26 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length; readonly attribute unsigned long long length;
}; };
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext] [Exposed=(Window, Worker), Serializable, SecureContext]
interface GPUCompilationInfo { interface GPUCompilationInfo {
readonly attribute FrozenArray<GPUCompilationMessage> messages; readonly attribute FrozenArray<GPUCompilationMessage> messages;
}; };
[Exposed=(Window, Worker), SecureContext, Serializable]
interface GPUPipelineError : DOMException {
constructor(optional DOMString message = "", GPUPipelineErrorInit options);
readonly attribute GPUPipelineErrorReason reason;
};
dictionary GPUPipelineErrorInit {
required GPUPipelineErrorReason reason;
};
enum GPUPipelineErrorReason {
"validation",
"internal",
};
enum GPUAutoLayoutMode { enum GPUAutoLayoutMode {
"auto", "auto",
}; };
@ -616,13 +637,13 @@ interface mixin GPUPipelineBase {
dictionary GPUProgrammableStage { dictionary GPUProgrammableStage {
required GPUShaderModule module; required GPUShaderModule module;
required USVString entryPoint; USVString entryPoint;
record<USVString, GPUPipelineConstantValue> constants; record<USVString, GPUPipelineConstantValue> constants;
}; };
typedef double GPUPipelineConstantValue; // May represent WGSLs bool, f32, i32, u32, and f16 if enabled. typedef double GPUPipelineConstantValue; // May represent WGSL's bool, f32, i32, u32, and f16 if enabled.
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUComputePipeline { interface GPUComputePipeline {
}; };
GPUComputePipeline includes GPUObjectBase; GPUComputePipeline includes GPUObjectBase;
@ -633,7 +654,7 @@ dictionary GPUComputePipelineDescriptor
required GPUProgrammableStage compute; required GPUProgrammableStage compute;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPURenderPipeline { interface GPURenderPipeline {
}; };
GPURenderPipeline includes GPUObjectBase; GPURenderPipeline includes GPUObjectBase;
@ -701,7 +722,7 @@ dictionary GPUBlendState {
}; };
typedef [EnforceRange] unsigned long GPUColorWriteFlags; typedef [EnforceRange] unsigned long GPUColorWriteFlags;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
namespace GPUColorWrite { namespace GPUColorWrite {
const GPUFlagsConstant RED = 0x1; const GPUFlagsConstant RED = 0x1;
const GPUFlagsConstant GREEN = 0x2; const GPUFlagsConstant GREEN = 0x2;
@ -854,7 +875,7 @@ dictionary GPUImageCopyTexture {
GPUTextureAspect aspect = "all"; GPUTextureAspect aspect = "all";
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUCommandBuffer { interface GPUCommandBuffer {
}; };
GPUCommandBuffer includes GPUObjectBase; GPUCommandBuffer includes GPUObjectBase;
@ -866,7 +887,7 @@ dictionary GPUCommandBufferDescriptor
interface mixin GPUCommandsMixin { interface mixin GPUCommandsMixin {
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUCommandEncoder { interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@ -933,7 +954,7 @@ interface mixin GPUDebugCommandsMixin {
undefined insertDebugMarker(USVString markerLabel); undefined insertDebugMarker(USVString markerLabel);
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUComputePassEncoder { interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline); undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1); undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1);
@ -957,7 +978,7 @@ dictionary GPUComputePassDescriptor
GPUComputePassTimestampWrites timestampWrites; GPUComputePassTimestampWrites timestampWrites;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPURenderPassEncoder { interface GPURenderPassEncoder {
undefined setViewport(float x, float y, undefined setViewport(float x, float y,
float width, float height, float width, float height,
@ -1052,7 +1073,7 @@ interface mixin GPURenderCommandsMixin {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPURenderBundle { interface GPURenderBundle {
}; };
GPURenderBundle includes GPUObjectBase; GPURenderBundle includes GPUObjectBase;
@ -1061,7 +1082,7 @@ dictionary GPURenderBundleDescriptor
: GPUObjectDescriptorBase { : GPUObjectDescriptorBase {
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPURenderBundleEncoder { interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
}; };
@ -1077,7 +1098,7 @@ dictionary GPURenderBundleEncoderDescriptor
boolean stencilReadOnly = false; boolean stencilReadOnly = false;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUQueue { interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> commandBuffers); undefined submit(sequence<GPUCommandBuffer> commandBuffers);
@ -1098,7 +1119,7 @@ interface GPUQueue {
}; };
GPUQueue includes GPUObjectBase; GPUQueue includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUQuerySet { interface GPUQuerySet {
undefined destroy(); undefined destroy();
@ -1118,7 +1139,7 @@ enum GPUQueryType {
"timestamp", "timestamp",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUCanvasContext { interface GPUCanvasContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas; readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
@ -1146,7 +1167,7 @@ enum GPUDeviceLostReason {
"destroyed", "destroyed",
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUDeviceLostInfo { interface GPUDeviceLostInfo {
readonly attribute GPUDeviceLostReason reason; readonly attribute GPUDeviceLostReason reason;
readonly attribute DOMString message; readonly attribute DOMString message;
@ -1156,27 +1177,33 @@ partial interface GPUDevice {
readonly attribute Promise<GPUDeviceLostInfo> lost; readonly attribute Promise<GPUDeviceLostInfo> lost;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUError { interface GPUError {
readonly attribute DOMString message; readonly attribute DOMString message;
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUValidationError interface GPUValidationError
: GPUError { : GPUError {
constructor(DOMString message); constructor(DOMString message);
}; };
[Exposed=(Window, DedicatedWorker), SecureContext] [Exposed=(Window, Worker), SecureContext]
interface GPUOutOfMemoryError interface GPUOutOfMemoryError
: GPUError { : GPUError {
constructor(DOMString message); constructor(DOMString message);
}; };
[Exposed=(Window, Worker), SecureContext]
interface GPUInternalError
: GPUError {
constructor(DOMString message);
};
enum GPUErrorFilter { enum GPUErrorFilter {
"validation", "validation",
"out-of-memory", "out-of-memory",
"internal" "internal",
}; };
partial interface GPUDevice { partial interface GPUDevice {
@ -1184,8 +1211,21 @@ partial interface GPUDevice {
Promise<GPUError?> popErrorScope(); Promise<GPUError?> popErrorScope();
}; };
[Exposed=(Window, Worker), SecureContext]
interface GPUUncapturedErrorEvent : Event {
constructor(
DOMString type,
GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict
);
[SameObject] readonly attribute GPUError error;
};
dictionary GPUUncapturedErrorEventInit : EventInit {
required GPUError error;
};
partial interface GPUDevice { partial interface GPUDevice {
[Exposed=(Window, DedicatedWorker)] [Exposed=(Window, Worker)]
attribute EventHandler onuncapturederror; attribute EventHandler onuncapturederror;
}; };