1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

chore: re-enable wgpu_sync (#13453)

This commit is contained in:
Aaron O'Mullan 2022-01-24 23:47:05 +01:00 committed by GitHub
parent bc8de78da3
commit bd5d445da9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 734 additions and 1900 deletions

87
Cargo.lock generated
View file

@ -136,9 +136,9 @@ dependencies = [
[[package]]
name = "ash"
version = "0.33.3+1.2.191"
version = "0.34.0+1.2.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219"
checksum = "b0f780da53d0063880d45554306489f09dd8d1bda47688b4a57bc579119356df"
dependencies = [
"libloading",
]
@ -283,6 +283,16 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitflags_serde_shim"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25c3d626f0280ec39b33a6fc5c6c1067432b4c41e94aee40ded197a6649bf025"
dependencies = [
"bitflags",
"serde",
]
[[package]]
name = "block"
version = "0.1.6"
@ -1430,12 +1440,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "fixedbitset"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e"
[[package]]
name = "flaky_test"
version = "0.1.0"
@ -1799,6 +1803,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hexf-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "hmac"
version = "0.11.0"
@ -2360,17 +2370,18 @@ dependencies = [
[[package]]
name = "naga"
version = "0.6.3"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c5859e55c51da10b98e7a73068e0a0c5da7bbcae4fc38f86043d0c6d1b917cf"
checksum = "22c5cfe6dbc4ae14962316265a931fbb89b892c5ed6a4a61d7fe4e9f58c0bf94"
dependencies = [
"bit-set",
"bitflags",
"codespan-reporting",
"fxhash",
"hexf-parse",
"indexmap",
"log",
"num-traits",
"petgraph 0.6.0",
"rustc-hash",
"serde",
"spirv",
"thiserror",
@ -2662,17 +2673,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset 0.2.0",
"indexmap",
]
[[package]]
name = "petgraph"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
dependencies = [
"fixedbitset 0.4.1",
"fixedbitset",
"indexmap",
]
@ -3040,16 +3041,6 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6"
[[package]]
name = "raw-window-handle"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76"
dependencies = [
"libc",
"raw-window-handle 0.4.2",
]
[[package]]
name = "raw-window-handle"
version = "0.4.2"
@ -3185,9 +3176,9 @@ dependencies = [
[[package]]
name = "ron"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4"
checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678"
dependencies = [
"base64 0.13.0",
"bitflags",
@ -3732,7 +3723,7 @@ dependencies = [
"is-macro",
"once_cell",
"parking_lot",
"petgraph 0.5.1",
"petgraph",
"radix_fmt",
"relative-path",
"retain_mut",
@ -4083,7 +4074,7 @@ checksum = "1d53bbcbb4b055c547f283af1f84211f425b95ac59e02d8b70c94b8a63a4704f"
dependencies = [
"ahash",
"indexmap",
"petgraph 0.5.1",
"petgraph",
"swc_common",
]
@ -4095,7 +4086,7 @@ checksum = "83b42a8b13068dd90dec954ec44576d5922914687bc34277f3b0f8d0bbeb4e83"
dependencies = [
"ahash",
"auto_impl",
"petgraph 0.5.1",
"petgraph",
"swc_fast_graph",
"tracing",
]
@ -4905,13 +4896,14 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.10.4"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f963c62473a36e3cef6c58181f2ed6d0d38d2043d970dbed46cb197190090c99"
checksum = "c4688c000eb841ca55f7b35db659b78d6e1cd77d7caf8fb929f4e181f754047d"
dependencies = [
"arrayvec 0.7.2",
"bitflags",
"cfg_aliases",
"codespan-reporting",
"copyless",
"fxhash",
"log",
@ -4928,9 +4920,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.10.7"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27cd894b17bff1958ee93da1cc991fd64bf99667746d4bd2a7403855f4d37fe2"
checksum = "62fa524903bf336b51a399f0d586f3c30af94101149588678ef147c30be89e53"
dependencies = [
"arrayvec 0.7.2",
"ash",
@ -4945,6 +4937,7 @@ dependencies = [
"gpu-alloc",
"gpu-descriptor",
"inplace_it",
"js-sys",
"khronos-egl",
"libloading",
"log",
@ -4952,21 +4945,25 @@ dependencies = [
"naga",
"objc",
"parking_lot",
"profiling",
"range-alloc",
"raw-window-handle 0.3.4",
"raw-window-handle",
"renderdoc-sys",
"thiserror",
"wasm-bindgen",
"web-sys",
"wgpu-types",
"winapi 0.3.9",
]
[[package]]
name = "wgpu-types"
version = "0.10.0"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25feb2fbf24ab3219a9f10890ceb8e1ef02b13314ed89d64a9ae99dcad883e18"
checksum = "549533d9e1cdd4b4cda7718d33ff500fc4c34b5467b71d76b547ae0324f3b2a2"
dependencies = [
"bitflags",
"bitflags_serde_shim",
"serde",
]

View file

@ -82,7 +82,7 @@ fn create_compiler_snapshot(
op_crate_libs.insert("deno.url", deno_url::get_declaration());
op_crate_libs.insert("deno.web", deno_web::get_declaration());
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration());
op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration());
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
@ -322,7 +322,7 @@ fn main() {
);
println!(
"cargo:rustc-env=DENO_WEBGPU_LIB_PATH={}",
deno_webgpu::get_declaration().display()
deno_webgpu_get_declaration().display()
);
println!(
"cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}",
@ -369,6 +369,11 @@ fn main() {
}
}
fn deno_webgpu_get_declaration() -> PathBuf {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
manifest_dir.join("dts").join("lib.deno_webgpu.d.ts")
}
fn get_js_files(d: &str) -> Vec<PathBuf> {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut js_files = std::fs::read_dir(d)

View file

@ -92,12 +92,15 @@ declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase {
}
declare type GPUFeatureName =
| "depth-clamping"
| "depth-clip-control"
| "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"
| "sampled-texture-binding-array"
@ -108,9 +111,6 @@ declare type GPUFeatureName =
| "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";
@ -314,6 +314,44 @@ declare type GPUTextureFormat =
| "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";
@ -519,7 +557,7 @@ declare interface GPUPrimitiveState {
stripIndexFormat?: GPUIndexFormat;
frontFace?: GPUFrontFace;
cullMode?: GPUCullMode;
clampDepth?: boolean;
unclippedDepth?: boolean;
}
declare type GPUFrontFace = "ccw" | "cw";
@ -558,9 +596,9 @@ declare class GPUColorWrite {
}
declare interface GPUBlendComponent {
operation: GPUBlendOperation;
srcFactor: GPUBlendFactor;
dstFactor: GPUBlendFactor;
operation: GPUBlendOperation;
}
declare type GPUBlendFactor =
@ -673,8 +711,6 @@ declare interface GPUVertexAttribute {
declare class GPUCommandBuffer implements GPUObjectBase {
label: string | null;
readonly executionTime: Promise<number>;
}
declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {}
@ -713,6 +749,12 @@ declare class GPUCommandEncoder implements GPUObjectBase {
copySize: GPUExtent3D,
): undefined;
clearBuffer(
destination: GPUBuffer,
destinationOffset: number,
size: number,
): undefined;
pushDebugGroup(groupLabel: string): undefined;
popDebugGroup(): undefined;
insertDebugMarker(markerLabel: string): undefined;
@ -730,9 +772,7 @@ declare class GPUCommandEncoder implements GPUObjectBase {
finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer;
}
declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {
measureExecutionTime?: boolean;
}
declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {}
declare interface GPUImageDataLayout {
offset?: number;

View file

@ -1,9 +1,10 @@
[[block]]
struct PrimeIndices {
data: [[stride(4)]] array<u32>;
}; // this is used as both input and output for convenience
[[group(0), binding(0)]]
var<storage, read_write> v_indices: PrimeIndices;
// The Collatz Conjecture states that for any integer n:
// If n is even, n = n/2
// If n is odd, n = 3n+1
@ -25,12 +26,14 @@ fn collatz_iterations(n_base: u32) -> u32{
if (n >= 1431655765u) { // 0x55555555u
return 4294967295u; // 0xffffffffu
}
n = 3u * n + 1u;
}
i = i + 1u;
}
return i;
}
[[stage(compute), workgroup_size(1)]]
fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) {
v_indices.data[global_id.x] = collatz_iterations(v_indices.data[global_id.x]);

View file

@ -33,13 +33,14 @@ Deno.test({
const stagingBuffer = device.createBuffer({
size: size,
usage: 1 | 8,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});
const storageBuffer = device.createBuffer({
label: "Storage Buffer",
size: size,
usage: 0x80 | 8 | 4,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST |
GPUBufferUsage.COPY_SRC,
mappedAtCreation: true,
});

View file

@ -3060,6 +3060,48 @@
device.pushError(err);
}
/**
* @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
*/
@ -3203,7 +3245,7 @@
prefix,
context: "Argument 3",
});
destination = webidl.converters.GPUQuerySet(destination, {
destination = webidl.converters.GPUBuffer(destination, {
prefix,
context: "Argument 4",
});
@ -4527,15 +4569,10 @@
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
})
}`;
}

View file

@ -111,28 +111,35 @@
webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
"GPUFeatureName",
[
"depth-clamping",
"depth-clip-control",
"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",
"sampled-texture-binding-array",
"sampled-texture-array-dynamic-indexing",
"sampled-texture-array-non-uniform-indexing",
"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",
"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",
],
);
@ -348,6 +355,44 @@
"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",
],
@ -1131,7 +1176,7 @@
defaultValue: "none",
},
{
key: "clampDepth",
key: "unclippedDepth",
converter: webidl.converters["boolean"],
defaultValue: false,
},
@ -1458,13 +1503,7 @@
);
// DICTIONARY: GPUCommandEncoderDescriptor
const dictMembersGPUCommandEncoderDescriptor = [
{
key: "measureExecutionTime",
converter: webidl.converters["boolean"],
defaultValue: false,
},
];
const dictMembersGPUCommandEncoderDescriptor = [];
webidl.converters["GPUCommandEncoderDescriptor"] = webidl
.createDictionaryConverter(
"GPUCommandEncoderDescriptor",

View file

@ -1,4 +1,4 @@
# Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
[package]
name = "deno_webgpu"
@ -7,15 +7,12 @@ authors = ["the Deno authors"]
edition = "2021"
license = "MIT"
readme = "README.md"
repository = "https://github.com/denoland/deno"
repository = "https://github.com/gfx-rs/wgpu"
description = "WebGPU implementation for Deno"
[lib]
path = "lib.rs"
[dependencies]
deno_core = { version = "0.116.0", path = "../../core" }
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"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.10", features = ["full"] }
wgpu-core = { version = "0.12", features = ["trace", "replay", "serde"] }
wgpu-types = { version = "0.12", features = ["trace", "replay", "serde"] }

View file

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

View file

@ -1,791 +0,0 @@
// 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),
})
}

View file

@ -1,132 +0,0 @@
// 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)
}

View file

@ -5,8 +5,7 @@ use deno_core::ResourceId;
use deno_core::{OpState, Resource};
use serde::Deserialize;
use std::borrow::Cow;
use crate::texture::{GpuTextureFormat, GpuTextureViewDimension};
use std::convert::{TryFrom, TryInto};
use super::error::WebGpuResult;
@ -59,41 +58,14 @@ impl From<GpuBufferBindingType> for wgpu_types::BufferBindingType {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuSamplerBindingLayout {
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,
},
}
}
r#type: wgpu_types::SamplerBindingType,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuTextureBindingLayout {
sample_type: GpuTextureSampleType,
view_dimension: GpuTextureViewDimension,
view_dimension: wgpu_types::TextureViewDimension,
multisampled: bool,
}
@ -127,8 +99,8 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess,
format: GpuTextureFormat,
view_dimension: GpuTextureViewDimension,
format: wgpu_types::TextureFormat,
view_dimension: wgpu_types::TextureViewDimension,
}
#[derive(Deserialize)]
@ -177,17 +149,19 @@ 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) => sampler.r#type.into(),
GpuBindingType::Sampler(sampler) => {
wgpu_types::BindingType::Sampler(sampler.r#type)
}
GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture {
sample_type: texture.sample_type.into(),
view_dimension: texture.view_dimension.into(),
view_dimension: texture.view_dimension,
multisampled: texture.multisampled,
},
GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(),
format: storage_texture.format.try_into()?,
view_dimension: storage_texture.view_dimension.into(),
format: storage_texture.format,
view_dimension: storage_texture.view_dimension,
}
}
};

View file

@ -9,9 +9,6 @@ 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(
@ -35,8 +32,8 @@ impl Resource for WebGpuRenderBundle {
pub struct CreateRenderBundleEncoderArgs {
device_rid: ResourceId,
label: Option<String>,
color_formats: Vec<GpuTextureFormat>,
depth_stencil_format: Option<GpuTextureFormat>,
color_formats: Vec<wgpu_types::TextureFormat>,
depth_stencil_format: Option<wgpu_types::TextureFormat>,
sample_count: u32,
depth_read_only: bool,
stencil_read_only: bool,
@ -55,12 +52,12 @@ pub fn op_webgpu_create_render_bundle_encoder(
let mut color_formats = vec![];
for format in args.color_formats {
color_formats.push(format.try_into()?);
color_formats.push(format);
}
let depth_stencil = if let Some(format) = args.depth_stencil_format {
Some(wgpu_types::RenderBundleDepthStencil {
format: format.try_into()?,
format,
depth_read_only: args.depth_read_only,
stencil_read_only: args.stencil_read_only,
})
@ -73,6 +70,7 @@ 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 =
@ -301,7 +299,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline(
pub struct RenderBundleEncoderSetIndexBufferArgs {
render_bundle_encoder_rid: ResourceId,
buffer: ResourceId,
index_format: GpuIndexFormat,
index_format: wgpu_types::IndexFormat,
offset: u64,
size: u64,
}
@ -324,7 +322,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
.borrow_mut()
.set_index_buffer(
buffer_resource.0,
args.index_format.into(),
args.index_format,
args.offset,
std::num::NonZeroU64::new(args.size),
);

View file

@ -8,8 +8,6 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::num::NonZeroU32;
use crate::texture::GpuTextureAspect;
use super::error::WebGpuResult;
pub(crate) struct WebGpuCommandEncoder(
@ -65,8 +63,8 @@ pub fn op_webgpu_create_command_encoder(
pub struct GpuRenderPassColorAttachment {
view: ResourceId,
resolve_target: Option<ResourceId>,
load_op: GpuLoadOp<super::render_pass::GpuColor>,
store_op: GpuStoreOp,
load_op: GpuLoadOp<wgpu_types::Color>,
store_op: wgpu_core::command::StoreOp,
}
#[derive(Deserialize)]
@ -76,31 +74,15 @@ enum GpuLoadOp<T> {
Clear(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: GpuStoreOp,
depth_store_op: wgpu_core::command::StoreOp,
depth_read_only: bool,
stencil_load_op: GpuLoadOp<u32>,
stencil_store_op: GpuStoreOp,
stencil_store_op: wgpu_core::command::StoreOp,
stencil_read_only: bool,
}
@ -147,19 +129,14 @@ 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.into(),
store_op: color_attachment.store_op,
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.into(),
clear_value: wgpu_types::Color {
r: color.r,
g: color.g,
b: color.b,
a: color.a,
},
store_op: color_attachment.store_op,
clear_value: color,
read_only: false,
},
},
@ -182,13 +159,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.into(),
store_op: attachment.depth_store_op,
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.into(),
store_op: attachment.depth_store_op,
clear_value: value,
read_only: attachment.depth_read_only,
},
@ -196,13 +173,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.into(),
store_op: attachment.stencil_store_op,
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.into(),
store_op: attachment.stencil_store_op,
clear_value: value,
read_only: attachment.stencil_read_only,
},
@ -315,31 +292,13 @@ pub struct GpuImageCopyBuffer {
rows_per_image: Option<u32>,
}
#[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: GpuOrigin3D,
pub aspect: GpuTextureAspect,
pub origin: wgpu_types::Origin3d,
pub aspect: wgpu_types::TextureAspect,
}
#[derive(Deserialize)]
@ -348,7 +307,7 @@ pub struct CommandEncoderCopyBufferToTextureArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyBuffer,
destination: GpuImageCopyTexture,
copy_size: super::texture::GpuExtent3D,
copy_size: wgpu_types::Extent3d,
}
pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
@ -381,14 +340,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.into(),
aspect: args.destination.aspect.into(),
origin: args.destination.origin,
aspect: args.destination.aspect,
};
gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture(
command_encoder,
&source,
&destination,
&args.copy_size.into()
&args.copy_size
))
}
@ -398,7 +357,7 @@ pub struct CommandEncoderCopyTextureToBufferArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyTexture,
destination: GpuImageCopyBuffer,
copy_size: super::texture::GpuExtent3D,
copy_size: wgpu_types::Extent3d,
}
pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
@ -423,8 +382,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.into(),
aspect: args.source.aspect.into(),
origin: args.source.origin,
aspect: args.source.aspect,
};
let destination = wgpu_core::command::ImageCopyBuffer {
buffer: destination_buffer_resource.0,
@ -442,7 +401,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
command_encoder,
&source,
&destination,
&args.copy_size.into()
&args.copy_size
))
}
@ -452,7 +411,7 @@ pub struct CommandEncoderCopyTextureToTextureArgs {
command_encoder_rid: ResourceId,
source: GpuImageCopyTexture,
destination: GpuImageCopyTexture,
copy_size: super::texture::GpuExtent3D,
copy_size: wgpu_types::Extent3d,
}
pub fn op_webgpu_command_encoder_copy_texture_to_texture(
@ -477,20 +436,51 @@ 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.into(),
aspect: args.source.aspect.into(),
origin: args.source.origin,
aspect: args.source.aspect,
};
let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0,
mip_level: args.destination.mip_level,
origin: args.destination.origin.into(),
aspect: args.destination.aspect.into(),
origin: args.destination.origin,
aspect: args.destination.aspect,
};
gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture(
command_encoder,
&source,
&destination,
&args.copy_size.into()
&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)
))
}

View file

@ -8,6 +8,7 @@ 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;
@ -258,6 +259,12 @@ 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,

View file

@ -14,7 +14,6 @@ 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;
@ -125,15 +124,11 @@ 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_CLAMPING) {
return_features.push("depth-clamping");
if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) {
return_features.push("depth-clip-control");
}
if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) {
return_features.push("pipeline-statistics-query");
@ -141,9 +136,18 @@ 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) {
@ -158,10 +162,14 @@ 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) {
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) {
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) {
@ -179,15 +187,6 @@ 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)
{
@ -206,7 +205,7 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
return_features.push("vertex-writable-storage");
}
if features.contains(wgpu_types::Features::CLEAR_COMMANDS) {
return_features.push("clear-commands");
return_features.push("clear-texture");
}
if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) {
return_features.push("spirv-shader-passthrough");
@ -218,28 +217,11 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
return_features
}
#[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<GpuPowerPreference>,
power_preference: Option<wgpu_types::PowerPreference>,
force_fallback_adapter: bool,
}
#[derive(Serialize)]
@ -266,31 +248,35 @@ 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,
wgpu_types::Backends::PRIMARY,
backends,
));
state.borrow::<Instance>()
};
let descriptor = wgpu_core::instance::RequestAdapterOptions {
power_preference: match args.power_preference {
Some(power_preference) => power_preference.into(),
Some(power_preference) => power_preference,
None => PowerPreference::default(),
},
// TODO(lucacasonato): respect forceFallbackAdapter
force_fallback_adapter: args.force_fallback_adapter,
compatible_surface: None, // windowless
};
let res = instance.request_adapter(
&descriptor,
wgpu_core::instance::AdapterInputs::Mask(
wgpu_types::Backends::PRIMARY,
|_| std::marker::PhantomData,
),
wgpu_core::instance::AdapterInputs::Mask(backends, |_| {
std::marker::PhantomData
}),
);
let adapter = match res {
@ -319,116 +305,13 @@ 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<GpuLimits>,
required_limits: Option<wgpu_types::Limits>,
}
#[derive(Deserialize)]
@ -437,101 +320,120 @@ 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();
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);
}
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"),
);
// extended from spec
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
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::STORAGE_RESOURCE_BINDING_ARRAY, true);
}
if required_features
.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::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
.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("texture-adapter-specific-format-features")
{
.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,
true,
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_COMMANDS,
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("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
}
@ -775,6 +677,10 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
command_encoder::op_webgpu_command_encoder_copy_texture_to_texture,
),
),
(
"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),
@ -895,6 +801,22 @@ fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
"op_webgpu_compute_pass_dispatch_indirect",
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),

View file

@ -108,7 +108,7 @@ pub struct QueueWriteTextureArgs {
queue_rid: ResourceId,
destination: super::command_encoder::GpuImageCopyTexture,
data_layout: GpuImageDataLayout,
size: super::texture::GpuExtent3D,
size: wgpu_types::Extent3d,
}
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.into(),
aspect: args.destination.aspect.into(),
origin: args.destination.origin,
aspect: args.destination.aspect,
};
let data_layout = args.data_layout.into();
@ -137,6 +137,6 @@ pub fn op_webgpu_write_texture(
&destination,
&*zero_copy,
&data_layout,
&args.size.into()
&args.size
))
}

View file

@ -9,8 +9,6 @@ use serde::Deserialize;
use std::borrow::Cow;
use std::cell::RefCell;
use crate::pipeline::GpuIndexFormat;
use super::error::WebGpuResult;
pub(crate) struct WebGpuRenderPass(
@ -86,20 +84,11 @@ pub fn op_webgpu_render_pass_set_scissor_rect(
Ok(WebGpuResult::empty())
}
#[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: GpuColor,
color: wgpu_types::Color,
}
pub fn op_webgpu_render_pass_set_blend_constant(
@ -113,12 +102,7 @@ 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(),
&wgpu_types::Color {
r: args.color.r,
g: args.color.g,
b: args.color.b,
a: args.color.a,
},
&args.color,
);
Ok(WebGpuResult::empty())
@ -466,7 +450,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
pub struct RenderPassSetIndexBufferArgs {
render_pass_rid: ResourceId,
buffer: u32,
index_format: GpuIndexFormat,
index_format: wgpu_types::IndexFormat,
offset: u64,
size: Option<u64>,
}
@ -494,7 +478,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.into(),
args.index_format,
args.offset,
size,
);

View file

@ -40,6 +40,7 @@ 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(

View file

@ -1,419 +0,0 @@
// 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)
}

View file

@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase {
USVString label;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
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)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUSupportedFeatures {
readonly setlike<DOMString>;
};
@ -46,12 +46,12 @@ enum GPUPredefinedColorSpace {
};
interface mixin NavigatorGPU {
[SameObject] readonly attribute GPU gpu;
[SameObject, SecureContext] readonly attribute GPU gpu;
};
Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU;
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
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)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUAdapter {
readonly attribute DOMString name;
[SameObject] readonly attribute GPUSupportedFeatures features;
@ -82,15 +82,18 @@ dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
};
enum GPUFeatureName {
"depth-clamping",
"depth-clip-control",
"depth24unorm-stencil8",
"depth32float-stencil8",
"pipeline-statistics-query",
"texture-compression-bc",
"texture-compression-etc2",
"texture-compression-astc",
"timestamp-query",
"indirect-first-instance",
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
@ -120,7 +123,7 @@ interface GPUDevice : EventTarget {
};
GPUDevice includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBuffer {
Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
@ -158,7 +161,7 @@ interface GPUMapMode {
const GPUFlagsConstant WRITE = 0x0002;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@ -191,7 +194,7 @@ interface GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUTextureView {
};
GPUTextureView includes GPUObjectBase;
@ -212,13 +215,13 @@ enum GPUTextureViewDimension {
"2d-array",
"cube",
"cube-array",
"3d"
"3d",
};
enum GPUTextureAspect {
"all",
"stencil-only",
"depth-only"
"depth-only",
};
enum GPUTextureFormat {
@ -293,6 +296,50 @@ 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",
@ -300,7 +347,7 @@ enum GPUTextureFormat {
"depth32float-stencil8",
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUSampler {
};
GPUSampler includes GPUObjectBase;
@ -321,12 +368,12 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
enum GPUAddressMode {
"clamp-to-edge",
"repeat",
"mirror-repeat"
"mirror-repeat",
};
enum GPUFilterMode {
"nearest",
"linear"
"linear",
};
enum GPUCompareFunction {
@ -337,10 +384,10 @@ enum GPUCompareFunction {
"greater",
"not-equal",
"greater-equal",
"always"
"always",
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBindGroupLayout {
};
GPUBindGroupLayout includes GPUObjectBase;
@ -413,7 +460,7 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d";
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBindGroup {
};
GPUBindGroup includes GPUObjectBase;
@ -436,7 +483,7 @@ dictionary GPUBufferBinding {
GPUSize64 size;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUPipelineLayout {
};
GPUPipelineLayout includes GPUObjectBase;
@ -445,7 +492,7 @@ dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase {
required sequence<GPUBindGroupLayout> bindGroupLayouts;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUShaderModule {
Promise<GPUCompilationInfo> compilationInfo();
};
@ -459,10 +506,10 @@ dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
enum GPUCompilationMessageType {
"error",
"warning",
"info"
"info",
};
[Exposed=(Window, DedicatedWorker), Serializable]
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
interface GPUCompilationMessage {
readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type;
@ -472,7 +519,7 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length;
};
[Exposed=(Window, DedicatedWorker), Serializable]
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
interface GPUCompilationInfo {
readonly attribute FrozenArray<GPUCompilationMessage> messages;
};
@ -493,7 +540,7 @@ dictionary GPUProgrammableStage {
typedef double GPUPipelineConstantValue; // May represent WGSLs bool, f32, i32, u32.
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUComputePipeline {
};
GPUComputePipeline includes GPUObjectBase;
@ -503,7 +550,7 @@ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
required GPUProgrammableStage compute;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderPipeline {
};
GPURenderPipeline includes GPUObjectBase;
@ -522,7 +569,7 @@ enum GPUPrimitiveTopology {
"line-list",
"line-strip",
"triangle-list",
"triangle-strip"
"triangle-strip",
};
dictionary GPUPrimitiveState {
@ -531,19 +578,19 @@ dictionary GPUPrimitiveState {
GPUFrontFace frontFace = "ccw";
GPUCullMode cullMode = "none";
// Enable depth clamping (requires "depth-clamping" feature)
boolean clampDepth = false;
// Requires "depth-clip-control" feature.
boolean unclippedDepth = false;
};
enum GPUFrontFace {
"ccw",
"cw"
"cw",
};
enum GPUCullMode {
"none",
"front",
"back"
"back",
};
dictionary GPUMultisampleState {
@ -579,9 +626,9 @@ interface GPUColorWrite {
};
dictionary GPUBlendComponent {
GPUBlendOperation operation = "add";
GPUBlendFactor srcFactor = "one";
GPUBlendFactor dstFactor = "zero";
GPUBlendOperation operation = "add";
};
enum GPUBlendFactor {
@ -597,7 +644,7 @@ enum GPUBlendFactor {
"one-minus-dst-alpha",
"src-alpha-saturated",
"constant",
"one-minus-constant"
"one-minus-constant",
};
enum GPUBlendOperation {
@ -605,7 +652,7 @@ enum GPUBlendOperation {
"subtract",
"reverse-subtract",
"min",
"max"
"max",
};
dictionary GPUDepthStencilState {
@ -640,12 +687,12 @@ enum GPUStencilOperation {
"increment-clamp",
"decrement-clamp",
"increment-wrap",
"decrement-wrap"
"decrement-wrap",
};
enum GPUIndexFormat {
"uint16",
"uint32"
"uint32",
};
enum GPUVertexFormat {
@ -683,7 +730,7 @@ enum GPUVertexFormat {
enum GPUVertexStepMode {
"vertex",
"instance"
"instance",
};
dictionary GPUVertexState : GPUProgrammableStage {
@ -703,16 +750,15 @@ dictionary GPUVertexAttribute {
required GPUIndex32 shaderLocation;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCommandBuffer {
readonly attribute Promise<double> executionTime;
};
GPUCommandBuffer includes GPUObjectBase;
dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@ -739,6 +785,11 @@ interface GPUCommandEncoder {
GPUImageCopyTexture destination,
GPUExtent3D copySize);
undefined clearBuffer(
GPUBuffer destination,
GPUSize64 destinationOffset,
GPUSize64 size);
undefined pushDebugGroup(USVString groupLabel);
undefined popDebugGroup();
undefined insertDebugMarker(USVString markerLabel);
@ -757,7 +808,6 @@ interface GPUCommandEncoder {
GPUCommandEncoder includes GPUObjectBase;
dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
boolean measureExecutionTime = false;
};
dictionary GPUImageDataLayout {
@ -791,7 +841,7 @@ interface mixin GPUProgrammablePassEncoder {
undefined insertDebugMarker(USVString markerLabel);
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1);
@ -827,7 +877,7 @@ interface mixin GPURenderEncoderBase {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderPassEncoder {
undefined setViewport(float x, float y,
float width, float height,
@ -881,12 +931,12 @@ dictionary GPURenderPassDepthStencilAttachment {
};
enum GPULoadOp {
"load"
"load",
};
enum GPUStoreOp {
"store",
"discard"
"discard",
};
dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
@ -895,7 +945,7 @@ dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
GPUSize32 sampleCount = 1;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderBundle {
};
GPURenderBundle includes GPUObjectBase;
@ -903,7 +953,7 @@ GPURenderBundle includes GPUObjectBase;
dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase {
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
};
@ -916,7 +966,7 @@ dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout {
boolean stencilReadOnly = false;
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> commandBuffers);
@ -937,7 +987,7 @@ interface GPUQueue {
};
GPUQueue includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUQuerySet {
undefined destroy();
};
@ -952,7 +1002,7 @@ dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
enum GPUQueryType {
"occlusion",
"pipeline-statistics",
"timestamp"
"timestamp",
};
enum GPUPipelineStatisticName {
@ -960,14 +1010,14 @@ enum GPUPipelineStatisticName {
"clipper-invocations",
"clipper-primitives-out",
"fragment-shader-invocations",
"compute-shader-invocations"
"compute-shader-invocations",
};
enum GPUDeviceLostReason {
"destroyed",
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUDeviceLostInfo {
readonly attribute (GPUDeviceLostReason or undefined) reason;
readonly attribute DOMString message;
@ -979,15 +1029,15 @@ partial interface GPUDevice {
enum GPUErrorFilter {
"out-of-memory",
"validation"
"validation",
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUOutOfMemoryError {
constructor();
};
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUValidationError {
constructor(DOMString message);
readonly attribute DOMString message;
@ -1000,9 +1050,7 @@ partial interface GPUDevice {
Promise<GPUError?> popErrorScope();
};
[
Exposed=(Window, DedicatedWorker)
]
[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUUncapturedErrorEvent : Event {
constructor(
DOMString type,
@ -1060,3 +1108,4 @@ dictionary GPUExtent3DDict {
GPUIntegerCoordinate depthOrArrayLayers = 1;
};
typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D;

View file

@ -59,3 +59,16 @@ So you can simply run `./tools/flamebench.js op_baseline bench_op_async` or
Tip: the `[bench_filter]` argument doesn't have to be an exact bench name, you
can use a shorthand or a partial match to profile a group of benches, e.g:
`./tools/flamebench.js de v8`
## wgpu_sync.js
`wgpu_sync.js` streamlines updating `deno_webgpu` from
[gfx-rs/wgpu](https://github.com/gfx-rs/wgpu/).
It essentially vendors the `deno_webgpu` tree with a few minor patches applied
on top, somewhat similar to `git subtree`.
1. Update `COMMIT` or `V_WGPU` in `./tools/wgpu_sync.js`
2. Run `./tools/wgpu_sync.js`
3. Double check changes, possibly patch
4. Commit & send a PR with the updates

View file

@ -7,7 +7,7 @@ import {
toFileUrl,
} from "../test_util/std/path/mod.ts";
export { dirname, fromFileUrl, join, resolve, toFileUrl };
export { existsSync } from "../test_util/std/fs/mod.ts";
export { existsSync, walk } from "../test_util/std/fs/mod.ts";
export { readLines } from "../test_util/std/io/mod.ts";
export { delay } from "../test_util/std/async/delay.ts";

119
tools/wgpu_sync.js Executable file
View file

@ -0,0 +1,119 @@
#!/usr/bin/env -S deno run --unstable --allow-read --allow-write --allow-run
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import { join, ROOT_PATH, walk } from "./util.js";
// const COMMIT = "c00e471274b6c21acda89b4b13d41742c0285d71"; // Release 12
const COMMIT = "c4aa3eaed020a640fec06b48f0a5ea93490d41bb"; // tip of PR (needs merge)
const REPO = "kvark/wgpu";
const V_WGPU = "0.12";
const TARGET_DIR = join(ROOT_PATH, "ext", "webgpu");
async function bash(subcmd, opts = {}) {
const p = Deno.run({ ...opts, cmd: ["bash", "-c", subcmd] });
// Exit process on failure
const { success, code } = await p.status();
if (!success) {
Deno.exit(code);
}
// Cleanup
p.close();
}
async function clearTargetDir() {
await bash(`rm -r ${TARGET_DIR}/*`);
}
async function checkoutUpstream() {
// Path of deno_webgpu inside the TAR
const tarPrefix = `${REPO.replace("/", "-")}-${
COMMIT.slice(0, 7)
}/deno_webgpu/`;
const cmd =
`curl -L https://api.github.com/repos/${REPO}/tarball/${COMMIT} | tar -C '${TARGET_DIR}' -xzvf - --strip=2 '${tarPrefix}'`;
// console.log(cmd);
await bash(cmd);
}
async function denoCoreVersion() {
const coreCargo = join(ROOT_PATH, "core", "Cargo.toml");
const contents = await Deno.readTextFile(coreCargo);
return contents.match(/^version = "(\d+\.\d+\.\d+)"$/m)[1];
}
async function denoWebgpuVersion() {
const coreCargo = join(ROOT_PATH, "runtime", "Cargo.toml");
const contents = await Deno.readTextFile(coreCargo);
return contents.match(
/^deno_webgpu = { version = "(\d+\.\d+\.\d+)", path = "..\/ext\/webgpu" }$/m,
)[1];
}
async function patchFile(path, patcher) {
const data = await Deno.readTextFile(path);
const patched = patcher(data);
await Deno.writeTextFile(path, patched);
}
async function patchCargo() {
const vDenoCore = await denoCoreVersion();
const vDenoWebgpu = await denoWebgpuVersion();
await patchFile(
join(TARGET_DIR, "Cargo.toml"),
(data) =>
data
.replace(/^version = .*/m, `version = "${vDenoWebgpu}"`)
.replace(`edition = "2018"`, `edition = "2021"`)
.replace(
/^deno_core \= .*$/gm,
`deno_core = { version = "${vDenoCore}", path = "../../core" }`,
)
.replace(
/^wgpu-core \= .*$/gm,
`wgpu-core = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`,
)
.replace(
/^wgpu-types \= .*$/gm,
`wgpu-types = { version = "${V_WGPU}", features = ["trace", "replay", "serde"] }`,
),
// .replace(
// /^wgpu-core \= .*$/gm,
// `wgpu-core = { git = "https://github.com/${REPO}", rev = "${COMMIT}", features = ["trace", "replay", "serde"] }`,
// )
// .replace(
// /^wgpu-types \= .*$/gm,
// `wgpu-types = { git = "https://github.com/${REPO}", rev = "${COMMIT}", features = ["trace", "replay", "serde"] }`,
// )
);
}
async function patchSrcLib() {
await patchFile(
join(TARGET_DIR, "src", "lib.rs"),
(data) =>
data.replace(`prefix "deno:deno_webgpu",`, `prefix "deno:ext/webgpu",`),
);
}
async function patchCopyrights() {
const walker = walk(TARGET_DIR, { includeDirs: false });
for await (const entry of walker) {
await patchFile(
entry.path,
(data) =>
data.replace(/^\/\/ Copyright 2018-2021/, "// Copyright 2018-2022"),
);
}
}
async function main() {
await clearTargetDir();
await checkoutUpstream();
await patchCargo();
await patchSrcLib();
await patchCopyrights();
await bash(join(ROOT_PATH, "tools", "format.js"));
}
await main();