summaryrefslogtreecommitdiff
path: root/ext/webgpu
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-01-20 15:23:53 +0100
committerGitHub <noreply@github.com>2022-01-20 15:23:53 +0100
commit3ab68bd0a2aff6df12388f2c3b5ed7ae3333a6ca (patch)
tree9a81824deb4e5a2b29c3eeb5a2adaa3e00720c45 /ext/webgpu
parent1cc38f5155bdc5605d74cd959660fa04f782ac63 (diff)
revert(#13402): experiment: wgpu sync (#13439)
Diffstat (limited to 'ext/webgpu')
-rw-r--r--ext/webgpu/01_webgpu.js49
-rw-r--r--ext/webgpu/02_idl_types.js69
-rw-r--r--ext/webgpu/Cargo.toml13
-rw-r--r--ext/webgpu/binding.rs (renamed from ext/webgpu/src/binding.rs)48
-rw-r--r--ext/webgpu/buffer.rs (renamed from ext/webgpu/src/buffer.rs)0
-rw-r--r--ext/webgpu/bundle.rs (renamed from ext/webgpu/src/bundle.rs)16
-rw-r--r--ext/webgpu/command_encoder.rs (renamed from ext/webgpu/src/command_encoder.rs)126
-rw-r--r--ext/webgpu/compute_pass.rs (renamed from ext/webgpu/src/compute_pass.rs)12
-rw-r--r--ext/webgpu/error.rs (renamed from ext/webgpu/src/error.rs)7
-rw-r--r--ext/webgpu/lib.deno_webgpu.d.ts1132
-rw-r--r--ext/webgpu/lib.rs (renamed from ext/webgpu/src/lib.rs)416
-rw-r--r--ext/webgpu/pipeline.rs791
-rw-r--r--ext/webgpu/queue.rs (renamed from ext/webgpu/src/queue.rs)8
-rw-r--r--ext/webgpu/render_pass.rs (renamed from ext/webgpu/src/render_pass.rs)36
-rw-r--r--ext/webgpu/sampler.rs132
-rw-r--r--ext/webgpu/shader.rs (renamed from ext/webgpu/src/shader.rs)1
-rw-r--r--ext/webgpu/texture.rs419
-rw-r--r--ext/webgpu/webgpu.idl187
18 files changed, 2969 insertions, 493 deletions
diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js
index 45d910c1a..f1d3eb120 100644
--- a/ext/webgpu/01_webgpu.js
+++ b/ext/webgpu/01_webgpu.js
@@ -3061,48 +3061,6 @@
}
/**
- * @param {GPUBuffer} destination
- * @param {GPUSize64} destinationOffset
- * @param {GPUSize64} size
- */
- clearBuffer(destination, destinationOffset, size) {
- webidl.assertBranded(this, GPUCommandEncoder);
- const prefix = "Failed to execute 'clearBuffer' on 'GPUCommandEncoder'";
- webidl.requiredArguments(arguments.length, 3, { prefix });
- destination = webidl.converters.GPUBuffer(destination, {
- prefix,
- context: "Argument 1",
- });
- destinationOffset = webidl.converters.GPUSize64(destinationOffset, {
- prefix,
- context: "Argument 2",
- });
- size = webidl.converters.GPUSize64(size, {
- prefix,
- context: "Argument 3",
- });
- const device = assertDevice(this, { prefix, context: "this" });
- const commandEncoderRid = assertResource(this, {
- prefix,
- context: "this",
- });
- const destinationRid = assertResource(destination, {
- prefix,
- context: "Argument 1",
- });
- const { err } = core.opSync(
- "op_webgpu_command_encoder_clear_buffer",
- {
- commandEncoderRid,
- destinationRid,
- destinationOffset,
- size,
- },
- );
- device.pushError(err);
- }
-
- /**
* @param {string} groupLabel
*/
pushDebugGroup(groupLabel) {
@@ -3245,7 +3203,7 @@
prefix,
context: "Argument 3",
});
- destination = webidl.converters.GPUBuffer(destination, {
+ destination = webidl.converters.GPUQuerySet(destination, {
prefix,
context: "Argument 4",
});
@@ -4569,10 +4527,15 @@
webidl.illegalConstructor();
}
+ get executionTime() {
+ throw new Error("Not yet implemented");
+ }
+
[SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${
inspect({
label: this.label,
+ // TODO(crowlKats): executionTime
})
}`;
}
diff --git a/ext/webgpu/02_idl_types.js b/ext/webgpu/02_idl_types.js
index bc92bebab..3c49c1888 100644
--- a/ext/webgpu/02_idl_types.js
+++ b/ext/webgpu/02_idl_types.js
@@ -111,35 +111,28 @@
webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
"GPUFeatureName",
[
- "depth-clip-control",
+ "depth-clamping",
"depth24unorm-stencil8",
"depth32float-stencil8",
"pipeline-statistics-query",
"texture-compression-bc",
- "texture-compression-etc2",
- "texture-compression-astc",
"timestamp-query",
- "indirect-first-instance",
// extended from spec
"mappable-primary-buffers",
- "texture-binding-array",
- "buffer-binding-array",
- "storage-resource-binding-array",
- "sampled-texture-and-storage-buffer-array-non-uniform-indexing",
- "uniform-buffer-and-storage-buffer-texture-non-uniform-indexing",
+ "sampled-texture-binding-array",
+ "sampled-texture-array-dynamic-indexing",
+ "sampled-texture-array-non-uniform-indexing",
"unsized-binding-array",
"multi-draw-indirect",
"multi-draw-indirect-count",
"push-constants",
"address-mode-clamp-to-border",
+ "non-fill-polygon-mode",
+ "texture-compression-etc2",
+ "texture-compression-astc-ldr",
"texture-adapter-specific-format-features",
"shader-float64",
"vertex-attribute-64bit",
- "conservative-rasterization",
- "vertex-writable-storage",
- "clear-commands",
- "spirv-shader-passthrough",
- "shader-primitive-index",
],
);
@@ -355,44 +348,6 @@
"bc6h-rgb-float",
"bc7-rgba-unorm",
"bc7-rgba-unorm-srgb",
- "etc2-rgb8unorm",
- "etc2-rgb8unorm-srgb",
- "etc2-rgb8a1unorm",
- "etc2-rgb8a1unorm-srgb",
- "etc2-rgba8unorm",
- "etc2-rgba8unorm-srgb",
- "eac-r11unorm",
- "eac-r11snorm",
- "eac-rg11unorm",
- "eac-rg11snorm",
- "astc-4x4-unorm",
- "astc-4x4-unorm-srgb",
- "astc-5x4-unorm",
- "astc-5x4-unorm-srgb",
- "astc-5x5-unorm",
- "astc-5x5-unorm-srgb",
- "astc-6x5-unorm",
- "astc-6x5-unorm-srgb",
- "astc-6x6-unorm",
- "astc-6x6-unorm-srgb",
- "astc-8x5-unorm",
- "astc-8x5-unorm-srgb",
- "astc-8x6-unorm",
- "astc-8x6-unorm-srgb",
- "astc-8x8-unorm",
- "astc-8x8-unorm-srgb",
- "astc-10x5-unorm",
- "astc-10x5-unorm-srgb",
- "astc-10x6-unorm",
- "astc-10x6-unorm-srgb",
- "astc-10x8-unorm",
- "astc-10x8-unorm-srgb",
- "astc-10x10-unorm",
- "astc-10x10-unorm-srgb",
- "astc-12x10-unorm",
- "astc-12x10-unorm-srgb",
- "astc-12x12-unorm",
- "astc-12x12-unorm-srgb",
"depth24unorm-stencil8",
"depth32float-stencil8",
],
@@ -1176,7 +1131,7 @@
defaultValue: "none",
},
{
- key: "unclippedDepth",
+ key: "clampDepth",
converter: webidl.converters["boolean"],
defaultValue: false,
},
@@ -1503,7 +1458,13 @@
);
// DICTIONARY: GPUCommandEncoderDescriptor
- const dictMembersGPUCommandEncoderDescriptor = [];
+ const dictMembersGPUCommandEncoderDescriptor = [
+ {
+ key: "measureExecutionTime",
+ converter: webidl.converters["boolean"],
+ defaultValue: false,
+ },
+ ];
webidl.converters["GPUCommandEncoderDescriptor"] = webidl
.createDictionaryConverter(
"GPUCommandEncoderDescriptor",
diff --git a/ext/webgpu/Cargo.toml b/ext/webgpu/Cargo.toml
index fa1228ff0..284f81278 100644
--- a/ext/webgpu/Cargo.toml
+++ b/ext/webgpu/Cargo.toml
@@ -7,12 +7,15 @@ authors = ["the Deno authors"]
edition = "2021"
license = "MIT"
readme = "README.md"
-repository = "https://github.com/gfx-rs/wgpu"
+repository = "https://github.com/denoland/deno"
description = "WebGPU implementation for Deno"
+[lib]
+path = "lib.rs"
+
[dependencies]
deno_core = { version = "0.114.0", path = "../../core" }
-serde = { version = "1.0", features = ["derive"] }
-tokio = { version = "1.10", features = ["full"] }
-wgpu-core = { git = "https://github.com/gfx-rs/wgpu", rev = "cdd480a89c9e3b681d9d174e65082d2bdbc903ef", features = ["trace", "replay", "serde"] }
-wgpu-types = { git = "https://github.com/gfx-rs/wgpu", rev = "cdd480a89c9e3b681d9d174e65082d2bdbc903ef", features = ["trace", "replay", "serde"] }
+serde = { version = "1.0.129", features = ["derive"] }
+tokio = { version = "1.10.1", features = ["full"] }
+wgpu-core = { version = "0.10.1", features = ["trace"] }
+wgpu-types = "0.10.0"
diff --git a/ext/webgpu/src/binding.rs b/ext/webgpu/binding.rs
index 9a8fa455f..fea99fc16 100644
--- a/ext/webgpu/src/binding.rs
+++ b/ext/webgpu/binding.rs
@@ -5,7 +5,8 @@ use deno_core::ResourceId;
use deno_core::{OpState, Resource};
use serde::Deserialize;
use std::borrow::Cow;
-use std::convert::{TryFrom, TryInto};
+
+use crate::texture::{GpuTextureFormat, GpuTextureViewDimension};
use super::error::WebGpuResult;
@@ -58,14 +59,41 @@ impl From<GpuBufferBindingType> for wgpu_types::BufferBindingType {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuSamplerBindingLayout {
- r#type: wgpu_types::SamplerBindingType,
+ r#type: GpuSamplerBindingType,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+enum GpuSamplerBindingType {
+ Filtering,
+ NonFiltering,
+ Comparison,
+}
+
+impl From<GpuSamplerBindingType> for wgpu_types::BindingType {
+ fn from(binding_type: GpuSamplerBindingType) -> Self {
+ match binding_type {
+ GpuSamplerBindingType::Filtering => wgpu_types::BindingType::Sampler {
+ filtering: true,
+ comparison: false,
+ },
+ GpuSamplerBindingType::NonFiltering => wgpu_types::BindingType::Sampler {
+ filtering: false,
+ comparison: false,
+ },
+ GpuSamplerBindingType::Comparison => wgpu_types::BindingType::Sampler {
+ filtering: true,
+ comparison: true,
+ },
+ }
+ }
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuTextureBindingLayout {
sample_type: GpuTextureSampleType,
- view_dimension: wgpu_types::TextureViewDimension,
+ view_dimension: GpuTextureViewDimension,
multisampled: bool,
}
@@ -99,8 +127,8 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess,
- format: wgpu_types::TextureFormat,
- view_dimension: wgpu_types::TextureViewDimension,
+ format: GpuTextureFormat,
+ view_dimension: GpuTextureViewDimension,
}
#[derive(Deserialize)]
@@ -149,19 +177,17 @@ impl TryFrom<GpuBindingType> for wgpu_types::BindingType {
has_dynamic_offset: buffer.has_dynamic_offset,
min_binding_size: std::num::NonZeroU64::new(buffer.min_binding_size),
},
- GpuBindingType::Sampler(sampler) => {
- wgpu_types::BindingType::Sampler(sampler.r#type)
- }
+ GpuBindingType::Sampler(sampler) => sampler.r#type.into(),
GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture {
sample_type: texture.sample_type.into(),
- view_dimension: texture.view_dimension,
+ view_dimension: texture.view_dimension.into(),
multisampled: texture.multisampled,
},
GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(),
- format: storage_texture.format,
- view_dimension: storage_texture.view_dimension,
+ format: storage_texture.format.try_into()?,
+ view_dimension: storage_texture.view_dimension.into(),
}
}
};
diff --git a/ext/webgpu/src/buffer.rs b/ext/webgpu/buffer.rs
index 3f2c07883..3f2c07883 100644
--- a/ext/webgpu/src/buffer.rs
+++ b/ext/webgpu/buffer.rs
diff --git a/ext/webgpu/src/bundle.rs b/ext/webgpu/bundle.rs
index ea327651a..7b32c1ece 100644
--- a/ext/webgpu/src/bundle.rs
+++ b/ext/webgpu/bundle.rs
@@ -9,6 +9,9 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::rc::Rc;
+use crate::pipeline::GpuIndexFormat;
+use crate::texture::GpuTextureFormat;
+
use super::error::WebGpuResult;
struct WebGpuRenderBundleEncoder(
@@ -32,8 +35,8 @@ impl Resource for WebGpuRenderBundle {
pub struct CreateRenderBundleEncoderArgs {
device_rid: ResourceId,
label: Option<String>,
- color_formats: Vec<wgpu_types::TextureFormat>,
- depth_stencil_format: Option<wgpu_types::TextureFormat>,
+ color_formats: Vec<GpuTextureFormat>,
+ depth_stencil_format: Option<GpuTextureFormat>,
sample_count: u32,
depth_read_only: bool,
stencil_read_only: bool,
@@ -52,12 +55,12 @@ pub fn op_webgpu_create_render_bundle_encoder(
let mut color_formats = vec![];
for format in args.color_formats {
- color_formats.push(format);
+ color_formats.push(format.try_into()?);
}
let depth_stencil = if let Some(format) = args.depth_stencil_format {
Some(wgpu_types::RenderBundleDepthStencil {
- format,
+ format: format.try_into()?,
depth_read_only: args.depth_read_only,
stencil_read_only: args.stencil_read_only,
})
@@ -70,7 +73,6 @@ pub fn op_webgpu_create_render_bundle_encoder(
color_formats: Cow::from(color_formats),
sample_count: args.sample_count,
depth_stencil,
- multiview: None,
};
let res =
@@ -299,7 +301,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline(
pub struct RenderBundleEncoderSetIndexBufferArgs {
render_bundle_encoder_rid: ResourceId,
buffer: ResourceId,
- index_format: wgpu_types::IndexFormat,
+ index_format: GpuIndexFormat,
offset: u64,
size: u64,
}
@@ -322,7 +324,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
.borrow_mut()
.set_index_buffer(
buffer_resource.0,
- args.index_format,
+ args.index_format.into(),
args.offset,
std::num::NonZeroU64::new(args.size),
);
diff --git a/ext/webgpu/src/command_encoder.rs b/ext/webgpu/command_encoder.rs
index 894b08f27..cbd57f694 100644
--- a/ext/webgpu/src/command_encoder.rs
+++ b/ext/webgpu/command_encoder.rs
@@ -8,6 +8,8 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::num::NonZeroU32;
+use crate::texture::GpuTextureAspect;
+
use super::error::WebGpuResult;
pub(crate) struct WebGpuCommandEncoder(
@@ -63,8 +65,8 @@ pub fn op_webgpu_create_command_encoder(
pub struct GpuRenderPassColorAttachment {
view: ResourceId,
resolve_target: Option<ResourceId>,
- load_op: GpuLoadOp<wgpu_types::Color>,
- store_op: wgpu_core::command::StoreOp,
+ load_op: GpuLoadOp<super::render_pass::GpuColor>,
+ store_op: GpuStoreOp,
}
#[derive(Deserialize)]
@@ -75,14 +77,30 @@ enum GpuLoadOp<T> {
}
#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+enum GpuStoreOp {
+ Store,
+ Discard,
+}
+
+impl From<GpuStoreOp> for wgpu_core::command::StoreOp {
+ fn from(value: GpuStoreOp) -> wgpu_core::command::StoreOp {
+ match value {
+ GpuStoreOp::Store => wgpu_core::command::StoreOp::Store,
+ GpuStoreOp::Discard => wgpu_core::command::StoreOp::Discard,
+ }
+ }
+}
+
+#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuRenderPassDepthStencilAttachment {
view: ResourceId,
depth_load_op: GpuLoadOp<f32>,
- depth_store_op: wgpu_core::command::StoreOp,
+ depth_store_op: GpuStoreOp,
depth_read_only: bool,
stencil_load_op: GpuLoadOp<u32>,
- stencil_store_op: wgpu_core::command::StoreOp,
+ stencil_store_op: GpuStoreOp,
stencil_read_only: bool,
}
@@ -129,14 +147,19 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
channel: match color_attachment.load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load,
- store_op: color_attachment.store_op,
+ store_op: color_attachment.store_op.into(),
clear_value: Default::default(),
read_only: false,
},
GpuLoadOp::Clear(color) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear,
- store_op: color_attachment.store_op,
- clear_value: color,
+ store_op: color_attachment.store_op.into(),
+ clear_value: wgpu_types::Color {
+ r: color.r,
+ g: color.g,
+ b: color.b,
+ a: color.a,
+ },
read_only: false,
},
},
@@ -159,13 +182,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
depth: match attachment.depth_load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load,
- store_op: attachment.depth_store_op,
+ store_op: attachment.depth_store_op.into(),
clear_value: 0.0,
read_only: attachment.depth_read_only,
},
GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear,
- store_op: attachment.depth_store_op,
+ store_op: attachment.depth_store_op.into(),
clear_value: value,
read_only: attachment.depth_read_only,
},
@@ -173,13 +196,13 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
stencil: match attachment.stencil_load_op {
GpuLoadOp::Load => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Load,
- store_op: attachment.stencil_store_op,
+ store_op: attachment.stencil_store_op.into(),
clear_value: 0,
read_only: attachment.stencil_read_only,
},
GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel {
load_op: wgpu_core::command::LoadOp::Clear,
- store_op: attachment.stencil_store_op,
+ store_op: attachment.stencil_store_op.into(),
clear_value: value,
read_only: attachment.stencil_read_only,
},
@@ -294,11 +317,29 @@ pub struct GpuImageCopyBuffer {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
+pub struct GpuOrigin3D {
+ pub x: u32,
+ pub y: u32,
+ pub z: u32,
+}
+
+impl From<GpuOrigin3D> for wgpu_types::Origin3d {
+ fn from(origin: GpuOrigin3D) -> wgpu_types::Origin3d {
+ wgpu_types::Origin3d {
+ x: origin.x,
+ y: origin.y,
+ z: origin.z,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
pub struct GpuImageCopyTexture {
pub texture: ResourceId,
pub mip_level: u32,
- pub origin: wgpu_types::Origin3d,
- pub aspect: wgpu_types::TextureAspect,
+ pub origin: GpuOrigin3D,
+ pub aspect: GpuTextureAspect,
}
#[derive(Deserialize)]
@@ -307,7 +348,7 @@ pub struct CommandEncoderCopyBufferToTextureArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyBuffer,
destination: GpuImageCopyTexture,
- copy_size: wgpu_types::Extent3d,
+ copy_size: super::texture::GpuExtent3D,
}
pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
@@ -340,14 +381,14 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0,
mip_level: args.destination.mip_level,
- origin: args.destination.origin,
- aspect: args.destination.aspect,
+ origin: args.destination.origin.into(),
+ aspect: args.destination.aspect.into(),
};
gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture(
command_encoder,
&source,
&destination,
- &args.copy_size
+ &args.copy_size.into()
))
}
@@ -357,7 +398,7 @@ pub struct CommandEncoderCopyTextureToBufferArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyTexture,
destination: GpuImageCopyBuffer,
- copy_size: wgpu_types::Extent3d,
+ copy_size: super::texture::GpuExtent3D,
}
pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
@@ -382,8 +423,8 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0,
mip_level: args.source.mip_level,
- origin: args.source.origin,
- aspect: args.source.aspect,
+ origin: args.source.origin.into(),
+ aspect: args.source.aspect.into(),
};
let destination = wgpu_core::command::ImageCopyBuffer {
buffer: destination_buffer_resource.0,
@@ -401,7 +442,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
command_encoder,
&source,
&destination,
- &args.copy_size
+ &args.copy_size.into()
))
}
@@ -411,7 +452,7 @@ pub struct CommandEncoderCopyTextureToTextureArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyTexture,
destination: GpuImageCopyTexture,
- copy_size: wgpu_types::Extent3d,
+ copy_size: super::texture::GpuExtent3D,
}
pub fn op_webgpu_command_encoder_copy_texture_to_texture(
@@ -436,51 +477,20 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture(
let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0,
mip_level: args.source.mip_level,
- origin: args.source.origin,
- aspect: args.source.aspect,
+ origin: args.source.origin.into(),
+ aspect: args.source.aspect.into(),
};
let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0,
mip_level: args.destination.mip_level,
- origin: args.destination.origin,
- aspect: args.destination.aspect,
+ origin: args.destination.origin.into(),
+ aspect: args.destination.aspect.into(),
};
gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture(
command_encoder,
&source,
&destination,
- &args.copy_size
- ))
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CommandEncoderClearBufferArgs {
- command_encoder_rid: u32,
- destination_rid: u32,
- destination_offset: u64,
- size: u64,
-}
-
-pub fn op_webgpu_command_encoder_clear_buffer(
- state: &mut OpState,
- args: CommandEncoderClearBufferArgs,
- _: (),
-) -> Result<WebGpuResult, AnyError> {
- let instance = state.borrow::<super::Instance>();
- let command_encoder_resource = state
- .resource_table
- .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?;
- let command_encoder = command_encoder_resource.0;
- let destination_resource = state
- .resource_table
- .get::<super::buffer::WebGpuBuffer>(args.destination_rid)?;
-
- gfx_ok!(command_encoder => instance.command_encoder_clear_buffer(
- command_encoder,
- destination_resource.0,
- args.destination_offset,
- std::num::NonZeroU64::new(args.size)
+ &args.copy_size.into()
))
}
diff --git a/ext/webgpu/src/compute_pass.rs b/ext/webgpu/compute_pass.rs
index 03d9163cb..e52db461c 100644
--- a/ext/webgpu/src/compute_pass.rs
+++ b/ext/webgpu/compute_pass.rs
@@ -125,10 +125,10 @@ pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query(
.get::<super::WebGpuQuerySet>(args.query_set)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query(
- &mut compute_pass_resource.0.borrow_mut(),
- query_set_resource.0,
- args.query_index,
- );
+ &mut compute_pass_resource.0.borrow_mut(),
+ query_set_resource.0,
+ args.query_index,
+ );
Ok(WebGpuResult::empty())
}
@@ -149,8 +149,8 @@ pub fn op_webgpu_compute_pass_end_pipeline_statistics_query(
.get::<WebGpuComputePass>(args.compute_pass_rid)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query(
- &mut compute_pass_resource.0.borrow_mut(),
- );
+ &mut compute_pass_resource.0.borrow_mut(),
+ );
Ok(WebGpuResult::empty())
}
diff --git a/ext/webgpu/src/error.rs b/ext/webgpu/error.rs
index ae6e48054..18ffdf1a8 100644
--- a/ext/webgpu/src/error.rs
+++ b/ext/webgpu/error.rs
@@ -8,7 +8,6 @@ use wgpu_core::binding_model::CreateBindGroupError;
use wgpu_core::binding_model::CreateBindGroupLayoutError;
use wgpu_core::binding_model::CreatePipelineLayoutError;
use wgpu_core::binding_model::GetBindGroupLayoutError;
-use wgpu_core::command::ClearError;
use wgpu_core::command::CommandEncoderError;
use wgpu_core::command::ComputePassError;
use wgpu_core::command::CopyError;
@@ -259,12 +258,6 @@ impl From<QueueWriteError> for WebGpuError {
}
}
-impl From<ClearError> for WebGpuError {
- fn from(err: ClearError) -> Self {
- WebGpuError::Validation(err.to_string())
- }
-}
-
#[derive(Debug)]
pub struct DomExceptionOperationError {
pub msg: String,
diff --git a/ext/webgpu/lib.deno_webgpu.d.ts b/ext/webgpu/lib.deno_webgpu.d.ts
new file mode 100644
index 000000000..6d480d3c3
--- /dev/null
+++ b/ext/webgpu/lib.deno_webgpu.d.ts
@@ -0,0 +1,1132 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-explicit-any no-empty-interface
+
+/// <reference no-default-lib="true" />
+/// <reference lib="esnext" />
+
+// 8cc98b6f10b7f354473a08c3773bb1de839845b9
+
+interface GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUObjectDescriptorBase {
+ label?: string;
+}
+
+declare class GPUSupportedLimits {
+ maxTextureDimension1D?: number;
+ maxTextureDimension2D?: number;
+ maxTextureDimension3D?: number;
+ maxTextureArrayLayers?: number;
+ maxBindGroups?: number;
+ maxDynamicUniformBuffersPerPipelineLayout?: number;
+ maxDynamicStorageBuffersPerPipelineLayout?: number;
+ maxSampledTexturesPerShaderStage?: number;
+ maxSamplersPerShaderStage?: number;
+ maxStorageBuffersPerShaderStage?: number;
+ maxStorageTexturesPerShaderStage?: number;
+ maxUniformBuffersPerShaderStage?: number;
+ maxUniformBufferBindingSize?: number;
+ maxStorageBufferBindingSize?: number;
+ minUniformBufferOffsetAlignment?: number;
+ minStorageBufferOffsetAlignment?: number;
+ maxVertexBuffers?: number;
+ maxVertexAttributes?: number;
+ maxVertexBufferArrayStride?: number;
+ maxInterStageShaderComponents?: number;
+ maxComputeWorkgroupStorageSize?: number;
+ maxComputeInvocationsPerWorkgroup?: number;
+ maxComputeWorkgroupSizeX?: number;
+ maxComputeWorkgroupSizeY?: number;
+ maxComputeWorkgroupSizeZ?: number;
+ maxComputeWorkgroupsPerDimension?: number;
+}
+
+declare class GPUSupportedFeatures {
+ forEach(
+ callbackfn: (
+ value: GPUFeatureName,
+ value2: GPUFeatureName,
+ set: Set<GPUFeatureName>,
+ ) => void,
+ thisArg?: any,
+ ): void;
+ has(value: GPUFeatureName): boolean;
+ size: number;
+ [
+ Symbol
+ .iterator
+ ](): IterableIterator<GPUFeatureName>;
+ entries(): IterableIterator<[GPUFeatureName, GPUFeatureName]>;
+ keys(): IterableIterator<GPUFeatureName>;
+ values(): IterableIterator<GPUFeatureName>;
+}
+
+declare class GPU {
+ requestAdapter(
+ options?: GPURequestAdapterOptions,
+ ): Promise<GPUAdapter | null>;
+}
+
+declare interface GPURequestAdapterOptions {
+ powerPreference?: GPUPowerPreference;
+ forceFallbackAdapter?: boolean;
+}
+
+declare type GPUPowerPreference = "low-power" | "high-performance";
+
+declare class GPUAdapter {
+ readonly name: string;
+ readonly features: GPUSupportedFeatures;
+ readonly limits: GPUSupportedLimits;
+ readonly isFallbackAdapter: boolean;
+
+ requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>;
+}
+
+declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase {
+ requiredFeatures?: GPUFeatureName[];
+ requiredLimits?: Record<string, number>;
+}
+
+declare type GPUFeatureName =
+ | "depth-clamping"
+ | "depth24unorm-stencil8"
+ | "depth32float-stencil8"
+ | "pipeline-statistics-query"
+ | "texture-compression-bc"
+ | "timestamp-query"
+ // extended from spec
+ | "mappable-primary-buffers"
+ | "sampled-texture-binding-array"
+ | "sampled-texture-array-dynamic-indexing"
+ | "sampled-texture-array-non-uniform-indexing"
+ | "unsized-binding-array"
+ | "multi-draw-indirect"
+ | "multi-draw-indirect-count"
+ | "push-constants"
+ | "address-mode-clamp-to-border"
+ | "non-fill-polygon-mode"
+ | "texture-compression-etc2"
+ | "texture-compression-astc-ldr"
+ | "texture-adapter-specific-format-features"
+ | "shader-float64"
+ | "vertex-attribute-64bit";
+
+declare class GPUDevice extends EventTarget implements GPUObjectBase {
+ label: string | null;
+
+ readonly lost: Promise<GPUDeviceLostInfo>;
+ pushErrorScope(filter: GPUErrorFilter): undefined;
+ popErrorScope(): Promise<GPUError | null>;
+ onuncapturederror:
+ | ((this: GPUDevice, ev: GPUUncapturedErrorEvent) => any)
+ | null;
+
+ readonly features: ReadonlyArray<GPUFeatureName>;
+ readonly limits: Record<string, number>;
+ readonly queue: GPUQueue;
+
+ destroy(): undefined;
+
+ createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer;
+ createTexture(descriptor: GPUTextureDescriptor): GPUTexture;
+ createSampler(descriptor?: GPUSamplerDescriptor): GPUSampler;
+
+ createBindGroupLayout(
+ descriptor: GPUBindGroupLayoutDescriptor,
+ ): GPUBindGroupLayout;
+ createPipelineLayout(
+ descriptor: GPUPipelineLayoutDescriptor,
+ ): GPUPipelineLayout;
+ createBindGroup(descriptor: GPUBindGroupDescriptor): GPUBindGroup;
+
+ createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule;
+ createComputePipeline(
+ descriptor: GPUComputePipelineDescriptor,
+ ): GPUComputePipeline;
+ createRenderPipeline(
+ descriptor: GPURenderPipelineDescriptor,
+ ): GPURenderPipeline;
+ createComputePipelineAsync(
+ descriptor: GPUComputePipelineDescriptor,
+ ): Promise<GPUComputePipeline>;
+ createRenderPipelineAsync(
+ descriptor: GPURenderPipelineDescriptor,
+ ): Promise<GPURenderPipeline>;
+
+ createCommandEncoder(
+ descriptor?: GPUCommandEncoderDescriptor,
+ ): GPUCommandEncoder;
+ createRenderBundleEncoder(
+ descriptor: GPURenderBundleEncoderDescriptor,
+ ): GPURenderBundleEncoder;
+
+ createQuerySet(descriptor: GPUQuerySetDescriptor): GPUQuerySet;
+}
+
+declare class GPUBuffer implements GPUObjectBase {
+ label: string | null;
+
+ mapAsync(
+ mode: GPUMapModeFlags,
+ offset?: number,
+ size?: number,
+ ): Promise<undefined>;
+ getMappedRange(offset?: number, size?: number): ArrayBuffer;
+ unmap(): undefined;
+
+ destroy(): undefined;
+}
+
+declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase {
+ size: number;
+ usage: GPUBufferUsageFlags;
+ mappedAtCreation?: boolean;
+}
+
+declare type GPUBufferUsageFlags = number;
+declare class GPUBufferUsage {
+ static MAP_READ: 0x0001;
+ static MAP_WRITE: 0x0002;
+ static COPY_SRC: 0x0004;
+ static COPY_DST: 0x0008;
+ static INDEX: 0x0010;
+ static VERTEX: 0x0020;
+ static UNIFORM: 0x0040;
+ static STORAGE: 0x0080;
+ static INDIRECT: 0x0100;
+ static QUERY_RESOLVE: 0x0200;
+}
+
+declare type GPUMapModeFlags = number;
+declare class GPUMapMode {
+ static READ: 0x0001;
+ static WRITE: 0x0002;
+}
+
+declare class GPUTexture implements GPUObjectBase {
+ label: string | null;
+
+ createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView;
+ destroy(): undefined;
+}
+
+declare interface GPUTextureDescriptor extends GPUObjectDescriptorBase {
+ size: GPUExtent3D;
+ mipLevelCount?: number;
+ sampleCount?: number;
+ dimension?: GPUTextureDimension;
+ format: GPUTextureFormat;
+ usage: GPUTextureUsageFlags;
+}
+
+declare type GPUTextureDimension = "1d" | "2d" | "3d";
+
+declare type GPUTextureUsageFlags = number;
+declare class GPUTextureUsage {
+ static COPY_SRC: 0x01;
+ static COPY_DST: 0x02;
+ static TEXTURE_BINDING: 0x04;
+ static STORAGE_BINDING: 0x08;
+ static RENDER_ATTACHMENT: 0x10;
+}
+
+declare class GPUTextureView implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUTextureViewDescriptor extends GPUObjectDescriptorBase {
+ format?: GPUTextureFormat;
+ dimension?: GPUTextureViewDimension;
+ aspect?: GPUTextureAspect;
+ baseMipLevel?: number;
+ mipLevelCount?: number;
+ baseArrayLayer?: number;
+ arrayLayerCount?: number;
+}
+
+declare type GPUTextureViewDimension =
+ | "1d"
+ | "2d"
+ | "2d-array"
+ | "cube"
+ | "cube-array"
+ | "3d";
+
+declare type GPUTextureAspect = "all" | "stencil-only" | "depth-only";
+
+declare type GPUTextureFormat =
+ | "r8unorm"
+ | "r8snorm"
+ | "r8uint"
+ | "r8sint"
+ | "r16uint"
+ | "r16sint"
+ | "r16float"
+ | "rg8unorm"
+ | "rg8snorm"
+ | "rg8uint"
+ | "rg8sint"
+ | "r32uint"
+ | "r32sint"
+ | "r32float"
+ | "rg16uint"
+ | "rg16sint"
+ | "rg16float"
+ | "rgba8unorm"
+ | "rgba8unorm-srgb"
+ | "rgba8snorm"
+ | "rgba8uint"
+ | "rgba8sint"
+ | "bgra8unorm"
+ | "bgra8unorm-srgb"
+ | "rgb9e5ufloat"
+ | "rgb10a2unorm"
+ | "rg11b10ufloat"
+ | "rg32uint"
+ | "rg32sint"
+ | "rg32float"
+ | "rgba16uint"
+ | "rgba16sint"
+ | "rgba16float"
+ | "rgba32uint"
+ | "rgba32sint"
+ | "rgba32float"
+ | "stencil8"
+ | "depth16unorm"
+ | "depth24plus"
+ | "depth24plus-stencil8"
+ | "depth32float"
+ | "bc1-rgba-unorm"
+ | "bc1-rgba-unorm-srgb"
+ | "bc2-rgba-unorm"
+ | "bc2-rgba-unorm-srgb"
+ | "bc3-rgba-unorm"
+ | "bc3-rgba-unorm-srgb"
+ | "bc4-r-unorm"
+ | "bc4-r-snorm"
+ | "bc5-rg-unorm"
+ | "bc5-rg-snorm"
+ | "bc6h-rgb-ufloat"
+ | "bc6h-rgb-float"
+ | "bc7-rgba-unorm"
+ | "bc7-rgba-unorm-srgb"
+ | "depth24unorm-stencil8"
+ | "depth32float-stencil8";
+
+declare class GPUSampler implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUSamplerDescriptor extends GPUObjectDescriptorBase {
+ addressModeU?: GPUAddressMode;
+ addressModeV?: GPUAddressMode;
+ addressModeW?: GPUAddressMode;
+ magFilter?: GPUFilterMode;
+ minFilter?: GPUFilterMode;
+ mipmapFilter?: GPUFilterMode;
+ lodMinClamp?: number;
+ lodMaxClamp?: number;
+ compare?: GPUCompareFunction;
+ maxAnisotropy?: number;
+}
+
+declare type GPUAddressMode = "clamp-to-edge" | "repeat" | "mirror-repeat";
+
+declare type GPUFilterMode = "nearest" | "linear";
+
+declare type GPUCompareFunction =
+ | "never"
+ | "less"
+ | "equal"
+ | "less-equal"
+ | "greater"
+ | "not-equal"
+ | "greater-equal"
+ | "always";
+
+declare class GPUBindGroupLayout implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUBindGroupLayoutDescriptor extends GPUObjectDescriptorBase {
+ entries: GPUBindGroupLayoutEntry[];
+}
+
+declare interface GPUBindGroupLayoutEntry {
+ binding: number;
+ visibility: GPUShaderStageFlags;
+
+ buffer?: GPUBufferBindingLayout;
+ sampler?: GPUSamplerBindingLayout;
+ texture?: GPUTextureBindingLayout;
+ storageTexture?: GPUStorageTextureBindingLayout;
+}
+
+declare type GPUShaderStageFlags = number;
+declare class GPUShaderStage {
+ static VERTEX: 0x1;
+ static FRAGMENT: 0x2;
+ static COMPUTE: 0x4;
+}
+
+declare interface GPUBufferBindingLayout {
+ type?: GPUBufferBindingType;
+ hasDynamicOffset?: boolean;
+ minBindingSize?: number;
+}
+
+declare type GPUBufferBindingType = "uniform" | "storage" | "read-only-storage";
+
+declare interface GPUSamplerBindingLayout {
+ type?: GPUSamplerBindingType;
+}
+
+declare type GPUSamplerBindingType =
+ | "filtering"
+ | "non-filtering"
+ | "comparison";
+
+declare interface GPUTextureBindingLayout {
+ sampleType?: GPUTextureSampleType;
+ viewDimension?: GPUTextureViewDimension;
+ multisampled?: boolean;
+}
+
+declare type GPUTextureSampleType =
+ | "float"
+ | "unfilterable-float"
+ | "depth"
+ | "sint"
+ | "uint";
+
+declare type GPUStorageTextureAccess = "write-only";
+
+declare interface GPUStorageTextureBindingLayout {
+ access: GPUStorageTextureAccess;
+ format: GPUTextureFormat;
+ viewDimension?: GPUTextureViewDimension;
+}
+
+declare class GPUBindGroup implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase {
+ layout: GPUBindGroupLayout;
+ entries: GPUBindGroupEntry[];
+}
+
+declare type GPUBindingResource =
+ | GPUSampler
+ | GPUTextureView
+ | GPUBufferBinding;
+
+declare interface GPUBindGroupEntry {
+ binding: number;
+ resource: GPUBindingResource;
+}
+
+declare interface GPUBufferBinding {
+ buffer: GPUBuffer;
+ offset?: number;
+ size?: number;
+}
+
+declare class GPUPipelineLayout implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPUPipelineLayoutDescriptor extends GPUObjectDescriptorBase {
+ bindGroupLayouts: GPUBindGroupLayout[];
+}
+
+declare type GPUCompilationMessageType = "error" | "warning" | "info";
+
+declare interface GPUCompilationMessage {
+ readonly message: string;
+ readonly type: GPUCompilationMessageType;
+ readonly lineNum: number;
+ readonly linePos: number;
+}
+
+declare interface GPUCompilationInfo {
+ readonly messages: ReadonlyArray<GPUCompilationMessage>;
+}
+
+declare class GPUShaderModule implements GPUObjectBase {
+ label: string | null;
+
+ compilationInfo(): Promise<GPUCompilationInfo>;
+}
+
+declare interface GPUShaderModuleDescriptor extends GPUObjectDescriptorBase {
+ code: string;
+ sourceMap?: any;
+}
+
+declare interface GPUPipelineDescriptorBase extends GPUObjectDescriptorBase {
+ layout?: GPUPipelineLayout;
+}
+
+declare interface GPUPipelineBase {
+ getBindGroupLayout(index: number): GPUBindGroupLayout;
+}
+
+declare interface GPUProgrammableStage {
+ module: GPUShaderModule;
+ entryPoint: string;
+}
+
+declare class GPUComputePipeline implements GPUObjectBase, GPUPipelineBase {
+ label: string | null;
+
+ getBindGroupLayout(index: number): GPUBindGroupLayout;
+}
+
+declare interface GPUComputePipelineDescriptor
+ extends GPUPipelineDescriptorBase {
+ compute: GPUProgrammableStage;
+}
+
+declare class GPURenderPipeline implements GPUObjectBase, GPUPipelineBase {
+ label: string | null;
+
+ getBindGroupLayout(index: number): GPUBindGroupLayout;
+}
+
+declare interface GPURenderPipelineDescriptor
+ extends GPUPipelineDescriptorBase {
+ vertex: GPUVertexState;
+ primitive?: GPUPrimitiveState;
+ depthStencil?: GPUDepthStencilState;
+ multisample?: GPUMultisampleState;
+ fragment?: GPUFragmentState;
+}
+
+declare type GPUPrimitiveTopology =
+ | "point-list"
+ | "line-list"
+ | "line-strip"
+ | "triangle-list"
+ | "triangle-strip";
+
+declare interface GPUPrimitiveState {
+ topology?: GPUPrimitiveTopology;
+ stripIndexFormat?: GPUIndexFormat;
+ frontFace?: GPUFrontFace;
+ cullMode?: GPUCullMode;
+ clampDepth?: boolean;
+}
+
+declare type GPUFrontFace = "ccw" | "cw";
+
+declare type GPUCullMode = "none" | "front" | "back";
+
+declare interface GPUMultisampleState {
+ count?: number;
+ mask?: number;
+ alphaToCoverageEnabled?: boolean;
+}
+
+declare interface GPUFragmentState extends GPUProgrammableStage {
+ targets: GPUColorTargetState[];
+}
+
+declare interface GPUColorTargetState {
+ format: GPUTextureFormat;
+
+ blend?: GPUBlendState;
+ writeMask?: GPUColorWriteFlags;
+}
+
+declare interface GPUBlendState {
+ color: GPUBlendComponent;
+ alpha: GPUBlendComponent;
+}
+
+declare type GPUColorWriteFlags = number;
+declare class GPUColorWrite {
+ static RED: 0x1;
+ static GREEN: 0x2;
+ static BLUE: 0x4;
+ static ALPHA: 0x8;
+ static ALL: 0xF;
+}
+
+declare interface GPUBlendComponent {
+ srcFactor: GPUBlendFactor;
+ dstFactor: GPUBlendFactor;
+ operation: GPUBlendOperation;
+}
+
+declare type GPUBlendFactor =
+ | "zero"
+ | "one"
+ | "src"
+ | "one-minus-src"
+ | "src-alpha"
+ | "one-minus-src-alpha"
+ | "dst"
+ | "one-minus-dst"
+ | "dst-alpha"
+ | "one-minus-dst-alpha"
+ | "src-alpha-saturated"
+ | "constant"
+ | "one-minus-constant";
+
+declare type GPUBlendOperation =
+ | "add"
+ | "subtract"
+ | "reverse-subtract"
+ | "min"
+ | "max";
+
+declare interface GPUDepthStencilState {
+ format: GPUTextureFormat;
+
+ depthWriteEnabled?: boolean;
+ depthCompare?: GPUCompareFunction;
+
+ stencilFront?: GPUStencilFaceState;
+ stencilBack?: GPUStencilFaceState;
+
+ stencilReadMask?: number;
+ stencilWriteMask?: number;
+
+ depthBias?: number;
+ depthBiasSlopeScale?: number;
+ depthBiasClamp?: number;
+}
+
+declare interface GPUStencilFaceState {
+ compare?: GPUCompareFunction;
+ failOp?: GPUStencilOperation;
+ depthFailOp?: GPUStencilOperation;
+ passOp?: GPUStencilOperation;
+}
+
+declare type GPUStencilOperation =
+ | "keep"
+ | "zero"
+ | "replace"
+ | "invert"
+ | "increment-clamp"
+ | "decrement-clamp"
+ | "increment-wrap"
+ | "decrement-wrap";
+
+declare type GPUIndexFormat = "uint16" | "uint32";
+
+declare type GPUVertexFormat =
+ | "uint8x2"
+ | "uint8x4"
+ | "sint8x2"
+ | "sint8x4"
+ | "unorm8x2"
+ | "unorm8x4"
+ | "snorm8x2"
+ | "snorm8x4"
+ | "uint16x2"
+ | "uint16x4"
+ | "sint16x2"
+ | "sint16x4"
+ | "unorm16x2"
+ | "unorm16x4"
+ | "snorm16x2"
+ | "snorm16x4"
+ | "float16x2"
+ | "float16x4"
+ | "float32"
+ | "float32x2"
+ | "float32x3"
+ | "float32x4"
+ | "uint32"
+ | "uint32x2"
+ | "uint32x3"
+ | "uint32x4"
+ | "sint32"
+ | "sint32x2"
+ | "sint32x3"
+ | "sint32x4";
+declare type GPUVertexStepMode = "vertex" | "instance";
+
+declare interface GPUVertexState extends GPUProgrammableStage {
+ buffers?: (GPUVertexBufferLayout | null)[];
+}
+
+declare interface GPUVertexBufferLayout {
+ arrayStride: number;
+ stepMode?: GPUVertexStepMode;
+ attributes: GPUVertexAttribute[];
+}
+
+declare interface GPUVertexAttribute {
+ format: GPUVertexFormat;
+ offset: number;
+
+ shaderLocation: number;
+}
+
+declare class GPUCommandBuffer implements GPUObjectBase {
+ label: string | null;
+
+ readonly executionTime: Promise<number>;
+}
+
+declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {}
+
+declare class GPUCommandEncoder implements GPUObjectBase {
+ label: string | null;
+
+ beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder;
+ beginComputePass(
+ descriptor?: GPUComputePassDescriptor,
+ ): GPUComputePassEncoder;
+
+ copyBufferToBuffer(
+ source: GPUBuffer,
+ sourceOffset: number,
+ destination: GPUBuffer,
+ destinationOffset: number,
+ size: number,
+ ): undefined;
+
+ copyBufferToTexture(
+ source: GPUImageCopyBuffer,
+ destination: GPUImageCopyTexture,
+ copySize: GPUExtent3D,
+ ): undefined;
+
+ copyTextureToBuffer(
+ source: GPUImageCopyTexture,
+ destination: GPUImageCopyBuffer,
+ copySize: GPUExtent3D,
+ ): undefined;
+
+ copyTextureToTexture(
+ source: GPUImageCopyTexture,
+ destination: GPUImageCopyTexture,
+ copySize: GPUExtent3D,
+ ): undefined;
+
+ pushDebugGroup(groupLabel: string): undefined;
+ popDebugGroup(): undefined;
+ insertDebugMarker(markerLabel: string): undefined;
+
+ writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined;
+
+ resolveQuerySet(
+ querySet: GPUQuerySet,
+ firstQuery: number,
+ queryCount: number,
+ destination: GPUBuffer,
+ destinationOffset: number,
+ ): undefined;
+
+ finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer;
+}
+
+declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {
+ measureExecutionTime?: boolean;
+}
+
+declare interface GPUImageDataLayout {
+ offset?: number;
+ bytesPerRow?: number;
+ rowsPerImage?: number;
+}
+
+declare interface GPUImageCopyBuffer extends GPUImageDataLayout {
+ buffer: GPUBuffer;
+}
+
+declare interface GPUImageCopyTexture {
+ texture: GPUTexture;
+ mipLevel?: number;
+ origin?: GPUOrigin3D;
+ aspect?: GPUTextureAspect;
+}
+
+interface GPUProgrammablePassEncoder {
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsets?: number[],
+ ): undefined;
+
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsetsData: Uint32Array,
+ dynamicOffsetsDataStart: number,
+ dynamicOffsetsDataLength: number,
+ ): undefined;
+
+ pushDebugGroup(groupLabel: string): undefined;
+ popDebugGroup(): undefined;
+ insertDebugMarker(markerLabel: string): undefined;
+}
+
+declare class GPUComputePassEncoder
+ implements GPUObjectBase, GPUProgrammablePassEncoder {
+ label: string | null;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsets?: number[],
+ ): undefined;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsetsData: Uint32Array,
+ dynamicOffsetsDataStart: number,
+ dynamicOffsetsDataLength: number,
+ ): undefined;
+ pushDebugGroup(groupLabel: string): undefined;
+ popDebugGroup(): undefined;
+ insertDebugMarker(markerLabel: string): undefined;
+ setPipeline(pipeline: GPUComputePipeline): undefined;
+ dispatch(x: number, y?: number, z?: number): undefined;
+ dispatchIndirect(
+ indirectBuffer: GPUBuffer,
+ indirectOffset: number,
+ ): undefined;
+
+ beginPipelineStatisticsQuery(
+ querySet: GPUQuerySet,
+ queryIndex: number,
+ ): undefined;
+ endPipelineStatisticsQuery(): undefined;
+
+ writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined;
+
+ endPass(): undefined;
+}
+
+declare interface GPUComputePassDescriptor extends GPUObjectDescriptorBase {}
+
+interface GPURenderEncoderBase {
+ setPipeline(pipeline: GPURenderPipeline): undefined;
+
+ setIndexBuffer(
+ buffer: GPUBuffer,
+ indexFormat: GPUIndexFormat,
+ offset?: number,
+ size?: number,
+ ): undefined;
+ setVertexBuffer(
+ slot: number,
+ buffer: GPUBuffer,
+ offset?: number,
+ size?: number,
+ ): undefined;
+
+ draw(
+ vertexCount: number,
+ instanceCount?: number,
+ firstVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+ drawIndexed(
+ indexCount: number,
+ instanceCount?: number,
+ firstIndex?: number,
+ baseVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+
+ drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined;
+ drawIndexedIndirect(
+ indirectBuffer: GPUBuffer,
+ indirectOffset: number,
+ ): undefined;
+}
+
+declare class GPURenderPassEncoder
+ implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase {
+ label: string | null;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsets?: number[],
+ ): undefined;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsetsData: Uint32Array,
+ dynamicOffsetsDataStart: number,
+ dynamicOffsetsDataLength: number,
+ ): undefined;
+ pushDebugGroup(groupLabel: string): undefined;
+ popDebugGroup(): undefined;
+ insertDebugMarker(markerLabel: string): undefined;
+ setPipeline(pipeline: GPURenderPipeline): undefined;
+ setIndexBuffer(
+ buffer: GPUBuffer,
+ indexFormat: GPUIndexFormat,
+ offset?: number,
+ size?: number,
+ ): undefined;
+ setVertexBuffer(
+ slot: number,
+ buffer: GPUBuffer,
+ offset?: number,
+ size?: number,
+ ): undefined;
+ draw(
+ vertexCount: number,
+ instanceCount?: number,
+ firstVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+ drawIndexed(
+ indexCount: number,
+ instanceCount?: number,
+ firstIndex?: number,
+ baseVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+ drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined;
+ drawIndexedIndirect(
+ indirectBuffer: GPUBuffer,
+ indirectOffset: number,
+ ): undefined;
+
+ setViewport(
+ x: number,
+ y: number,
+ width: number,
+ height: number,
+ minDepth: number,
+ maxDepth: number,
+ ): undefined;
+
+ setScissorRect(
+ x: number,
+ y: number,
+ width: number,
+ height: number,
+ ): undefined;
+
+ setBlendConstant(color: GPUColor): undefined;
+ setStencilReference(reference: number): undefined;
+
+ beginOcclusionQuery(queryIndex: number): undefined;
+ endOcclusionQuery(): undefined;
+
+ beginPipelineStatisticsQuery(
+ querySet: GPUQuerySet,
+ queryIndex: number,
+ ): undefined;
+ endPipelineStatisticsQuery(): undefined;
+
+ writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined;
+
+ executeBundles(bundles: GPURenderBundle[]): undefined;
+ endPass(): undefined;
+}
+
+declare interface GPURenderPassDescriptor extends GPUObjectDescriptorBase {
+ colorAttachments: GPURenderPassColorAttachment[];
+ depthStencilAttachment?: GPURenderPassDepthStencilAttachment;
+ occlusionQuerySet?: GPUQuerySet;
+}
+
+declare interface GPURenderPassColorAttachment {
+ view: GPUTextureView;
+ resolveTarget?: GPUTextureView;
+
+ loadValue: GPULoadOp | GPUColor;
+ storeOp?: GPUStoreOp;
+}
+
+declare interface GPURenderPassDepthStencilAttachment {
+ view: GPUTextureView;
+
+ depthLoadValue: GPULoadOp | number;
+ depthStoreOp: GPUStoreOp;
+ depthReadOnly?: boolean;
+
+ stencilLoadValue: GPULoadOp | number;
+ stencilStoreOp: GPUStoreOp;
+ stencilReadOnly?: boolean;
+}
+
+declare type GPULoadOp = "load";
+
+declare type GPUStoreOp = "store" | "discard";
+
+declare class GPURenderBundle implements GPUObjectBase {
+ label: string | null;
+}
+
+declare interface GPURenderBundleDescriptor extends GPUObjectDescriptorBase {}
+
+declare class GPURenderBundleEncoder
+ implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase {
+ label: string | null;
+ draw(
+ vertexCount: number,
+ instanceCount?: number,
+ firstVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+ drawIndexed(
+ indexCount: number,
+ instanceCount?: number,
+ firstIndex?: number,
+ baseVertex?: number,
+ firstInstance?: number,
+ ): undefined;
+ drawIndexedIndirect(
+ indirectBuffer: GPUBuffer,
+ indirectOffset: number,
+ ): undefined;
+ drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined;
+ insertDebugMarker(markerLabel: string): undefined;
+ popDebugGroup(): undefined;
+ pushDebugGroup(groupLabel: string): undefined;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsets?: number[],
+ ): undefined;
+ setBindGroup(
+ index: number,
+ bindGroup: GPUBindGroup,
+ dynamicOffsetsData: Uint32Array,
+ dynamicOffsetsDataStart: number,
+ dynamicOffsetsDataLength: number,
+ ): undefined;
+ setIndexBuffer(
+ buffer: GPUBuffer,
+ indexFormat: GPUIndexFormat,
+ offset?: number,
+ size?: number,
+ ): undefined;
+ setPipeline(pipeline: GPURenderPipeline): undefined;
+ setVertexBuffer(
+ slot: number,
+ buffer: GPUBuffer,
+ offset?: number,
+ size?: number,
+ ): undefined;
+
+ finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle;
+}
+
+declare interface GPURenderPassLayout extends GPUObjectDescriptorBase {
+ colorFormats: GPUTextureFormat[];
+ depthStencilFormat?: GPUTextureFormat;
+ sampleCount?: number;
+}
+
+declare interface GPURenderBundleEncoderDescriptor extends GPURenderPassLayout {
+ depthReadOnly?: boolean;
+ stencilReadOnly?: boolean;
+}
+
+declare class GPUQueue implements GPUObjectBase {
+ label: string | null;
+
+ submit(commandBuffers: GPUCommandBuffer[]): undefined;
+
+ onSubmittedWorkDone(): Promise<undefined>;
+
+ writeBuffer(
+ buffer: GPUBuffer,
+ bufferOffset: number,
+ data: BufferSource,
+ dataOffset?: number,
+ size?: number,
+ ): undefined;
+
+ writeTexture(
+ destination: GPUImageCopyTexture,
+ data: BufferSource,
+ dataLayout: GPUImageDataLayout,
+ size: GPUExtent3D,
+ ): undefined;
+}
+
+declare class GPUQuerySet implements GPUObjectBase {
+ label: string | null;
+
+ destroy(): undefined;
+}
+
+declare interface GPUQuerySetDescriptor extends GPUObjectDescriptorBase {
+ type: GPUQueryType;
+ count: number;
+ pipelineStatistics?: GPUPipelineStatisticName[];
+}
+
+declare type GPUQueryType = "occlusion" | "pipeline-statistics" | "timestamp";
+
+declare type GPUPipelineStatisticName =
+ | "vertex-shader-invocations"
+ | "clipper-invocations"
+ | "clipper-primitives-out"
+ | "fragment-shader-invocations"
+ | "compute-shader-invocations";
+
+declare type GPUDeviceLostReason = "destroyed";
+
+declare interface GPUDeviceLostInfo {
+ readonly reason: GPUDeviceLostReason | undefined;
+ readonly message: string;
+}
+
+declare type GPUErrorFilter = "out-of-memory" | "validation";
+
+declare class GPUOutOfMemoryError {
+ constructor();
+}
+
+declare class GPUValidationError {
+ constructor(message: string);
+ readonly message: string;
+}
+
+declare type GPUError = GPUOutOfMemoryError | GPUValidationError;
+
+declare class GPUUncapturedErrorEvent extends Event {
+ constructor(
+ type: string,
+ gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit,
+ );
+ readonly error: GPUError;
+}
+
+declare interface GPUUncapturedErrorEventInit extends EventInit {
+ error?: GPUError;
+}
+
+declare interface GPUColorDict {
+ r: number;
+ g: number;
+ b: number;
+ a: number;
+}
+
+declare type GPUColor = number[] | GPUColorDict;
+
+declare interface GPUOrigin3DDict {
+ x?: number;
+ y?: number;
+ z?: number;
+}
+
+declare type GPUOrigin3D = number[] | GPUOrigin3DDict;
+
+declare interface GPUExtent3DDict {
+ width: number;
+ height?: number;
+ depthOrArrayLayers?: number;
+}
+
+declare type GPUExtent3D = number[] | GPUExtent3DDict;
diff --git a/ext/webgpu/src/lib.rs b/ext/webgpu/lib.rs
index 77bb10a60..81f84f6bf 100644
--- a/ext/webgpu/src/lib.rs
+++ b/ext/webgpu/lib.rs
@@ -14,6 +14,7 @@ use serde::Serialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashSet;
+use std::path::PathBuf;
use std::rc::Rc;
pub use wgpu_core;
pub use wgpu_types;
@@ -124,11 +125,15 @@ pub fn init(unstable: bool) -> Extension {
.build()
}
+pub fn get_declaration() -> PathBuf {
+ PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webgpu.d.ts")
+}
+
fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
let mut return_features: Vec<&'static str> = vec![];
- if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) {
- return_features.push("depth-clip-control");
+ if features.contains(wgpu_types::Features::DEPTH_CLAMPING) {
+ return_features.push("depth-clamping");
}
if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) {
return_features.push("pipeline-statistics-query");
@@ -136,18 +141,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) {
return_features.push("texture-compression-bc");
}
- if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) {
- return_features.push("texture-compression-etc2");
- }
- if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) {
- return_features.push("texture-compression-astc");
- }
if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) {
return_features.push("timestamp-query");
}
- if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) {
- return_features.push("indirect-first-instance");
- }
// extended from spec
if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) {
@@ -162,16 +158,12 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) {
return_features.push("storage-resource-binding-array");
}
- if features.contains(
- wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
- ) {
- return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing");
- }
- if features.contains(
- wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
- ) {
- return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing");
- }
+ if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING) {
+ return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing");
+ }
+ if features.contains(wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) {
+ return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing");
+ }
if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) {
return_features.push("unsized-binding-array");
}
@@ -187,6 +179,15 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) {
return_features.push("address-mode-clamp-to-border");
}
+ if features.contains(wgpu_types::Features::NON_FILL_POLYGON_MODE) {
+ return_features.push("non-fill-polygon-mode");
+ }
+ if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) {
+ return_features.push("texture-compression-etc2");
+ }
+ if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) {
+ return_features.push("texture-compression-astc-ldr");
+ }
if features
.contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES)
{
@@ -204,8 +205,8 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) {
return_features.push("vertex-writable-storage");
}
- if features.contains(wgpu_types::Features::CLEAR_TEXTURE) {
- return_features.push("clear-texture");
+ if features.contains(wgpu_types::Features::CLEAR_COMMANDS) {
+ return_features.push("clear-commands");
}
if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) {
return_features.push("spirv-shader-passthrough");
@@ -218,10 +219,27 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
}
#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+enum GpuPowerPreference {
+ LowPower,
+ HighPerformance,
+}
+
+impl From<GpuPowerPreference> for wgpu_types::PowerPreference {
+ fn from(value: GpuPowerPreference) -> wgpu_types::PowerPreference {
+ match value {
+ GpuPowerPreference::LowPower => wgpu_types::PowerPreference::LowPower,
+ GpuPowerPreference::HighPerformance => {
+ wgpu_types::PowerPreference::HighPerformance
+ }
+ }
+ }
+}
+
+#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestAdapterArgs {
- power_preference: Option<wgpu_types::PowerPreference>,
- force_fallback_adapter: bool,
+ power_preference: Option<GpuPowerPreference>,
}
#[derive(Serialize)]
@@ -248,35 +266,31 @@ pub async fn op_webgpu_request_adapter(
) -> Result<GpuAdapterDeviceOrErr, AnyError> {
let mut state = state.borrow_mut();
check_unstable(&state, "navigator.gpu.requestAdapter");
- let backends = std::env::var("DENO_WEBGPU_BACKEND")
- .ok()
- .map_or_else(wgpu_types::Backends::all, |s| {
- wgpu_core::instance::parse_backends_from_comma_list(&s)
- });
let instance = if let Some(instance) = state.try_borrow::<Instance>() {
instance
} else {
state.put(wgpu_core::hub::Global::new(
"webgpu",
wgpu_core::hub::IdentityManagerFactory,
- backends,
+ wgpu_types::Backends::PRIMARY,
));
state.borrow::<Instance>()
};
let descriptor = wgpu_core::instance::RequestAdapterOptions {
power_preference: match args.power_preference {
- Some(power_preference) => power_preference,
+ Some(power_preference) => power_preference.into(),
None => PowerPreference::default(),
},
- force_fallback_adapter: args.force_fallback_adapter,
+ // TODO(lucacasonato): respect forceFallbackAdapter
compatible_surface: None, // windowless
};
let res = instance.request_adapter(
&descriptor,
- wgpu_core::instance::AdapterInputs::Mask(backends, |_| {
- std::marker::PhantomData
- }),
+ wgpu_core::instance::AdapterInputs::Mask(
+ wgpu_types::Backends::PRIMARY,
+ |_| std::marker::PhantomData,
+ ),
);
let adapter = match res {
@@ -307,11 +321,114 @@ pub async fn op_webgpu_request_adapter(
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
+struct GpuLimits {
+ max_texture_dimension_1d: Option<u32>,
+ max_texture_dimension_2d: Option<u32>,
+ max_texture_dimension_3d: Option<u32>,
+ max_texture_array_layers: Option<u32>,
+ max_bind_groups: Option<u32>,
+ max_dynamic_uniform_buffers_per_pipeline_layout: Option<u32>,
+ max_dynamic_storage_buffers_per_pipeline_layout: Option<u32>,
+ max_sampled_textures_per_shader_stage: Option<u32>,
+ max_samplers_per_shader_stage: Option<u32>,
+ max_storage_buffers_per_shader_stage: Option<u32>,
+ max_storage_textures_per_shader_stage: Option<u32>,
+ max_uniform_buffers_per_shader_stage: Option<u32>,
+ max_uniform_buffer_binding_size: Option<u32>, // TODO(@crowlkats): u64
+ max_storage_buffer_binding_size: Option<u32>, // TODO(@crowlkats): u64
+ // min_uniform_buffer_offset_alignment: Option<u32>,
+ // min_storage_buffer_offset_alignment: Option<u32>,
+ max_vertex_buffers: Option<u32>,
+ max_vertex_attributes: Option<u32>,
+ max_vertex_buffer_array_stride: Option<u32>,
+ // max_inter_stage_shader_components: Option<u32>,
+ // max_compute_workgroup_storage_size: Option<u32>,
+ // max_compute_invocations_per_workgroup: Option<u32>,
+ // max_compute_workgroup_size_x: Option<u32>,
+ // max_compute_workgroup_size_y: Option<u32>,
+ // max_compute_workgroup_size_z: Option<u32>,
+ // max_compute_workgroups_per_dimension: Option<u32>,
+}
+
+impl From<GpuLimits> for wgpu_types::Limits {
+ fn from(limits: GpuLimits) -> wgpu_types::Limits {
+ wgpu_types::Limits {
+ max_texture_dimension_1d: limits.max_texture_dimension_1d.unwrap_or(8192),
+ max_texture_dimension_2d: limits.max_texture_dimension_2d.unwrap_or(8192),
+ max_texture_dimension_3d: limits.max_texture_dimension_3d.unwrap_or(2048),
+ max_texture_array_layers: limits.max_texture_array_layers.unwrap_or(2048),
+ max_bind_groups: limits.max_bind_groups.unwrap_or(4),
+ max_dynamic_uniform_buffers_per_pipeline_layout: limits
+ .max_dynamic_uniform_buffers_per_pipeline_layout
+ .unwrap_or(8),
+ max_dynamic_storage_buffers_per_pipeline_layout: limits
+ .max_dynamic_storage_buffers_per_pipeline_layout
+ .unwrap_or(4),
+ max_sampled_textures_per_shader_stage: limits
+ .max_sampled_textures_per_shader_stage
+ .unwrap_or(16),
+ max_samplers_per_shader_stage: limits
+ .max_samplers_per_shader_stage
+ .unwrap_or(16),
+ max_storage_buffers_per_shader_stage: limits
+ .max_storage_buffers_per_shader_stage
+ .unwrap_or(4),
+ max_storage_textures_per_shader_stage: limits
+ .max_storage_textures_per_shader_stage
+ .unwrap_or(4),
+ max_uniform_buffers_per_shader_stage: limits
+ .max_uniform_buffers_per_shader_stage
+ .unwrap_or(12),
+ max_uniform_buffer_binding_size: limits
+ .max_uniform_buffer_binding_size
+ .unwrap_or(16384),
+ max_storage_buffer_binding_size: limits
+ .max_storage_buffer_binding_size
+ .unwrap_or(134217728),
+ // min_uniform_buffer_offset_alignment: limits
+ // .min_uniform_buffer_offset_alignment
+ // .unwrap_or(default),
+ // min_storage_buffer_offset_alignment: limits
+ // .min_storage_buffer_offset_alignment
+ // .unwrap_or(default),
+ max_vertex_buffers: limits.max_vertex_buffers.unwrap_or(8),
+ max_vertex_attributes: limits.max_vertex_attributes.unwrap_or(16),
+ max_vertex_buffer_array_stride: limits
+ .max_vertex_buffer_array_stride
+ .unwrap_or(2048),
+ // max_inter_stage_shader_components: limits
+ // .max_inter_stage_shader_components
+ // .unwrap_or(default),
+ // max_compute_workgroup_storage_size: limits
+ // .max_compute_workgroup_storage_size
+ // .unwrap_or(default),
+ // max_compute_invocations_per_workgroup: limits
+ // .max_compute_invocations_per_workgroup
+ // .unwrap_or(default),
+ // max_compute_workgroup_size_x: limits
+ // .max_compute_workgroup_size_x
+ // .unwrap_or(default),
+ // max_compute_workgroup_size_y: limits
+ // .max_compute_workgroup_size_y
+ // .unwrap_or(default),
+ // max_compute_workgroup_size_z: limits
+ // .max_compute_workgroup_size_z
+ // .unwrap_or(default),
+ // max_compute_workgroups_per_dimension: limits
+ // .max_compute_workgroups_per_dimension
+ // .unwrap_or(default),
+ max_push_constant_size: 0,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
pub struct RequestDeviceArgs {
adapter_rid: ResourceId,
label: Option<String>,
required_features: Option<GpuRequiredFeatures>,
- required_limits: Option<wgpu_types::Limits>,
+ required_limits: Option<GpuLimits>,
}
#[derive(Deserialize)]
@@ -320,120 +437,101 @@ pub struct GpuRequiredFeatures(HashSet<String>);
impl From<GpuRequiredFeatures> for wgpu_types::Features {
fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features {
let mut features: wgpu_types::Features = wgpu_types::Features::empty();
- features.set(
- wgpu_types::Features::DEPTH_CLIP_CONTROL,
- required_features.0.contains("depth-clip-control"),
- );
- features.set(
- wgpu_types::Features::PIPELINE_STATISTICS_QUERY,
- required_features.0.contains("pipeline-statistics-query"),
- );
- features.set(
- wgpu_types::Features::TEXTURE_COMPRESSION_BC,
- required_features.0.contains("texture-compression-bc"),
- );
- features.set(
- wgpu_types::Features::TEXTURE_COMPRESSION_ETC2,
- required_features.0.contains("texture-compression-etc2"),
- );
- features.set(
- wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR,
- required_features.0.contains("texture-compression-astc"),
- );
- features.set(
- wgpu_types::Features::TIMESTAMP_QUERY,
- required_features.0.contains("timestamp-query"),
- );
- features.set(
- wgpu_types::Features::INDIRECT_FIRST_INSTANCE,
- required_features.0.contains("indirect-first-instance"),
- );
+
+ if required_features.0.contains("depth-clamping") {
+ features.set(wgpu_types::Features::DEPTH_CLAMPING, true);
+ }
+ if required_features.0.contains("pipeline-statistics-query") {
+ features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true);
+ }
+ if required_features.0.contains("texture-compression-bc") {
+ features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true);
+ }
+ if required_features.0.contains("timestamp-query") {
+ features.set(wgpu_types::Features::TIMESTAMP_QUERY, true);
+ }
// extended from spec
- features.set(
- wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS,
- required_features.0.contains("mappable-primary-buffers"),
- );
- features.set(
- wgpu_types::Features::TEXTURE_BINDING_ARRAY,
- required_features.0.contains("texture-binding-array"),
- );
- features.set(
- wgpu_types::Features::BUFFER_BINDING_ARRAY,
- required_features.0.contains("buffer-binding-array"),
- );
- features.set(
- wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY,
- required_features
- .0
- .contains("storage-resource-binding-array"),
- );
- features.set(
- wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
- required_features
- .0
- .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"),
- );
- features.set(
- wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
- required_features
- .0
- .contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"),
- );
- features.set(
- wgpu_types::Features::UNSIZED_BINDING_ARRAY,
- required_features.0.contains("unsized-binding-array"),
- );
- features.set(
- wgpu_types::Features::MULTI_DRAW_INDIRECT,
- required_features.0.contains("multi-draw-indirect"),
- );
- features.set(
- wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT,
- required_features.0.contains("multi-draw-indirect-count"),
- );
- features.set(
- wgpu_types::Features::PUSH_CONSTANTS,
- required_features.0.contains("push-constants"),
- );
- features.set(
- wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
- required_features.0.contains("address-mode-clamp-to-border"),
- );
- features.set(
- wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
- required_features
- .0
- .contains("texture-adapter-specific-format-features"),
- );
- features.set(
- wgpu_types::Features::SHADER_FLOAT64,
- required_features.0.contains("shader-float64"),
- );
- features.set(
- wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT,
- required_features.0.contains("vertex-attribute-64bit"),
- );
- features.set(
- wgpu_types::Features::CONSERVATIVE_RASTERIZATION,
- required_features.0.contains("conservative-rasterization"),
- );
- features.set(
- wgpu_types::Features::VERTEX_WRITABLE_STORAGE,
- required_features.0.contains("vertex-writable-storage"),
- );
- features.set(
- wgpu_types::Features::CLEAR_TEXTURE,
- required_features.0.contains("clear-commands"),
- );
- features.set(
- wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH,
- required_features.0.contains("spirv-shader-passthrough"),
- );
- features.set(
- wgpu_types::Features::SHADER_PRIMITIVE_INDEX,
- required_features.0.contains("shader-primitive-index"),
- );
+ if required_features.0.contains("mappable-primary-buffers") {
+ features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true);
+ }
+ if required_features.0.contains("texture-binding-array") {
+ features.set(wgpu_types::Features::TEXTURE_BINDING_ARRAY, true);
+ }
+ if required_features.0.contains("buffer-binding-array") {
+ features.set(wgpu_types::Features::BUFFER_BINDING_ARRAY, true);
+ }
+ if required_features
+ .0
+ .contains("storage-resource-binding-array")
+ {
+ features.set(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, true);
+ }
+ if required_features
+ .0
+ .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing")
+ {
+ features.set(wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, true);
+ }
+ if required_features.0.contains(
+ "uniform-buffer-and-storage-buffer-texture-non-uniform-indexing",
+ ) {
+ features.set(wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, true);
+ }
+ if required_features.0.contains("unsized-binding-array") {
+ features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true);
+ }
+ if required_features.0.contains("multi-draw-indirect") {
+ features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, true);
+ }
+ if required_features.0.contains("multi-draw-indirect-count") {
+ features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, true);
+ }
+ if required_features.0.contains("push-constants") {
+ features.set(wgpu_types::Features::PUSH_CONSTANTS, true);
+ }
+ if required_features.0.contains("address-mode-clamp-to-border") {
+ features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true);
+ }
+ if required_features.0.contains("non-fill-polygon-mode") {
+ features.set(wgpu_types::Features::NON_FILL_POLYGON_MODE, true);
+ }
+ if required_features.0.contains("texture-compression-etc2") {
+ features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, true);
+ }
+ if required_features.0.contains("texture-compression-astc-ldr") {
+ features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true);
+ }
+ if required_features
+ .0
+ .contains("texture-adapter-specific-format-features")
+ {
+ features.set(
+ wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
+ true,
+ );
+ }
+ if required_features.0.contains("shader-float64") {
+ features.set(wgpu_types::Features::SHADER_FLOAT64, true);
+ }
+ if required_features.0.contains("vertex-attribute-64bit") {
+ features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, true);
+ }
+ if required_features.0.contains("conservative-rasterization") {
+ features.set(wgpu_types::Features::CONSERVATIVE_RASTERIZATION, true);
+ }
+ if required_features.0.contains("vertex-writable-storage") {
+ features.set(wgpu_types::Features::VERTEX_WRITABLE_STORAGE, true);
+ }
+ if required_features.0.contains("clear-commands") {
+ features.set(wgpu_types::Features::CLEAR_COMMANDS, true);
+ }
+ if required_features.0.contains("spirv-shader-passthrough") {
+ features.set(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, true);
+ }
+ if required_features.0.contains("shader-primitive-index") {
+ features.set(wgpu_types::Features::SHADER_PRIMITIVE_INDEX, true);
+ }
features
}
@@ -678,10 +776,6 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
),
),
(
- "op_webgpu_command_encoder_clear_buffer",
- op_sync(command_encoder::op_webgpu_command_encoder_clear_buffer),
- ),
- (
"op_webgpu_command_encoder_push_debug_group",
op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group),
),
@@ -802,22 +896,6 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect),
),
(
- "op_webgpu_compute_pass_begin_pipeline_statistics_query",
- op_sync(
- compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query,
- ),
- ),
- (
- "op_webgpu_compute_pass_end_pipeline_statistics_query",
- op_sync(
- compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query,
- ),
- ),
- (
- "op_webgpu_compute_pass_write_timestamp",
- op_sync(compute_pass::op_webgpu_compute_pass_write_timestamp),
- ),
- (
"op_webgpu_compute_pass_end_pass",
op_sync(compute_pass::op_webgpu_compute_pass_end_pass),
),
diff --git a/ext/webgpu/pipeline.rs b/ext/webgpu/pipeline.rs
new file mode 100644
index 000000000..1d22bdba0
--- /dev/null
+++ b/ext/webgpu/pipeline.rs
@@ -0,0 +1,791 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::AnyError;
+use deno_core::ResourceId;
+use deno_core::{OpState, Resource};
+use serde::Deserialize;
+use serde::Serialize;
+use std::borrow::Cow;
+
+use crate::sampler::GpuCompareFunction;
+use crate::texture::GpuTextureFormat;
+
+use super::error::{WebGpuError, WebGpuResult};
+
+const MAX_BIND_GROUPS: usize = 8;
+
+pub(crate) struct WebGpuPipelineLayout(
+ pub(crate) wgpu_core::id::PipelineLayoutId,
+);
+impl Resource for WebGpuPipelineLayout {
+ fn name(&self) -> Cow<str> {
+ "webGPUPipelineLayout".into()
+ }
+}
+
+pub(crate) struct WebGpuComputePipeline(
+ pub(crate) wgpu_core::id::ComputePipelineId,
+);
+impl Resource for WebGpuComputePipeline {
+ fn name(&self) -> Cow<str> {
+ "webGPUComputePipeline".into()
+ }
+}
+
+pub(crate) struct WebGpuRenderPipeline(
+ pub(crate) wgpu_core::id::RenderPipelineId,
+);
+impl Resource for WebGpuRenderPipeline {
+ fn name(&self) -> Cow<str> {
+ "webGPURenderPipeline".into()
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuIndexFormat {
+ Uint16,
+ Uint32,
+}
+
+impl From<GpuIndexFormat> for wgpu_types::IndexFormat {
+ fn from(value: GpuIndexFormat) -> wgpu_types::IndexFormat {
+ match value {
+ GpuIndexFormat::Uint16 => wgpu_types::IndexFormat::Uint16,
+ GpuIndexFormat::Uint32 => wgpu_types::IndexFormat::Uint32,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GPUStencilOperation {
+ Keep,
+ Zero,
+ Replace,
+ Invert,
+ IncrementClamp,
+ DecrementClamp,
+ IncrementWrap,
+ DecrementWrap,
+}
+
+impl From<GPUStencilOperation> for wgpu_types::StencilOperation {
+ fn from(value: GPUStencilOperation) -> wgpu_types::StencilOperation {
+ match value {
+ GPUStencilOperation::Keep => wgpu_types::StencilOperation::Keep,
+ GPUStencilOperation::Zero => wgpu_types::StencilOperation::Zero,
+ GPUStencilOperation::Replace => wgpu_types::StencilOperation::Replace,
+ GPUStencilOperation::Invert => wgpu_types::StencilOperation::Invert,
+ GPUStencilOperation::IncrementClamp => {
+ wgpu_types::StencilOperation::IncrementClamp
+ }
+ GPUStencilOperation::DecrementClamp => {
+ wgpu_types::StencilOperation::DecrementClamp
+ }
+ GPUStencilOperation::IncrementWrap => {
+ wgpu_types::StencilOperation::IncrementWrap
+ }
+ GPUStencilOperation::DecrementWrap => {
+ wgpu_types::StencilOperation::DecrementWrap
+ }
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuBlendFactor {
+ Zero,
+ One,
+ Src,
+ OneMinusSrc,
+ SrcAlpha,
+ OneMinusSrcAlpha,
+ Dst,
+ OneMinusDst,
+ DstAlpha,
+ OneMinusDstAlpha,
+ SrcAlphaSaturated,
+ Constant,
+ OneMinusConstant,
+}
+
+impl From<GpuBlendFactor> for wgpu_types::BlendFactor {
+ fn from(value: GpuBlendFactor) -> wgpu_types::BlendFactor {
+ match value {
+ GpuBlendFactor::Zero => wgpu_types::BlendFactor::Zero,
+ GpuBlendFactor::One => wgpu_types::BlendFactor::One,
+ GpuBlendFactor::Src => wgpu_types::BlendFactor::Src,
+ GpuBlendFactor::OneMinusSrc => wgpu_types::BlendFactor::OneMinusSrc,
+ GpuBlendFactor::SrcAlpha => wgpu_types::BlendFactor::SrcAlpha,
+ GpuBlendFactor::OneMinusSrcAlpha => {
+ wgpu_types::BlendFactor::OneMinusSrcAlpha
+ }
+ GpuBlendFactor::Dst => wgpu_types::BlendFactor::Dst,
+ GpuBlendFactor::OneMinusDst => wgpu_types::BlendFactor::OneMinusDst,
+ GpuBlendFactor::DstAlpha => wgpu_types::BlendFactor::DstAlpha,
+ GpuBlendFactor::OneMinusDstAlpha => {
+ wgpu_types::BlendFactor::OneMinusDstAlpha
+ }
+ GpuBlendFactor::SrcAlphaSaturated => {
+ wgpu_types::BlendFactor::SrcAlphaSaturated
+ }
+ GpuBlendFactor::Constant => wgpu_types::BlendFactor::Constant,
+ GpuBlendFactor::OneMinusConstant => {
+ wgpu_types::BlendFactor::OneMinusConstant
+ }
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuBlendOperation {
+ Add,
+ Subtract,
+ ReverseSubtract,
+ Min,
+ Max,
+}
+
+impl From<GpuBlendOperation> for wgpu_types::BlendOperation {
+ fn from(value: GpuBlendOperation) -> wgpu_types::BlendOperation {
+ match value {
+ GpuBlendOperation::Add => wgpu_types::BlendOperation::Add,
+ GpuBlendOperation::Subtract => wgpu_types::BlendOperation::Subtract,
+ GpuBlendOperation::ReverseSubtract => {
+ wgpu_types::BlendOperation::ReverseSubtract
+ }
+ GpuBlendOperation::Min => wgpu_types::BlendOperation::Min,
+ GpuBlendOperation::Max => wgpu_types::BlendOperation::Max,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuPrimitiveTopology {
+ PointList,
+ LineList,
+ LineStrip,
+ TriangleList,
+ TriangleStrip,
+}
+
+impl From<GpuPrimitiveTopology> for wgpu_types::PrimitiveTopology {
+ fn from(value: GpuPrimitiveTopology) -> wgpu_types::PrimitiveTopology {
+ match value {
+ GpuPrimitiveTopology::PointList => {
+ wgpu_types::PrimitiveTopology::PointList
+ }
+ GpuPrimitiveTopology::LineList => wgpu_types::PrimitiveTopology::LineList,
+ GpuPrimitiveTopology::LineStrip => {
+ wgpu_types::PrimitiveTopology::LineStrip
+ }
+ GpuPrimitiveTopology::TriangleList => {
+ wgpu_types::PrimitiveTopology::TriangleList
+ }
+ GpuPrimitiveTopology::TriangleStrip => {
+ wgpu_types::PrimitiveTopology::TriangleStrip
+ }
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuFrontFace {
+ Ccw,
+ Cw,
+}
+
+impl From<GpuFrontFace> for wgpu_types::FrontFace {
+ fn from(value: GpuFrontFace) -> wgpu_types::FrontFace {
+ match value {
+ GpuFrontFace::Ccw => wgpu_types::FrontFace::Ccw,
+ GpuFrontFace::Cw => wgpu_types::FrontFace::Cw,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuCullMode {
+ None,
+ Front,
+ Back,
+}
+
+impl From<GpuCullMode> for Option<wgpu_types::Face> {
+ fn from(value: GpuCullMode) -> Option<wgpu_types::Face> {
+ match value {
+ GpuCullMode::None => None,
+ GpuCullMode::Front => Some(wgpu_types::Face::Front),
+ GpuCullMode::Back => Some(wgpu_types::Face::Back),
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuProgrammableStage {
+ module: ResourceId,
+ entry_point: String,
+ // constants: HashMap<String, GPUPipelineConstantValue>
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateComputePipelineArgs {
+ device_rid: ResourceId,
+ label: Option<String>,
+ layout: Option<ResourceId>,
+ compute: GpuProgrammableStage,
+}
+
+pub fn op_webgpu_create_compute_pipeline(
+ state: &mut OpState,
+ args: CreateComputePipelineArgs,
+ _: (),
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(args.device_rid)?;
+ let device = device_resource.0;
+
+ let pipeline_layout = if let Some(rid) = args.layout {
+ let id = state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
+ Some(id.0)
+ } else {
+ None
+ };
+
+ let compute_shader_module_resource =
+ state
+ .resource_table
+ .get::<super::shader::WebGpuShaderModule>(args.compute.module)?;
+
+ let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor {
+ label: args.label.map(Cow::from),
+ layout: pipeline_layout,
+ stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
+ module: compute_shader_module_resource.0,
+ entry_point: Cow::from(args.compute.entry_point),
+ // TODO(lucacasonato): support args.compute.constants
+ },
+ };
+ let implicit_pipelines = match args.layout {
+ Some(_) => None,
+ None => Some(wgpu_core::device::ImplicitPipelineIds {
+ root_id: std::marker::PhantomData,
+ group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS],
+ }),
+ };
+
+ let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline(
+ device,
+ &descriptor,
+ std::marker::PhantomData,
+ implicit_pipelines
+ ));
+
+ let rid = state
+ .resource_table
+ .add(WebGpuComputePipeline(compute_pipeline));
+
+ Ok(WebGpuResult::rid_err(rid, maybe_err))
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ComputePipelineGetBindGroupLayoutArgs {
+ compute_pipeline_rid: ResourceId,
+ index: u32,
+}
+
+#[derive(Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PipelineLayout {
+ rid: ResourceId,
+ label: String,
+ err: Option<WebGpuError>,
+}
+
+pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
+ state: &mut OpState,
+ args: ComputePipelineGetBindGroupLayoutArgs,
+ _: (),
+) -> Result<PipelineLayout, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let compute_pipeline_resource = state
+ .resource_table
+ .get::<WebGpuComputePipeline>(args.compute_pipeline_rid)?;
+ let compute_pipeline = compute_pipeline_resource.0;
+
+ let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData));
+
+ let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));
+
+ let rid = state
+ .resource_table
+ .add(super::binding::WebGpuBindGroupLayout(bind_group_layout));
+
+ Ok(PipelineLayout {
+ rid,
+ label,
+ err: maybe_err.map(WebGpuError::from),
+ })
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuPrimitiveState {
+ topology: GpuPrimitiveTopology,
+ strip_index_format: Option<GpuIndexFormat>,
+ front_face: GpuFrontFace,
+ cull_mode: GpuCullMode,
+ clamp_depth: bool,
+}
+
+impl From<GpuPrimitiveState> for wgpu_types::PrimitiveState {
+ fn from(value: GpuPrimitiveState) -> wgpu_types::PrimitiveState {
+ wgpu_types::PrimitiveState {
+ topology: value.topology.into(),
+ strip_index_format: value.strip_index_format.map(Into::into),
+ front_face: value.front_face.into(),
+ cull_mode: value.cull_mode.into(),
+ clamp_depth: value.clamp_depth,
+ polygon_mode: Default::default(), // native-only
+ conservative: false, // native-only
+ }
+ }
+}
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuBlendComponent {
+ src_factor: GpuBlendFactor,
+ dst_factor: GpuBlendFactor,
+ operation: GpuBlendOperation,
+}
+
+impl From<GpuBlendComponent> for wgpu_types::BlendComponent {
+ fn from(component: GpuBlendComponent) -> Self {
+ wgpu_types::BlendComponent {
+ src_factor: component.src_factor.into(),
+ dst_factor: component.dst_factor.into(),
+ operation: component.operation.into(),
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuBlendState {
+ color: GpuBlendComponent,
+ alpha: GpuBlendComponent,
+}
+
+impl From<GpuBlendState> for wgpu_types::BlendState {
+ fn from(state: GpuBlendState) -> wgpu_types::BlendState {
+ wgpu_types::BlendState {
+ color: state.color.into(),
+ alpha: state.alpha.into(),
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuColorTargetState {
+ format: GpuTextureFormat,
+ blend: Option<GpuBlendState>,
+ write_mask: u32,
+}
+
+impl TryFrom<GpuColorTargetState> for wgpu_types::ColorTargetState {
+ type Error = AnyError;
+ fn try_from(
+ state: GpuColorTargetState,
+ ) -> Result<wgpu_types::ColorTargetState, AnyError> {
+ Ok(wgpu_types::ColorTargetState {
+ format: state.format.try_into()?,
+ blend: state.blend.map(Into::into),
+ write_mask: wgpu_types::ColorWrites::from_bits_truncate(state.write_mask),
+ })
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuStencilFaceState {
+ compare: GpuCompareFunction,
+ fail_op: GPUStencilOperation,
+ depth_fail_op: GPUStencilOperation,
+ pass_op: GPUStencilOperation,
+}
+
+impl From<GpuStencilFaceState> for wgpu_types::StencilFaceState {
+ fn from(state: GpuStencilFaceState) -> Self {
+ wgpu_types::StencilFaceState {
+ compare: state.compare.into(),
+ fail_op: state.fail_op.into(),
+ depth_fail_op: state.depth_fail_op.into(),
+ pass_op: state.pass_op.into(),
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuDepthStencilState {
+ format: GpuTextureFormat,
+ depth_write_enabled: bool,
+ depth_compare: GpuCompareFunction,
+ stencil_front: GpuStencilFaceState,
+ stencil_back: GpuStencilFaceState,
+ stencil_read_mask: u32,
+ stencil_write_mask: u32,
+ depth_bias: i32,
+ depth_bias_slope_scale: f32,
+ depth_bias_clamp: f32,
+}
+
+impl TryFrom<GpuDepthStencilState> for wgpu_types::DepthStencilState {
+ type Error = AnyError;
+ fn try_from(
+ state: GpuDepthStencilState,
+ ) -> Result<wgpu_types::DepthStencilState, AnyError> {
+ Ok(wgpu_types::DepthStencilState {
+ format: state.format.try_into()?,
+ depth_write_enabled: state.depth_write_enabled,
+ depth_compare: state.depth_compare.into(),
+ stencil: wgpu_types::StencilState {
+ front: state.stencil_front.into(),
+ back: state.stencil_back.into(),
+ read_mask: state.stencil_read_mask,
+ write_mask: state.stencil_write_mask,
+ },
+ bias: wgpu_types::DepthBiasState {
+ constant: state.depth_bias,
+ slope_scale: state.depth_bias_slope_scale,
+ clamp: state.depth_bias_clamp,
+ },
+ })
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuVertexAttribute {
+ format: GpuVertexFormat,
+ offset: u64,
+ shader_location: u32,
+}
+
+impl From<GpuVertexAttribute> for wgpu_types::VertexAttribute {
+ fn from(attribute: GpuVertexAttribute) -> Self {
+ wgpu_types::VertexAttribute {
+ format: attribute.format.into(),
+ offset: attribute.offset,
+ shader_location: attribute.shader_location,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "lowercase")]
+enum GpuVertexFormat {
+ Uint8x2,
+ Uint8x4,
+ Sint8x2,
+ Sint8x4,
+ Unorm8x2,
+ Unorm8x4,
+ Snorm8x2,
+ Snorm8x4,
+ Uint16x2,
+ Uint16x4,
+ Sint16x2,
+ Sint16x4,
+ Unorm16x2,
+ Unorm16x4,
+ Snorm16x2,
+ Snorm16x4,
+ Float16x2,
+ Float16x4,
+ Float32,
+ Float32x2,
+ Float32x3,
+ Float32x4,
+ Uint32,
+ Uint32x2,
+ Uint32x3,
+ Uint32x4,
+ Sint32,
+ Sint32x2,
+ Sint32x3,
+ Sint32x4,
+ Float64,
+ Float64x2,
+ Float64x3,
+ Float64x4,
+}
+
+impl From<GpuVertexFormat> for wgpu_types::VertexFormat {
+ fn from(vf: GpuVertexFormat) -> wgpu_types::VertexFormat {
+ use wgpu_types::VertexFormat;
+ match vf {
+ GpuVertexFormat::Uint8x2 => VertexFormat::Uint8x2,
+ GpuVertexFormat::Uint8x4 => VertexFormat::Uint8x4,
+ GpuVertexFormat::Sint8x2 => VertexFormat::Sint8x2,
+ GpuVertexFormat::Sint8x4 => VertexFormat::Sint8x4,
+ GpuVertexFormat::Unorm8x2 => VertexFormat::Unorm8x2,
+ GpuVertexFormat::Unorm8x4 => VertexFormat::Unorm8x4,
+ GpuVertexFormat::Snorm8x2 => VertexFormat::Snorm8x2,
+ GpuVertexFormat::Snorm8x4 => VertexFormat::Snorm8x4,
+ GpuVertexFormat::Uint16x2 => VertexFormat::Uint16x2,
+ GpuVertexFormat::Uint16x4 => VertexFormat::Uint16x4,
+ GpuVertexFormat::Sint16x2 => VertexFormat::Sint16x2,
+ GpuVertexFormat::Sint16x4 => VertexFormat::Sint16x4,
+ GpuVertexFormat::Unorm16x2 => VertexFormat::Unorm16x2,
+ GpuVertexFormat::Unorm16x4 => VertexFormat::Unorm16x4,
+ GpuVertexFormat::Snorm16x2 => VertexFormat::Snorm16x2,
+ GpuVertexFormat::Snorm16x4 => VertexFormat::Snorm16x4,
+ GpuVertexFormat::Float16x2 => VertexFormat::Float16x2,
+ GpuVertexFormat::Float16x4 => VertexFormat::Float16x4,
+ GpuVertexFormat::Float32 => VertexFormat::Float32,
+ GpuVertexFormat::Float32x2 => VertexFormat::Float32x2,
+ GpuVertexFormat::Float32x3 => VertexFormat::Float32x3,
+ GpuVertexFormat::Float32x4 => VertexFormat::Float32x4,
+ GpuVertexFormat::Uint32 => VertexFormat::Uint32,
+ GpuVertexFormat::Uint32x2 => VertexFormat::Uint32x2,
+ GpuVertexFormat::Uint32x3 => VertexFormat::Uint32x3,
+ GpuVertexFormat::Uint32x4 => VertexFormat::Uint32x4,
+ GpuVertexFormat::Sint32 => VertexFormat::Sint32,
+ GpuVertexFormat::Sint32x2 => VertexFormat::Sint32x2,
+ GpuVertexFormat::Sint32x3 => VertexFormat::Sint32x3,
+ GpuVertexFormat::Sint32x4 => VertexFormat::Sint32x4,
+ GpuVertexFormat::Float64 => VertexFormat::Float64,
+ GpuVertexFormat::Float64x2 => VertexFormat::Float64x2,
+ GpuVertexFormat::Float64x3 => VertexFormat::Float64x3,
+ GpuVertexFormat::Float64x4 => VertexFormat::Float64x4,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+enum GpuVertexStepMode {
+ Vertex,
+ Instance,
+}
+
+impl From<GpuVertexStepMode> for wgpu_types::VertexStepMode {
+ fn from(vsm: GpuVertexStepMode) -> wgpu_types::VertexStepMode {
+ use wgpu_types::VertexStepMode;
+ match vsm {
+ GpuVertexStepMode::Vertex => VertexStepMode::Vertex,
+ GpuVertexStepMode::Instance => VertexStepMode::Instance,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuVertexBufferLayout {
+ array_stride: u64,
+ step_mode: GpuVertexStepMode,
+ attributes: Vec<GpuVertexAttribute>,
+}
+
+impl<'a> From<GpuVertexBufferLayout>
+ for wgpu_core::pipeline::VertexBufferLayout<'a>
+{
+ fn from(
+ layout: GpuVertexBufferLayout,
+ ) -> wgpu_core::pipeline::VertexBufferLayout<'a> {
+ wgpu_core::pipeline::VertexBufferLayout {
+ array_stride: layout.array_stride,
+ step_mode: layout.step_mode.into(),
+ attributes: Cow::Owned(
+ layout.attributes.into_iter().map(Into::into).collect(),
+ ),
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuVertexState {
+ module: ResourceId,
+ entry_point: String,
+ buffers: Vec<Option<GpuVertexBufferLayout>>,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuMultisampleState {
+ count: u32,
+ mask: u64,
+ alpha_to_coverage_enabled: bool,
+}
+
+impl From<GpuMultisampleState> for wgpu_types::MultisampleState {
+ fn from(gms: GpuMultisampleState) -> wgpu_types::MultisampleState {
+ wgpu_types::MultisampleState {
+ count: gms.count,
+ mask: gms.mask,
+ alpha_to_coverage_enabled: gms.alpha_to_coverage_enabled,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct GpuFragmentState {
+ targets: Vec<GpuColorTargetState>,
+ module: u32,
+ entry_point: String,
+ // TODO(lucacasonato): constants
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateRenderPipelineArgs {
+ device_rid: ResourceId,
+ label: Option<String>,
+ layout: Option<ResourceId>,
+ vertex: GpuVertexState,
+ primitive: GpuPrimitiveState,
+ depth_stencil: Option<GpuDepthStencilState>,
+ multisample: GpuMultisampleState,
+ fragment: Option<GpuFragmentState>,
+}
+
+pub fn op_webgpu_create_render_pipeline(
+ state: &mut OpState,
+ args: CreateRenderPipelineArgs,
+ _: (),
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(args.device_rid)?;
+ let device = device_resource.0;
+
+ let layout = if let Some(rid) = args.layout {
+ let pipeline_layout_resource =
+ state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
+ Some(pipeline_layout_resource.0)
+ } else {
+ None
+ };
+
+ let vertex_shader_module_resource =
+ state
+ .resource_table
+ .get::<super::shader::WebGpuShaderModule>(args.vertex.module)?;
+
+ let fragment = if let Some(fragment) = args.fragment {
+ let fragment_shader_module_resource =
+ state
+ .resource_table
+ .get::<super::shader::WebGpuShaderModule>(fragment.module)?;
+
+ let mut targets = Vec::with_capacity(fragment.targets.len());
+
+ for target in fragment.targets {
+ targets.push(target.try_into()?);
+ }
+
+ Some(wgpu_core::pipeline::FragmentState {
+ stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
+ module: fragment_shader_module_resource.0,
+ entry_point: Cow::from(fragment.entry_point),
+ },
+ targets: Cow::from(targets),
+ })
+ } else {
+ None
+ };
+
+ let vertex_buffers = args
+ .vertex
+ .buffers
+ .into_iter()
+ .flatten()
+ .map(Into::into)
+ .collect();
+
+ let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor {
+ label: args.label.map(Cow::Owned),
+ layout,
+ vertex: wgpu_core::pipeline::VertexState {
+ stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
+ module: vertex_shader_module_resource.0,
+ entry_point: Cow::Owned(args.vertex.entry_point),
+ },
+ buffers: Cow::Owned(vertex_buffers),
+ },
+ primitive: args.primitive.into(),
+ depth_stencil: args.depth_stencil.map(TryInto::try_into).transpose()?,
+ multisample: args.multisample.into(),
+ fragment,
+ };
+
+ let implicit_pipelines = match args.layout {
+ Some(_) => None,
+ None => Some(wgpu_core::device::ImplicitPipelineIds {
+ root_id: std::marker::PhantomData,
+ group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS],
+ }),
+ };
+
+ let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline(
+ device,
+ &descriptor,
+ std::marker::PhantomData,
+ implicit_pipelines
+ ));
+
+ let rid = state
+ .resource_table
+ .add(WebGpuRenderPipeline(render_pipeline));
+
+ Ok(WebGpuResult::rid_err(rid, maybe_err))
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RenderPipelineGetBindGroupLayoutArgs {
+ render_pipeline_rid: ResourceId,
+ index: u32,
+}
+
+pub fn op_webgpu_render_pipeline_get_bind_group_layout(
+ state: &mut OpState,
+ args: RenderPipelineGetBindGroupLayoutArgs,
+ _: (),
+) -> Result<PipelineLayout, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let render_pipeline_resource = state
+ .resource_table
+ .get::<WebGpuRenderPipeline>(args.render_pipeline_rid)?;
+ let render_pipeline = render_pipeline_resource.0;
+
+ let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData));
+
+ let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));
+
+ let rid = state
+ .resource_table
+ .add(super::binding::WebGpuBindGroupLayout(bind_group_layout));
+
+ Ok(PipelineLayout {
+ rid,
+ label,
+ err: maybe_err.map(WebGpuError::from),
+ })
+}
diff --git a/ext/webgpu/src/queue.rs b/ext/webgpu/queue.rs
index a662c4ead..39bd93603 100644
--- a/ext/webgpu/src/queue.rs
+++ b/ext/webgpu/queue.rs
@@ -108,7 +108,7 @@ pub struct QueueWriteTextureArgs {
queue_rid: ResourceId,
destination: super::command_encoder::GpuImageCopyTexture,
data_layout: GpuImageDataLayout,
- size: wgpu_types::Extent3d,
+ size: super::texture::GpuExtent3D,
}
pub fn op_webgpu_write_texture(
@@ -127,8 +127,8 @@ pub fn op_webgpu_write_texture(
let destination = wgpu_core::command::ImageCopyTexture {
texture: texture_resource.0,
mip_level: args.destination.mip_level,
- origin: args.destination.origin,
- aspect: args.destination.aspect,
+ origin: args.destination.origin.into(),
+ aspect: args.destination.aspect.into(),
};
let data_layout = args.data_layout.into();
@@ -137,6 +137,6 @@ pub fn op_webgpu_write_texture(
&destination,
&*zero_copy,
&data_layout,
- &args.size
+ &args.size.into()
))
}
diff --git a/ext/webgpu/src/render_pass.rs b/ext/webgpu/render_pass.rs
index 469bf727e..780b6ea57 100644
--- a/ext/webgpu/src/render_pass.rs
+++ b/ext/webgpu/render_pass.rs
@@ -9,6 +9,8 @@ use serde::Deserialize;
use std::borrow::Cow;
use std::cell::RefCell;
+use crate::pipeline::GpuIndexFormat;
+
use super::error::WebGpuResult;
pub(crate) struct WebGpuRenderPass(
@@ -86,9 +88,18 @@ pub fn op_webgpu_render_pass_set_scissor_rect(
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
+pub struct GpuColor {
+ pub r: f64,
+ pub g: f64,
+ pub b: f64,
+ pub a: f64,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
pub struct RenderPassSetBlendConstantArgs {
render_pass_rid: ResourceId,
- color: wgpu_types::Color,
+ color: GpuColor,
}
pub fn op_webgpu_render_pass_set_blend_constant(
@@ -102,7 +113,12 @@ pub fn op_webgpu_render_pass_set_blend_constant(
wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant(
&mut render_pass_resource.0.borrow_mut(),
- &args.color,
+ &wgpu_types::Color {
+ r: args.color.r,
+ g: args.color.g,
+ b: args.color.b,
+ a: args.color.a,
+ },
);
Ok(WebGpuResult::empty())
@@ -153,10 +169,10 @@ pub fn op_webgpu_render_pass_begin_pipeline_statistics_query(
.get::<super::WebGpuQuerySet>(args.query_set)?;
wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query(
- &mut render_pass_resource.0.borrow_mut(),
- query_set_resource.0,
- args.query_index,
- );
+ &mut render_pass_resource.0.borrow_mut(),
+ query_set_resource.0,
+ args.query_index,
+ );
Ok(WebGpuResult::empty())
}
@@ -177,8 +193,8 @@ pub fn op_webgpu_render_pass_end_pipeline_statistics_query(
.get::<WebGpuRenderPass>(args.render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query(
- &mut render_pass_resource.0.borrow_mut(),
- );
+ &mut render_pass_resource.0.borrow_mut(),
+ );
Ok(WebGpuResult::empty())
}
@@ -450,7 +466,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
pub struct RenderPassSetIndexBufferArgs {
render_pass_rid: ResourceId,
buffer: u32,
- index_format: wgpu_types::IndexFormat,
+ index_format: GpuIndexFormat,
offset: u64,
size: Option<u64>,
}
@@ -478,7 +494,7 @@ pub fn op_webgpu_render_pass_set_index_buffer(
render_pass_resource.0.borrow_mut().set_index_buffer(
buffer_resource.0,
- args.index_format,
+ args.index_format.into(),
args.offset,
size,
);
diff --git a/ext/webgpu/sampler.rs b/ext/webgpu/sampler.rs
new file mode 100644
index 000000000..23652cc47
--- /dev/null
+++ b/ext/webgpu/sampler.rs
@@ -0,0 +1,132 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::AnyError;
+use deno_core::ResourceId;
+use deno_core::{OpState, Resource};
+use serde::Deserialize;
+use std::borrow::Cow;
+
+use super::error::WebGpuResult;
+
+pub(crate) struct WebGpuSampler(pub(crate) wgpu_core::id::SamplerId);
+impl Resource for WebGpuSampler {
+ fn name(&self) -> Cow<str> {
+ "webGPUSampler".into()
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+enum GpuAddressMode {
+ ClampToEdge,
+ Repeat,
+ MirrorRepeat,
+}
+
+impl From<GpuAddressMode> for wgpu_types::AddressMode {
+ fn from(value: GpuAddressMode) -> wgpu_types::AddressMode {
+ match value {
+ GpuAddressMode::ClampToEdge => wgpu_types::AddressMode::ClampToEdge,
+ GpuAddressMode::Repeat => wgpu_types::AddressMode::Repeat,
+ GpuAddressMode::MirrorRepeat => wgpu_types::AddressMode::MirrorRepeat,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+enum GpuFilterMode {
+ Nearest,
+ Linear,
+}
+
+impl From<GpuFilterMode> for wgpu_types::FilterMode {
+ fn from(value: GpuFilterMode) -> wgpu_types::FilterMode {
+ match value {
+ GpuFilterMode::Nearest => wgpu_types::FilterMode::Nearest,
+ GpuFilterMode::Linear => wgpu_types::FilterMode::Linear,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuCompareFunction {
+ Never,
+ Less,
+ Equal,
+ LessEqual,
+ Greater,
+ NotEqual,
+ GreaterEqual,
+ Always,
+}
+
+impl From<GpuCompareFunction> for wgpu_types::CompareFunction {
+ fn from(value: GpuCompareFunction) -> wgpu_types::CompareFunction {
+ match value {
+ GpuCompareFunction::Never => wgpu_types::CompareFunction::Never,
+ GpuCompareFunction::Less => wgpu_types::CompareFunction::Less,
+ GpuCompareFunction::Equal => wgpu_types::CompareFunction::Equal,
+ GpuCompareFunction::LessEqual => wgpu_types::CompareFunction::LessEqual,
+ GpuCompareFunction::Greater => wgpu_types::CompareFunction::Greater,
+ GpuCompareFunction::NotEqual => wgpu_types::CompareFunction::NotEqual,
+ GpuCompareFunction::GreaterEqual => {
+ wgpu_types::CompareFunction::GreaterEqual
+ }
+ GpuCompareFunction::Always => wgpu_types::CompareFunction::Always,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateSamplerArgs {
+ device_rid: ResourceId,
+ label: Option<String>,
+ address_mode_u: GpuAddressMode,
+ address_mode_v: GpuAddressMode,
+ address_mode_w: GpuAddressMode,
+ mag_filter: GpuFilterMode,
+ min_filter: GpuFilterMode,
+ mipmap_filter: GpuFilterMode,
+ lod_min_clamp: f32,
+ lod_max_clamp: f32,
+ compare: Option<GpuCompareFunction>,
+ max_anisotropy: u8,
+}
+
+pub fn op_webgpu_create_sampler(
+ state: &mut OpState,
+ args: CreateSamplerArgs,
+ _: (),
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(args.device_rid)?;
+ let device = device_resource.0;
+
+ let descriptor = wgpu_core::resource::SamplerDescriptor {
+ label: args.label.map(Cow::from),
+ address_modes: [
+ args.address_mode_u.into(),
+ args.address_mode_v.into(),
+ args.address_mode_w.into(),
+ ],
+ mag_filter: args.mag_filter.into(),
+ min_filter: args.min_filter.into(),
+ mipmap_filter: args.mipmap_filter.into(),
+ lod_min_clamp: args.lod_min_clamp,
+ lod_max_clamp: args.lod_max_clamp,
+ compare: args.compare.map(Into::into),
+ anisotropy_clamp: std::num::NonZeroU8::new(args.max_anisotropy),
+ border_color: None, // native-only
+ };
+
+ gfx_put!(device => instance.device_create_sampler(
+ device,
+ &descriptor,
+ std::marker::PhantomData
+ ) => state, WebGpuSampler)
+}
diff --git a/ext/webgpu/src/shader.rs b/ext/webgpu/shader.rs
index 60290de8b..2477beceb 100644
--- a/ext/webgpu/src/shader.rs
+++ b/ext/webgpu/shader.rs
@@ -40,7 +40,6 @@ pub fn op_webgpu_create_shader_module(
let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor {
label: args.label.map(Cow::from),
- shader_bound_checks: wgpu_types::ShaderBoundChecks::default(),
};
gfx_put!(device => instance.device_create_shader_module(
diff --git a/ext/webgpu/texture.rs b/ext/webgpu/texture.rs
new file mode 100644
index 000000000..9b007b34d
--- /dev/null
+++ b/ext/webgpu/texture.rs
@@ -0,0 +1,419 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::not_supported;
+use deno_core::error::AnyError;
+use deno_core::ResourceId;
+use deno_core::{OpState, Resource};
+use serde::Deserialize;
+use std::borrow::Cow;
+
+use super::error::WebGpuResult;
+pub(crate) struct WebGpuTexture(pub(crate) wgpu_core::id::TextureId);
+impl Resource for WebGpuTexture {
+ fn name(&self) -> Cow<str> {
+ "webGPUTexture".into()
+ }
+}
+
+pub(crate) struct WebGpuTextureView(pub(crate) wgpu_core::id::TextureViewId);
+impl Resource for WebGpuTextureView {
+ fn name(&self) -> Cow<str> {
+ "webGPUTextureView".into()
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuTextureFormat {
+ // 8-bit formats
+ #[serde(rename = "r8unorm")]
+ R8Unorm,
+ #[serde(rename = "r8snorm")]
+ R8Snorm,
+ #[serde(rename = "r8uint")]
+ R8Uint,
+ #[serde(rename = "r8sint")]
+ R8Sint,
+
+ // 16-bit formats
+ #[serde(rename = "r16uint")]
+ R16Uint,
+ #[serde(rename = "r16sint")]
+ R16Sint,
+ #[serde(rename = "r16float")]
+ R16Float,
+ #[serde(rename = "rg8unorm")]
+ Rg8Unorm,
+ #[serde(rename = "rg8snorm")]
+ Rg8Snorm,
+ #[serde(rename = "rg8uint")]
+ Rg8Uint,
+ #[serde(rename = "rg8sint")]
+ Rg8Sint,
+
+ // 32-bit formats
+ #[serde(rename = "r32uint")]
+ R32Uint,
+ #[serde(rename = "r32sint")]
+ R32Sint,
+ #[serde(rename = "r32float")]
+ R32Float,
+ #[serde(rename = "rg16uint")]
+ Rg16Uint,
+ #[serde(rename = "rg16sint")]
+ Rg16Sint,
+ #[serde(rename = "rg16float")]
+ Rg16Float,
+ #[serde(rename = "rgba8unorm")]
+ Rgba8Unorm,
+ #[serde(rename = "rgba8unorm-srgb")]
+ Rgba8UnormSrgb,
+ #[serde(rename = "rgba8snorm")]
+ Rgba8Snorm,
+ #[serde(rename = "rgba8uint")]
+ Rgba8Uint,
+ #[serde(rename = "rgba8sint")]
+ Rgba8Sint,
+ #[serde(rename = "bgra8unorm")]
+ Bgra8Unorm,
+ #[serde(rename = "bgra8unorm-srgb")]
+ Bgra8UnormSrgb,
+ // Packed 32-bit formats
+ #[serde(rename = "rgb9e5ufloat")]
+ RgB9E5UFloat,
+ #[serde(rename = "rgb10a2unorm")]
+ Rgb10a2Unorm,
+ #[serde(rename = "rg11b10ufloat")]
+ Rg11b10Float,
+
+ // 64-bit formats
+ #[serde(rename = "rg32uint")]
+ Rg32Uint,
+ #[serde(rename = "rg32sint")]
+ Rg32Sint,
+ #[serde(rename = "rg32float")]
+ Rg32Float,
+ #[serde(rename = "rgba16uint")]
+ Rgba16Uint,
+ #[serde(rename = "rgba16sint")]
+ Rgba16Sint,
+ #[serde(rename = "rgba16float")]
+ Rgba16Float,
+
+ // 128-bit formats
+ #[serde(rename = "rgba32uint")]
+ Rgba32Uint,
+ #[serde(rename = "rgba32sint")]
+ Rgba32Sint,
+ #[serde(rename = "rgba32float")]
+ Rgba32Float,
+
+ // Depth and stencil formats
+ #[serde(rename = "stencil8")]
+ Stencil8,
+ #[serde(rename = "depth16unorm")]
+ Depth16Unorm,
+ #[serde(rename = "depth24plus")]
+ Depth24Plus,
+ #[serde(rename = "depth24plus-stencil8")]
+ Depth24PlusStencil8,
+ #[serde(rename = "depth32float")]
+ Depth32Float,
+
+ // BC compressed formats usable if "texture-compression-bc" is both
+ // supported by the device/user agent and enabled in requestDevice.
+ #[serde(rename = "bc1-rgba-unorm")]
+ Bc1RgbaUnorm,
+ #[serde(rename = "bc1-rgba-unorm-srgb")]
+ Bc1RgbaUnormSrgb,
+ #[serde(rename = "bc2-rgba-unorm")]
+ Bc2RgbaUnorm,
+ #[serde(rename = "bc2-rgba-unorm-srgb")]
+ Bc2RgbaUnormSrgb,
+ #[serde(rename = "bc3-rgba-unorm")]
+ Bc3RgbaUnorm,
+ #[serde(rename = "bc3-rgba-unorm-srgb")]
+ Bc3RgbaUnormSrgb,
+ #[serde(rename = "bc4-r-unorm")]
+ Bc4RUnorm,
+ #[serde(rename = "bc4-r-snorm")]
+ Bc4RSnorm,
+ #[serde(rename = "bc5-rg-unorm")]
+ Bc5RgUnorm,
+ #[serde(rename = "bc5-rg-snorm")]
+ Bc5RgSnorm,
+ #[serde(rename = "bc6h-rgb-ufloat")]
+ Bc6hRgbUfloat,
+ #[serde(rename = "bc6h-rgb-float")]
+ Bc6HRgbFloat,
+ #[serde(rename = "bc7-rgba-unorm")]
+ Bc7RgbaUnorm,
+ #[serde(rename = "bc7-rgba-unorm-srgb")]
+ Bc7RgbaUnormSrgb,
+
+ // "depth24unorm-stencil8" feature
+ #[serde(rename = "depth24unorm-stencil8")]
+ Depth24UnormStencil8,
+
+ // "depth32float-stencil8" feature
+ #[serde(rename = "depth32float-stencil8")]
+ Depth32FloatStencil8,
+}
+
+impl TryFrom<GpuTextureFormat> for wgpu_types::TextureFormat {
+ type Error = AnyError;
+
+ fn try_from(value: GpuTextureFormat) -> Result<Self, Self::Error> {
+ use wgpu_types::TextureFormat;
+ match value {
+ GpuTextureFormat::R8Unorm => Ok(TextureFormat::R8Unorm),
+ GpuTextureFormat::R8Snorm => Ok(TextureFormat::R8Snorm),
+ GpuTextureFormat::R8Uint => Ok(TextureFormat::R8Uint),
+ GpuTextureFormat::R8Sint => Ok(TextureFormat::R8Sint),
+
+ GpuTextureFormat::R16Uint => Ok(TextureFormat::R16Uint),
+ GpuTextureFormat::R16Sint => Ok(TextureFormat::R16Sint),
+ GpuTextureFormat::R16Float => Ok(TextureFormat::R16Float),
+ GpuTextureFormat::Rg8Unorm => Ok(TextureFormat::Rg8Unorm),
+ GpuTextureFormat::Rg8Snorm => Ok(TextureFormat::Rg8Snorm),
+ GpuTextureFormat::Rg8Uint => Ok(TextureFormat::Rg8Uint),
+ GpuTextureFormat::Rg8Sint => Ok(TextureFormat::Rg8Sint),
+
+ GpuTextureFormat::R32Uint => Ok(TextureFormat::R32Uint),
+ GpuTextureFormat::R32Sint => Ok(TextureFormat::R32Sint),
+ GpuTextureFormat::R32Float => Ok(TextureFormat::R32Float),
+ GpuTextureFormat::Rg16Uint => Ok(TextureFormat::Rg16Uint),
+ GpuTextureFormat::Rg16Sint => Ok(TextureFormat::Rg16Sint),
+ GpuTextureFormat::Rg16Float => Ok(TextureFormat::Rg16Float),
+ GpuTextureFormat::Rgba8Unorm => Ok(TextureFormat::Rgba8Unorm),
+ GpuTextureFormat::Rgba8UnormSrgb => Ok(TextureFormat::Rgba8UnormSrgb),
+ GpuTextureFormat::Rgba8Snorm => Ok(TextureFormat::Rgba8Snorm),
+ GpuTextureFormat::Rgba8Uint => Ok(TextureFormat::Rgba8Uint),
+ GpuTextureFormat::Rgba8Sint => Ok(TextureFormat::Rgba8Sint),
+ GpuTextureFormat::Bgra8Unorm => Ok(TextureFormat::Bgra8Unorm),
+ GpuTextureFormat::Bgra8UnormSrgb => Ok(TextureFormat::Bgra8UnormSrgb),
+ GpuTextureFormat::RgB9E5UFloat => Err(not_supported()), // wgpu#967
+ GpuTextureFormat::Rgb10a2Unorm => Ok(TextureFormat::Rgb10a2Unorm),
+ GpuTextureFormat::Rg11b10Float => Ok(TextureFormat::Rg11b10Float),
+
+ GpuTextureFormat::Rg32Uint => Ok(TextureFormat::Rg32Uint),
+ GpuTextureFormat::Rg32Sint => Ok(TextureFormat::Rg32Sint),
+ GpuTextureFormat::Rg32Float => Ok(TextureFormat::Rg32Float),
+ GpuTextureFormat::Rgba16Uint => Ok(TextureFormat::Rgba16Uint),
+ GpuTextureFormat::Rgba16Sint => Ok(TextureFormat::Rgba16Sint),
+ GpuTextureFormat::Rgba16Float => Ok(TextureFormat::Rgba16Float),
+
+ GpuTextureFormat::Rgba32Uint => Ok(TextureFormat::Rgba32Uint),
+ GpuTextureFormat::Rgba32Sint => Ok(TextureFormat::Rgba32Sint),
+ GpuTextureFormat::Rgba32Float => Ok(TextureFormat::Rgba32Float),
+
+ GpuTextureFormat::Stencil8 => Err(not_supported()), // wgpu#967
+ GpuTextureFormat::Depth16Unorm => Err(not_supported()), // wgpu#967
+ GpuTextureFormat::Depth24Plus => Ok(TextureFormat::Depth24Plus),
+ GpuTextureFormat::Depth24PlusStencil8 => {
+ Ok(TextureFormat::Depth24PlusStencil8)
+ }
+ GpuTextureFormat::Depth32Float => Ok(TextureFormat::Depth32Float),
+
+ GpuTextureFormat::Bc1RgbaUnorm => Ok(TextureFormat::Bc1RgbaUnorm),
+ GpuTextureFormat::Bc1RgbaUnormSrgb => Ok(TextureFormat::Bc1RgbaUnormSrgb),
+ GpuTextureFormat::Bc2RgbaUnorm => Ok(TextureFormat::Bc2RgbaUnorm),
+ GpuTextureFormat::Bc2RgbaUnormSrgb => Ok(TextureFormat::Bc2RgbaUnormSrgb),
+ GpuTextureFormat::Bc3RgbaUnorm => Ok(TextureFormat::Bc3RgbaUnorm),
+ GpuTextureFormat::Bc3RgbaUnormSrgb => Ok(TextureFormat::Bc3RgbaUnormSrgb),
+ GpuTextureFormat::Bc4RUnorm => Ok(TextureFormat::Bc4RUnorm),
+ GpuTextureFormat::Bc4RSnorm => Ok(TextureFormat::Bc4RSnorm),
+ GpuTextureFormat::Bc5RgUnorm => Ok(TextureFormat::Bc5RgUnorm),
+ GpuTextureFormat::Bc5RgSnorm => Ok(TextureFormat::Bc5RgSnorm),
+ GpuTextureFormat::Bc6hRgbUfloat => Ok(TextureFormat::Bc6hRgbUfloat),
+ GpuTextureFormat::Bc6HRgbFloat => Ok(TextureFormat::Bc6hRgbSfloat), // wgpu#967
+ GpuTextureFormat::Bc7RgbaUnorm => Ok(TextureFormat::Bc7RgbaUnorm),
+ GpuTextureFormat::Bc7RgbaUnormSrgb => Ok(TextureFormat::Bc7RgbaUnormSrgb),
+
+ GpuTextureFormat::Depth24UnormStencil8 => Err(not_supported()), // wgpu#967,
+
+ GpuTextureFormat::Depth32FloatStencil8 => Err(not_supported()), // wgpu#967
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuTextureViewDimension {
+ #[serde(rename = "1d")]
+ D1,
+ #[serde(rename = "2d")]
+ D2,
+ #[serde(rename = "2d-array")]
+ D2Array,
+ #[serde(rename = "cube")]
+ Cube,
+ #[serde(rename = "cube-array")]
+ CubeArray,
+ #[serde(rename = "3d")]
+ D3,
+}
+
+impl From<GpuTextureViewDimension> for wgpu_types::TextureViewDimension {
+ fn from(view_dimension: GpuTextureViewDimension) -> Self {
+ match view_dimension {
+ GpuTextureViewDimension::D1 => wgpu_types::TextureViewDimension::D1,
+ GpuTextureViewDimension::D2 => wgpu_types::TextureViewDimension::D2,
+ GpuTextureViewDimension::D2Array => {
+ wgpu_types::TextureViewDimension::D2Array
+ }
+ GpuTextureViewDimension::Cube => wgpu_types::TextureViewDimension::Cube,
+ GpuTextureViewDimension::CubeArray => {
+ wgpu_types::TextureViewDimension::CubeArray
+ }
+ GpuTextureViewDimension::D3 => wgpu_types::TextureViewDimension::D3,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuTextureDimension {
+ #[serde(rename = "1d")]
+ D1,
+ #[serde(rename = "2d")]
+ D2,
+ #[serde(rename = "3d")]
+ D3,
+}
+
+impl From<GpuTextureDimension> for wgpu_types::TextureDimension {
+ fn from(texture_dimension: GpuTextureDimension) -> Self {
+ match texture_dimension {
+ GpuTextureDimension::D1 => wgpu_types::TextureDimension::D1,
+ GpuTextureDimension::D2 => wgpu_types::TextureDimension::D2,
+ GpuTextureDimension::D3 => wgpu_types::TextureDimension::D3,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuTextureAspect {
+ All,
+ StencilOnly,
+ DepthOnly,
+}
+
+impl From<GpuTextureAspect> for wgpu_types::TextureAspect {
+ fn from(aspect: GpuTextureAspect) -> wgpu_types::TextureAspect {
+ match aspect {
+ GpuTextureAspect::All => wgpu_types::TextureAspect::All,
+ GpuTextureAspect::StencilOnly => wgpu_types::TextureAspect::StencilOnly,
+ GpuTextureAspect::DepthOnly => wgpu_types::TextureAspect::DepthOnly,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GpuExtent3D {
+ pub width: u32,
+ pub height: u32,
+ pub depth_or_array_layers: u32,
+}
+
+impl From<GpuExtent3D> for wgpu_types::Extent3d {
+ fn from(extent: GpuExtent3D) -> Self {
+ wgpu_types::Extent3d {
+ width: extent.width,
+ height: extent.height,
+ depth_or_array_layers: extent.depth_or_array_layers,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateTextureArgs {
+ device_rid: ResourceId,
+ label: Option<String>,
+ size: GpuExtent3D,
+ mip_level_count: u32,
+ sample_count: u32,
+ dimension: GpuTextureDimension,
+ format: GpuTextureFormat,
+ usage: u32,
+}
+
+pub fn op_webgpu_create_texture(
+ state: &mut OpState,
+ args: CreateTextureArgs,
+ _: (),
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let device_resource = state
+ .resource_table
+ .get::<super::WebGpuDevice>(args.device_rid)?;
+ let device = device_resource.0;
+
+ let descriptor = wgpu_core::resource::TextureDescriptor {
+ label: args.label.map(Cow::from),
+ size: args.size.into(),
+ mip_level_count: args.mip_level_count,
+ sample_count: args.sample_count,
+ dimension: args.dimension.into(),
+ format: args.format.try_into()?,
+ usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage),
+ };
+
+ gfx_put!(device => instance.device_create_texture(
+ device,
+ &descriptor,
+ std::marker::PhantomData
+ ) => state, WebGpuTexture)
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateTextureViewArgs {
+ texture_rid: ResourceId,
+ label: Option<String>,
+ format: Option<GpuTextureFormat>,
+ dimension: Option<GpuTextureViewDimension>,
+ aspect: GpuTextureAspect,
+ base_mip_level: u32,
+ mip_level_count: Option<u32>,
+ base_array_layer: u32,
+ array_layer_count: Option<u32>,
+}
+
+pub fn op_webgpu_create_texture_view(
+ state: &mut OpState,
+ args: CreateTextureViewArgs,
+ _: (),
+) -> Result<WebGpuResult, AnyError> {
+ let instance = state.borrow::<super::Instance>();
+ let texture_resource = state
+ .resource_table
+ .get::<WebGpuTexture>(args.texture_rid)?;
+ let texture = texture_resource.0;
+
+ let descriptor = wgpu_core::resource::TextureViewDescriptor {
+ label: args.label.map(Cow::from),
+ format: args.format.map(|s| s.try_into()).transpose()?,
+ dimension: args.dimension.map(|s| s.into()),
+ range: wgpu_types::ImageSubresourceRange {
+ aspect: args.aspect.into(),
+ base_mip_level: args.base_mip_level,
+ mip_level_count: std::num::NonZeroU32::new(
+ args.mip_level_count.unwrap_or(0),
+ ),
+ base_array_layer: args.base_array_layer,
+ array_layer_count: std::num::NonZeroU32::new(
+ args.array_layer_count.unwrap_or(0),
+ ),
+ },
+ };
+
+ gfx_put!(texture => instance.texture_create_view(
+ texture,
+ &descriptor,
+ std::marker::PhantomData
+ ) => state, WebGpuTextureView)
+}
diff --git a/ext/webgpu/webgpu.idl b/ext/webgpu/webgpu.idl
index 79d65791d..026506996 100644
--- a/ext/webgpu/webgpu.idl
+++ b/ext/webgpu/webgpu.idl
@@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase {
USVString label;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension1D;
readonly attribute unsigned long maxTextureDimension2D;
@@ -36,7 +36,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUSupportedFeatures {
readonly setlike<DOMString>;
};
@@ -46,12 +46,12 @@ enum GPUPredefinedColorSpace {
};
interface mixin NavigatorGPU {
- [SameObject, SecureContext] readonly attribute GPU gpu;
+ [SameObject] readonly attribute GPU gpu;
};
Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU;
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPU {
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
};
@@ -63,10 +63,10 @@ dictionary GPURequestAdapterOptions {
enum GPUPowerPreference {
"low-power",
- "high-performance",
+ "high-performance"
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUAdapter {
readonly attribute DOMString name;
[SameObject] readonly attribute GPUSupportedFeatures features;
@@ -82,18 +82,15 @@ dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
};
enum GPUFeatureName {
- "depth-clip-control",
+ "depth-clamping",
"depth24unorm-stencil8",
"depth32float-stencil8",
"pipeline-statistics-query",
"texture-compression-bc",
- "texture-compression-etc2",
- "texture-compression-astc",
"timestamp-query",
- "indirect-first-instance",
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
@@ -123,7 +120,7 @@ interface GPUDevice : EventTarget {
};
GPUDevice includes GPUObjectBase;
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUBuffer {
Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
@@ -161,7 +158,7 @@ interface GPUMapMode {
const GPUFlagsConstant WRITE = 0x0002;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@@ -194,7 +191,7 @@ interface GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUTextureView {
};
GPUTextureView includes GPUObjectBase;
@@ -215,13 +212,13 @@ enum GPUTextureViewDimension {
"2d-array",
"cube",
"cube-array",
- "3d",
+ "3d"
};
enum GPUTextureAspect {
"all",
"stencil-only",
- "depth-only",
+ "depth-only"
};
enum GPUTextureFormat {
@@ -296,50 +293,6 @@ enum GPUTextureFormat {
"bc7-rgba-unorm",
"bc7-rgba-unorm-srgb",
- // ETC2 compressed formats usable if "texture-compression-etc2" is both
- // supported by the device/user agent and enabled in requestDevice.
- "etc2-rgb8unorm",
- "etc2-rgb8unorm-srgb",
- "etc2-rgb8a1unorm",
- "etc2-rgb8a1unorm-srgb",
- "etc2-rgba8unorm",
- "etc2-rgba8unorm-srgb",
- "eac-r11unorm",
- "eac-r11snorm",
- "eac-rg11unorm",
- "eac-rg11snorm",
-
- // ASTC compressed formats usable if "texture-compression-astc" is both
- // supported by the device/user agent and enabled in requestDevice.
- "astc-4x4-unorm",
- "astc-4x4-unorm-srgb",
- "astc-5x4-unorm",
- "astc-5x4-unorm-srgb",
- "astc-5x5-unorm",
- "astc-5x5-unorm-srgb",
- "astc-6x5-unorm",
- "astc-6x5-unorm-srgb",
- "astc-6x6-unorm",
- "astc-6x6-unorm-srgb",
- "astc-8x5-unorm",
- "astc-8x5-unorm-srgb",
- "astc-8x6-unorm",
- "astc-8x6-unorm-srgb",
- "astc-8x8-unorm",
- "astc-8x8-unorm-srgb",
- "astc-10x5-unorm",
- "astc-10x5-unorm-srgb",
- "astc-10x6-unorm",
- "astc-10x6-unorm-srgb",
- "astc-10x8-unorm",
- "astc-10x8-unorm-srgb",
- "astc-10x10-unorm",
- "astc-10x10-unorm-srgb",
- "astc-12x10-unorm",
- "astc-12x10-unorm-srgb",
- "astc-12x12-unorm",
- "astc-12x12-unorm-srgb",
-
// "depth24unorm-stencil8" feature
"depth24unorm-stencil8",
@@ -347,7 +300,7 @@ enum GPUTextureFormat {
"depth32float-stencil8",
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUSampler {
};
GPUSampler includes GPUObjectBase;
@@ -368,12 +321,12 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
enum GPUAddressMode {
"clamp-to-edge",
"repeat",
- "mirror-repeat",
+ "mirror-repeat"
};
enum GPUFilterMode {
"nearest",
- "linear",
+ "linear"
};
enum GPUCompareFunction {
@@ -384,10 +337,10 @@ enum GPUCompareFunction {
"greater",
"not-equal",
"greater-equal",
- "always",
+ "always"
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUBindGroupLayout {
};
GPUBindGroupLayout includes GPUObjectBase;
@@ -437,11 +390,11 @@ dictionary GPUSamplerBindingLayout {
};
enum GPUTextureSampleType {
- "float",
- "unfilterable-float",
- "depth",
- "sint",
- "uint",
+ "float",
+ "unfilterable-float",
+ "depth",
+ "sint",
+ "uint",
};
dictionary GPUTextureBindingLayout {
@@ -460,7 +413,7 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d";
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUBindGroup {
};
GPUBindGroup includes GPUObjectBase;
@@ -483,7 +436,7 @@ dictionary GPUBufferBinding {
GPUSize64 size;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUPipelineLayout {
};
GPUPipelineLayout includes GPUObjectBase;
@@ -492,7 +445,7 @@ dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase {
required sequence<GPUBindGroupLayout> bindGroupLayouts;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUShaderModule {
Promise<GPUCompilationInfo> compilationInfo();
};
@@ -506,10 +459,10 @@ dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
enum GPUCompilationMessageType {
"error",
"warning",
- "info",
+ "info"
};
-[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
+[Exposed=(Window, DedicatedWorker), Serializable]
interface GPUCompilationMessage {
readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type;
@@ -519,7 +472,7 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length;
};
-[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
+[Exposed=(Window, DedicatedWorker), Serializable]
interface GPUCompilationInfo {
readonly attribute FrozenArray<GPUCompilationMessage> messages;
};
@@ -540,7 +493,7 @@ dictionary GPUProgrammableStage {
typedef double GPUPipelineConstantValue; // May represent WGSL’s bool, f32, i32, u32.
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUComputePipeline {
};
GPUComputePipeline includes GPUObjectBase;
@@ -550,7 +503,7 @@ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
required GPUProgrammableStage compute;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPURenderPipeline {
};
GPURenderPipeline includes GPUObjectBase;
@@ -569,7 +522,7 @@ enum GPUPrimitiveTopology {
"line-list",
"line-strip",
"triangle-list",
- "triangle-strip",
+ "triangle-strip"
};
dictionary GPUPrimitiveState {
@@ -578,19 +531,19 @@ dictionary GPUPrimitiveState {
GPUFrontFace frontFace = "ccw";
GPUCullMode cullMode = "none";
- // Requires "depth-clip-control" feature.
- boolean unclippedDepth = false;
+ // Enable depth clamping (requires "depth-clamping" feature)
+ boolean clampDepth = false;
};
enum GPUFrontFace {
"ccw",
- "cw",
+ "cw"
};
enum GPUCullMode {
"none",
"front",
- "back",
+ "back"
};
dictionary GPUMultisampleState {
@@ -599,7 +552,7 @@ dictionary GPUMultisampleState {
boolean alphaToCoverageEnabled = false;
};
-dictionary GPUFragmentState : GPUProgrammableStage {
+dictionary GPUFragmentState: GPUProgrammableStage {
required sequence<GPUColorTargetState> targets;
};
@@ -626,9 +579,9 @@ interface GPUColorWrite {
};
dictionary GPUBlendComponent {
- GPUBlendOperation operation = "add";
GPUBlendFactor srcFactor = "one";
GPUBlendFactor dstFactor = "zero";
+ GPUBlendOperation operation = "add";
};
enum GPUBlendFactor {
@@ -644,7 +597,7 @@ enum GPUBlendFactor {
"one-minus-dst-alpha",
"src-alpha-saturated",
"constant",
- "one-minus-constant",
+ "one-minus-constant"
};
enum GPUBlendOperation {
@@ -652,7 +605,7 @@ enum GPUBlendOperation {
"subtract",
"reverse-subtract",
"min",
- "max",
+ "max"
};
dictionary GPUDepthStencilState {
@@ -687,12 +640,12 @@ enum GPUStencilOperation {
"increment-clamp",
"decrement-clamp",
"increment-wrap",
- "decrement-wrap",
+ "decrement-wrap"
};
enum GPUIndexFormat {
"uint16",
- "uint32",
+ "uint32"
};
enum GPUVertexFormat {
@@ -730,10 +683,10 @@ enum GPUVertexFormat {
enum GPUVertexStepMode {
"vertex",
- "instance",
+ "instance"
};
-dictionary GPUVertexState : GPUProgrammableStage {
+dictionary GPUVertexState: GPUProgrammableStage {
sequence<GPUVertexBufferLayout?> buffers = [];
};
@@ -750,15 +703,16 @@ dictionary GPUVertexAttribute {
required GPUIndex32 shaderLocation;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUCommandBuffer {
+ readonly attribute Promise<double> executionTime;
};
GPUCommandBuffer includes GPUObjectBase;
dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@@ -785,11 +739,6 @@ interface GPUCommandEncoder {
GPUImageCopyTexture destination,
GPUExtent3D copySize);
- undefined clearBuffer(
- GPUBuffer destination,
- GPUSize64 destinationOffset,
- GPUSize64 size);
-
undefined pushDebugGroup(USVString groupLabel);
undefined popDebugGroup();
undefined insertDebugMarker(USVString markerLabel);
@@ -808,6 +757,7 @@ interface GPUCommandEncoder {
GPUCommandEncoder includes GPUObjectBase;
dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
+ boolean measureExecutionTime = false;
};
dictionary GPUImageDataLayout {
@@ -841,7 +791,7 @@ interface mixin GPUProgrammablePassEncoder {
undefined insertDebugMarker(USVString markerLabel);
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1);
@@ -877,7 +827,7 @@ interface mixin GPURenderEncoderBase {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPURenderPassEncoder {
undefined setViewport(float x, float y,
float width, float height,
@@ -931,12 +881,12 @@ dictionary GPURenderPassDepthStencilAttachment {
};
enum GPULoadOp {
- "load",
+ "load"
};
enum GPUStoreOp {
"store",
- "discard",
+ "discard"
};
dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
@@ -945,7 +895,7 @@ dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
GPUSize32 sampleCount = 1;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPURenderBundle {
};
GPURenderBundle includes GPUObjectBase;
@@ -953,7 +903,7 @@ GPURenderBundle includes GPUObjectBase;
dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase {
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
};
@@ -966,7 +916,7 @@ dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout {
boolean stencilReadOnly = false;
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> commandBuffers);
@@ -980,14 +930,14 @@ interface GPUQueue {
optional GPUSize64 size);
undefined writeTexture(
- GPUImageCopyTexture destination,
- [AllowShared] BufferSource data,
- GPUImageDataLayout dataLayout,
- GPUExtent3D size);
+ GPUImageCopyTexture destination,
+ [AllowShared] BufferSource data,
+ GPUImageDataLayout dataLayout,
+ GPUExtent3D size);
};
GPUQueue includes GPUObjectBase;
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUQuerySet {
undefined destroy();
};
@@ -1002,7 +952,7 @@ dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
enum GPUQueryType {
"occlusion",
"pipeline-statistics",
- "timestamp",
+ "timestamp"
};
enum GPUPipelineStatisticName {
@@ -1010,14 +960,14 @@ enum GPUPipelineStatisticName {
"clipper-invocations",
"clipper-primitives-out",
"fragment-shader-invocations",
- "compute-shader-invocations",
+ "compute-shader-invocations"
};
enum GPUDeviceLostReason {
"destroyed",
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUDeviceLostInfo {
readonly attribute (GPUDeviceLostReason or undefined) reason;
readonly attribute DOMString message;
@@ -1029,15 +979,15 @@ partial interface GPUDevice {
enum GPUErrorFilter {
"out-of-memory",
- "validation",
+ "validation"
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUOutOfMemoryError {
constructor();
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[Exposed=(Window, DedicatedWorker)]
interface GPUValidationError {
constructor(DOMString message);
readonly attribute DOMString message;
@@ -1050,7 +1000,9 @@ partial interface GPUDevice {
Promise<GPUError?> popErrorScope();
};
-[Exposed=(Window, DedicatedWorker), SecureContext]
+[
+ Exposed=(Window, DedicatedWorker)
+]
interface GPUUncapturedErrorEvent : Event {
constructor(
DOMString type,
@@ -1108,4 +1060,3 @@ dictionary GPUExtent3DDict {
GPUIntegerCoordinate depthOrArrayLayers = 1;
};
typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D;
-