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]]
name = "deno_webgpu"
version = "0.85.0"
version = "0.110.0"
dependencies = [
"deno_core",
"raw-window-handle 0.6.0",

View File

@ -170,7 +170,7 @@ deno_core = "0.272.0"
deno_url = "0.143.0"
deno_web = "0.174.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"
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 { DOMException } from "ext:deno_web/01_dom_exception.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";
const webgpu = loadWebGPU();
// imports needed to pass module evaluation
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/13_message_port.js";
import "ext:deno_web/14_compression.js";
import "ext:deno_webgpu/02_surface.js";
let globalThis_;

View File

@ -29,6 +29,9 @@ mod native {
.ok_or_else(|| anyhow!("missing specifier in first command line argument"))?;
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 {
module_loader: Some(Rc::new(deno_core::FsModuleLoader)),
get_error_class_fn: Some(&get_error_class_name),
@ -40,9 +43,10 @@ mod native {
Arc::new(BlobStore::default()),
None,
),
deno_webgpu::deno_webgpu::init_ops_and_esm(true),
deno_webgpu::deno_webgpu::init_ops_and_esm(),
cts_runner::init_ops_and_esm(),
],
feature_checker: Some(Arc::new(feature_checker)),
..Default::default()
};
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
/// <reference path="../../core/lib.deno_core.d.ts" />
@ -6,27 +6,32 @@
/// <reference path="../web/lib.deno_web.d.ts" />
/// <reference path="./lib.deno_webgpu.d.ts" />
const core = globalThis.Deno.core;
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials;
const { Symbol } = primordials;
import { primordials } from "ext:core/mod.js";
import {
_device,
assertDevice,
createGPUTexture,
GPUTextureUsage,
} from "ext:deno_webgpu/01_webgpu.js";
op_webgpu_surface_configure,
op_webgpu_surface_create,
op_webgpu_surface_get_current_texture,
op_webgpu_surface_present,
} 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 _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,11 +55,15 @@ class GPUCanvasContext {
context: "Argument 1",
});
const { _device, assertDevice } = loadWebGPU();
this[_device] = configuration.device[_device];
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],
deviceRid: device.rid,
format: configuration.format,
@ -69,6 +78,8 @@ class GPUCanvasContext {
}
unconfigure() {
const { _device } = loadWebGPU();
webidl.assertBranded(this, GPUCanvasContextPrototype);
this[_configuration] = null;
@ -77,11 +88,13 @@ class GPUCanvasContext {
getCurrentTexture() {
webidl.assertBranded(this, GPUCanvasContextPrototype);
const prefix = "Failed to execute 'getCurrentTexture' on 'GPUCanvasContext'";
const prefix =
"Failed to execute 'getCurrentTexture' on 'GPUCanvasContext'";
if (this[_configuration] === null) {
throw new DOMException("context is not configured.", "InvalidStateError");
}
const { createGPUTexture, assertDevice } = loadWebGPU();
const device = assertDevice(this, { prefix, context: "this" });
@ -89,7 +102,10 @@ class GPUCanvasContext {
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(
{
@ -112,102 +128,66 @@ 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 } = loadWebGPU();
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]);
const device = assertDevice(this[_currentTexture], {
prefix,
context: "this",
});
op_webgpu_surface_present(device.rid, this[_surfaceRid]);
this[_currentTexture].destroy();
this[_currentTexture] = undefined;
}
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
return inspect(
createFilteredInspectProxy({
object: this,
evaluate: ObjectPrototypeIsPrototypeOf(GPUCanvasContextPrototype, this),
keys: [
"canvas",
],
}),
inspectOptions,
);
}
}
const GPUCanvasContextPrototype = GPUCanvasContext.prototype;
function createCanvasContext(options) {
// lazy load webgpu if needed
const canvasContext = webidl.createBranded(GPUCanvasContext);
canvasContext[_surfaceRid] = options.surfaceRid;
canvasContext[_canvas] = options.canvas;
return canvasContext;
}
// Converters
// External webgpu surfaces
// ENUM: GPUCanvasAlphaMode
webidl.converters["GPUCanvasAlphaMode"] = webidl.createEnumConverter(
"GPUCanvasAlphaMode",
[
"opaque",
"premultiplied",
],
);
// TODO(@littledivy): This will extend `OffscreenCanvas` when we add it.
class UnsafeWindowSurface {
#ctx;
#surfaceRid;
// NON-SPEC: ENUM: GPUPresentMode
webidl.converters["GPUPresentMode"] = webidl.createEnumConverter(
"GPUPresentMode",
[
"autoVsync",
"autoNoVsync",
"fifo",
"fifoRelaxed",
"immediate",
"mailbox",
],
);
constructor(system, win, display) {
this.#surfaceRid = op_webgpu_surface_create(system, win, display);
}
// 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",
},
getContext(context) {
if (context !== "webgpu") {
throw new TypeError("Only 'webgpu' context is supported.");
}
this.#ctx = createCanvasContext({ surfaceRid: this.#surfaceRid });
return this.#ctx;
}
// 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,
);
present() {
this.#ctx[_present]();
}
}
window.__bootstrap.webgpu = {
...window.__bootstrap.webgpu,
GPUCanvasContext,
createCanvasContext,
};
export { GPUCanvasContext, UnsafeWindowSurface };

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]
name = "deno_webgpu"
version = "0.85.0"
version = "0.110.0"
authors = ["the Deno authors"]
edition.workspace = true
license = "MIT"
@ -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]
@ -23,11 +20,11 @@ deno_core.workspace = true
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
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]
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.
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgpu-core]

View File

@ -1,6 +1,6 @@
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
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
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
crate tries to stay up to date with the spec, but is constrained by the features
draft as of March 31, 2024. The spec is still very much in flux. This extension
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).
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::op2;
@ -112,25 +112,11 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess,
access: wgpu_types::StorageTextureAccess,
format: wgpu_types::TextureFormat,
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)]
#[serde(rename_all = "camelCase")]
pub struct GpuBindGroupLayoutEntry {
@ -165,7 +151,7 @@ impl From<GpuBindingType> for wgpu_types::BindingType {
},
GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(),
access: storage_texture.access,
format: storage_texture.format,
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::AnyError;
@ -163,6 +163,7 @@ pub fn op_webgpu_buffer_get_mapped_range(
))
.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) };
buf.copy_from_slice(slice);
@ -189,6 +190,7 @@ pub fn op_webgpu_buffer_unmap(
let buffer = buffer_resource.1;
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) };
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::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 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::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::ResourceId;
use serde::Serialize;
@ -23,7 +24,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;
@ -87,6 +87,7 @@ pub enum WebGpuError {
Lost,
OutOfMemory,
Validation(String),
Internal,
}
impl From<CreateBufferError> for WebGpuError {
@ -277,7 +278,6 @@ impl From<ClearError> for WebGpuError {
}
}
#[cfg(feature = "surface")]
impl From<ConfigureSurfaceError> for WebGpuError {
fn from(err: ConfigureSurfaceError) -> Self {
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"))]
#![warn(unsafe_op_in_unsafe_fn)]
@ -19,6 +19,8 @@ pub use wgpu_types;
use error::DomExceptionOperationError;
use error::WebGpuResult;
pub const UNSTABLE_FEATURE_NAME: &str = "webgpu";
#[macro_use]
mod macros {
macro_rules! gfx_select {
@ -71,6 +73,7 @@ mod macros {
pub mod binding;
pub mod buffer;
pub mod bundle;
pub mod byow;
pub mod command_encoder;
pub mod compute_pass;
pub mod error;
@ -79,23 +82,9 @@ 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);
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>;
struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId);
@ -224,12 +213,15 @@ 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,
// byow
byow::op_webgpu_surface_create,
],
esm = ["01_webgpu.js"],
options = { unstable: bool },
state = |state, options| {
state.put(Unstable(options.unstable));
},
esm = ["00_init.js", "02_surface.js"],
lazy_loaded_esm = ["01_webgpu.js"],
);
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)]
#[serde(untagged)]
pub enum GpuAdapterDeviceOrErr {
pub enum GpuAdapterResOrErr {
Error { err: String },
Features(GpuAdapterDevice),
Features(GpuAdapterRes),
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuAdapterDevice {
pub struct GpuAdapterRes {
rid: ResourceId,
limits: wgpu_types::Limits,
features: Vec<&'static str>,
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]
pub async fn op_webgpu_request_adapter(
pub fn op_webgpu_request_adapter(
state: Rc<RefCell<OpState>>,
#[serde] power_preference: Option<wgpu_types::PowerPreference>,
force_fallback_adapter: bool,
) -> Result<GpuAdapterDeviceOrErr, AnyError> {
) -> Result<GpuAdapterResOrErr, AnyError> {
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(
|_| wgpu_types::Backends::all(),
|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 {
Ok(adapter) => adapter,
Err(err) => {
return Ok(GpuAdapterDeviceOrErr::Error {
return Ok(GpuAdapterResOrErr::Error {
err: err.to_string(),
})
}
@ -445,7 +453,7 @@ pub async fn op_webgpu_request_adapter(
let rid = state.resource_table.add(WebGpuAdapter(instance, adapter));
Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice {
Ok(GpuAdapterResOrErr::Features(GpuAdapterRes {
rid,
features,
limits: adapter_limits,
@ -649,15 +657,15 @@ impl From<GpuRequiredFeatures> for wgpu_types::Features {
}
}
#[op2(async)]
#[op2]
#[serde]
pub async fn op_webgpu_request_device(
pub fn op_webgpu_request_device(
state: Rc<RefCell<OpState>>,
#[smi] adapter_rid: ResourceId,
#[string] label: String,
#[serde] required_features: GpuRequiredFeatures,
#[serde] required_limits: Option<wgpu_types::Limits>,
) -> Result<GpuAdapterDevice, AnyError> {
) -> Result<GpuDeviceRes, AnyError> {
let mut state = state.borrow_mut();
let adapter_resource = state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
let adapter = adapter_resource.1;
@ -669,7 +677,7 @@ pub async fn op_webgpu_request_device(
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,
&descriptor,
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 instance = instance.clone();
let instance2 = instance.clone();
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,
queue_rid,
features,
limits,
// TODO(lucacasonato): report correctly from wgpu
@ -705,9 +718,9 @@ pub struct GPUAdapterInfo {
description: String,
}
#[op2(async)]
#[op2]
#[serde]
pub async fn op_webgpu_request_adapter_info(
pub fn op_webgpu_request_adapter_info(
state: Rc<RefCell<OpState>>,
#[smi] adapter_rid: ResourceId,
) -> 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::op2;
@ -74,7 +74,7 @@ pub enum GPUPipelineLayoutOrGPUAutoLayoutMode {
#[serde(rename_all = "camelCase")]
pub struct GpuProgrammableStage {
module: ResourceId,
entry_point: String,
entry_point: Option<String>,
// constants: HashMap<String, GPUPipelineConstantValue>
}
@ -110,7 +110,7 @@ pub fn op_webgpu_create_compute_pipeline(
layout: pipeline_layout,
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
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
},
};

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::Instance;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
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]
#[serde]
@ -19,7 +31,7 @@ pub fn op_webgpu_queue_submit(
#[smi] queue_rid: ResourceId,
#[serde] command_buffers: Vec<ResourceId>,
) -> 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 = queue_resource.1;
@ -32,7 +44,7 @@ pub fn op_webgpu_queue_submit(
})
.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 {
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
@ -71,7 +83,7 @@ pub fn op_webgpu_write_buffer(
#[number] size: Option<usize>,
#[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let instance = state.borrow::<Instance>();
let buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(buffer)?;
@ -84,7 +96,7 @@ pub fn op_webgpu_write_buffer(
None => &buf[data_offset..],
};
let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
queue.transmute(),
queue,
buffer,
buffer_offset,
data
@ -104,7 +116,7 @@ pub fn op_webgpu_write_texture(
#[serde] size: wgpu_types::Extent3d,
#[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let instance = state.borrow::<Instance>();
let texture_resource = state
.resource_table
.get::<super::texture::WebGpuTexture>(destination.texture)?;
@ -120,7 +132,7 @@ pub fn op_webgpu_write_texture(
let data_layout = data_layout.into();
gfx_ok!(queue => instance.queue_write_texture(
queue.transmute(),
queue,
&destination,
buf,
&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::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::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::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 deno_core::error::AnyError;
@ -11,21 +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"],
options = { unstable: bool },
state = |state, options| {
state.put(super::Unstable(options.unstable));
},
);
pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId);
impl Resource for WebGpuSurface {
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::op2;

View File

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