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

chore: update wgpu (#23684)

This commit is contained in:
Leo Kettmeir 2024-05-05 07:22:18 -07:00 committed by GitHub
parent b2628e4a06
commit cd12d41627
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 820 additions and 505 deletions

142
Cargo.lock generated
View file

@ -608,6 +608,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "chrono"
version = "0.4.37"
@ -981,9 +987,9 @@ dependencies = [
[[package]]
name = "d3d12"
version = "0.7.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20"
checksum = "b28bfe653d79bd16c77f659305b195b82bb5ce0c0eb2a4846b82ddbd77586813"
dependencies = [
"bitflags 2.5.0",
"libloading 0.8.3",
@ -2218,6 +2224,15 @@ dependencies = [
"syn 2.0.58",
]
[[package]]
name = "document-features"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95"
dependencies = [
"litrs",
]
[[package]]
name = "dotenvy"
version = "0.15.7"
@ -3020,23 +3035,22 @@ dependencies = [
[[package]]
name = "gpu-allocator"
version = "0.23.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40fe17c8a05d60c38c0a4e5a3c802f2f1ceb66b76c67d96ffb34bef0475a7fad"
checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884"
dependencies = [
"backtrace",
"log",
"presser",
"thiserror",
"winapi",
"windows 0.51.1",
"windows",
]
[[package]]
name = "gpu-descriptor"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c"
checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557"
dependencies = [
"bitflags 2.5.0",
"gpu-descriptor-types",
@ -3045,9 +3059,9 @@ dependencies = [
[[package]]
name = "gpu-descriptor-types"
version = "0.1.2"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c"
checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91"
dependencies = [
"bitflags 2.5.0",
]
@ -3621,6 +3635,12 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.29"
@ -3892,6 +3912,12 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "litrs"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
[[package]]
name = "lock_api"
version = "0.4.11"
@ -4040,9 +4066,9 @@ dependencies = [
[[package]]
name = "metal"
version = "0.27.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25"
checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb"
dependencies = [
"bitflags 2.5.0",
"block",
@ -4101,10 +4127,11 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "naga"
version = "0.14.2"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae585df4b6514cf8842ac0f1ab4992edc975892704835b549cf818dc0191249e"
checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231"
dependencies = [
"arrayvec",
"bit-set",
"bitflags 2.5.0",
"codespan-reporting",
@ -4146,6 +4173,15 @@ dependencies = [
"syn 2.0.58",
]
[[package]]
name = "ndk-sys"
version = "0.5.0+25.2.9519653"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
dependencies = [
"jni-sys",
]
[[package]]
name = "netif"
version = "0.1.6"
@ -4327,16 +4363,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
"objc_exception",
]
[[package]]
name = "objc_exception"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
dependencies = [
"cc",
]
[[package]]
@ -5112,9 +5138,9 @@ checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab"
[[package]]
name = "raw-window-handle"
version = "0.5.2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
checksum = "8cc3bcbdb1ddfc11e700e62968e6b4cc9c75bb466464ad28fb61c5b2c964418b"
[[package]]
name = "rayon"
@ -5631,9 +5657,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
dependencies = [
"serde_derive",
]
@ -5659,9 +5685,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
dependencies = [
"proc-macro2",
"quote",
@ -5916,12 +5942,11 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "spirv"
version = "0.2.0+1.5.4"
version = "0.3.0+sdk-1.3.268.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830"
checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844"
dependencies = [
"bitflags 1.3.2",
"num-traits",
"bitflags 2.5.0",
]
[[package]]
@ -6655,18 +6680,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
dependencies = [
"proc-macro2",
"quote",
@ -7424,16 +7449,20 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "wgpu-core"
version = "0.18.1"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef91c1d62d1e9e81c79e600131a258edf75c9531cbdbde09c44a011a47312726"
checksum = "ac6a86eaa5e763e59c73cf9e97d55fffd4dfda69fd8bda19589fcf851ddfef1f"
dependencies = [
"arrayvec",
"bit-vec",
"bitflags 2.5.0",
"cfg_aliases",
"codespan-reporting",
"document-features",
"indexmap",
"log",
"naga",
"once_cell",
"parking_lot 0.12.1",
"profiling",
"raw-window-handle",
@ -7449,9 +7478,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.18.1"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84ecc802da3eb67b4cf3dd9ea6fe45bbb47ef13e6c49c5c3240868a9cc6cdd9"
checksum = "4d71c8ae05170583049b65ee562fd839fdc0b3e9ddb84f4e40c9d5f8ea0d4c8c"
dependencies = [
"android_system_properties",
"arrayvec",
@ -7459,6 +7488,7 @@ dependencies = [
"bit-set",
"bitflags 2.5.0",
"block",
"cfg_aliases",
"core-graphics-types",
"d3d12",
"glow",
@ -7473,6 +7503,7 @@ dependencies = [
"log",
"metal",
"naga",
"ndk-sys",
"objc",
"once_cell",
"parking_lot 0.12.1",
@ -7490,9 +7521,9 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.18.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d5ed5f0edf0de351fe311c53304986315ce866f394a2e6df0c4b3c70774bcdd"
checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef"
dependencies = [
"bitflags 2.5.0",
"js-sys",
@ -7549,7 +7580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b2b1bf557d947847a30eb73f79aa6cdb3eaf3ce02f5e9599438f77896a62b3c"
dependencies = [
"thiserror",
"windows 0.52.0",
"windows",
]
[[package]]
@ -7583,35 +7614,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
dependencies = [
"windows-core 0.51.1",
"windows-targets 0.48.5",
]
[[package]]
name = "windows"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core 0.52.0",
"windows-core",
"windows-targets 0.52.4",
]
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-core"
version = "0.52.0"

View file

@ -185,10 +185,10 @@ hkdf = "0.12.3"
rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node
# webgpu
raw-window-handle = "0.5.0"
wgpu-core = { version = "=0.18", features = ["raw-window-handle"] }
wgpu-hal = "=0.18"
wgpu-types = "=0.18"
raw-window-handle = "0.6.0"
wgpu-core = "0.20"
wgpu-hal = "0.20"
wgpu-types = "0.20"
# macros
proc-macro2 = "1"

View file

@ -48,6 +48,8 @@ declare class GPUSupportedLimits {
maxVertexAttributes?: number;
maxVertexBufferArrayStride?: number;
maxInterStageShaderComponents?: number;
maxColorAttachments?: number;
maxColorAttachmentBytesPerSample?: number;
maxComputeWorkgroupStorageSize?: number;
maxComputeInvocationsPerWorkgroup?: number;
maxComputeWorkgroupSizeX?: number;
@ -124,7 +126,7 @@ declare class GPUAdapter {
readonly isFallbackAdapter: boolean;
requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>;
requestAdapterInfo(unmaskHints?: string[]): Promise<GPUAdapterInfo>;
requestAdapterInfo(): Promise<GPUAdapterInfo>;
}
/**
@ -150,6 +152,9 @@ declare type GPUFeatureName =
| "timestamp-query"
| "indirect-first-instance"
| "shader-f16"
| "rg11b10ufloat-renderable"
| "bgra8unorm-storage"
| "float32-filterable"
// extended from spec
| "mappable-primary-buffers"
| "sampled-texture-binding-array"
@ -427,6 +432,7 @@ declare type GPUTextureFormat =
| "bgra8unorm"
| "bgra8unorm-srgb"
| "rgb9e5ufloat"
| "rgb10a2uint"
| "rgb10a2unorm"
| "rg11b10ufloat"
| "rg32uint"
@ -658,7 +664,10 @@ declare type GPUTextureSampleType =
* @category WebGPU
* @tags unstable
*/
declare type GPUStorageTextureAccess = "write-only";
declare type GPUStorageTextureAccess =
| "write-only"
| "read-only"
| "read-write";
/**
* @category WebGPU
@ -756,6 +765,30 @@ declare interface GPUCompilationInfo {
readonly messages: ReadonlyArray<GPUCompilationMessage>;
}
/**
* @category GPU
* @tags unstable
*/
declare class GPUPipelineError extends DOMException {
constructor(message?: string, options?: GPUPipelineErrorInit);
readonly reason: GPUPipelineErrorReason;
}
/**
* @category GPU
* @tags unstable
*/
declare interface GPUPipelineErrorInit {
reason: GPUPipelineErrorReason;
}
/**
* @category GPU
* @tags unstable
*/
declare type GPUPipelineErrorReason = "validation" | "internal";
/**
* @category WebGPU
* @tags unstable
@ -801,7 +834,8 @@ declare interface GPUPipelineBase {
*/
declare interface GPUProgrammableStage {
module: GPUShaderModule;
entryPoint: string;
entryPoint?: string;
constants?: Record<string, number>;
}
/**
@ -1063,7 +1097,8 @@ declare type GPUVertexFormat =
| "sint32"
| "sint32x2"
| "sint32x3"
| "sint32x4";
| "sint32x4"
| "unorm10-10-10-2";
/**
* @category WebGPU
@ -1653,11 +1688,40 @@ declare class GPUValidationError extends GPUError {
constructor(message: string);
}
/**
* @category GPU
* @tags unstable
*/
declare class GPUInternalError extends GPUError {
constructor(message: string);
}
/**
* @category WebGPU
* @tags unstable
*/
declare type GPUErrorFilter = "out-of-memory" | "validation";
declare type GPUErrorFilter = "out-of-memory" | "validation" | "internal";
/**
* @category GPU
* @tags unstable
*/
declare class GPUUncapturedErrorEvent extends EventTarget {
constructor(
type: string,
gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit,
);
readonly error: GPUError;
}
/**
* @category GPU
* @tags unstable
*/
declare interface GPUUncapturedErrorEventInit extends EventInit {
error: GPUError;
}
/**
* @category WebGPU

View file

@ -92,8 +92,7 @@ const {
ArrayBuffer,
ArrayBufferPrototypeGetByteLength,
ArrayIsArray,
ArrayPrototypeFilter,
ArrayPrototypeIncludes,
ArrayPrototypeFindLast,
ArrayPrototypeMap,
ArrayPrototypePop,
ArrayPrototypePush,
@ -104,12 +103,9 @@ const {
ObjectHasOwn,
ObjectPrototypeIsPrototypeOf,
Promise,
PromisePrototypeCatch,
PromisePrototypeThen,
PromiseReject,
PromiseResolve,
SafeArrayIterator,
SafePromiseAll,
SafeSet,
SafeWeakRef,
SetPrototypeHas,
@ -124,7 +120,12 @@ const {
} = primordials;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { EventTarget } from "ext:deno_web/02_event.js";
import {
defineEventHandler,
Event,
EventTarget,
setEventTargetData,
} from "ext:deno_web/02_event.js";
import { DOMException } from "ext:deno_web/01_dom_exception.js";
import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
@ -299,7 +300,6 @@ class GPUValidationError extends GPUError {
this[_message] = message;
}
}
const GPUValidationErrorPrototype = GPUValidationError.prototype;
class GPUOutOfMemoryError extends GPUError {
name = "GPUOutOfMemoryError";
@ -312,7 +312,40 @@ class GPUOutOfMemoryError extends GPUError {
this[_message] = message;
}
}
const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError.prototype;
class GPUInternalError extends GPUError {
name = "GPUInternalError";
constructor() {
super(illegalConstructorKey);
this[webidl.brand] = webidl.brand;
}
}
class GPUUncapturedErrorEvent extends Event {
#error;
constructor(type, gpuUncapturedErrorEventInitDict) {
super(type, gpuUncapturedErrorEventInitDict);
this[webidl.brand] = webidl.brand;
const prefix = "Failed to construct 'GPUUncapturedErrorEvent'";
webidl.requiredArguments(arguments.length, 2, prefix);
gpuUncapturedErrorEventInitDict = webidl.converters
.GPUUncapturedErrorEventInit(
gpuUncapturedErrorEventInitDict,
prefix,
"Argument 2",
);
this.#error = gpuUncapturedErrorEventInitDict.error;
}
get error() {
webidl.assertBranded(this, GPUUncapturedErrorEventPrototype);
return this.#error;
}
}
const GPUUncapturedErrorEventPrototype = GPUUncapturedErrorEvent.prototype;
class GPU {
[webidl.brand] = webidl.brand;
@ -433,7 +466,7 @@ class GPUAdapter {
}
}
const { rid, features, limits } = op_webgpu_request_device(
const { rid, queueRid, features, limits } = op_webgpu_request_device(
this[_adapter].rid,
descriptor.label,
requiredFeatures,
@ -446,25 +479,22 @@ class GPUAdapter {
features: createGPUSupportedFeatures(features),
limits: createGPUSupportedLimits(limits),
});
return createGPUDevice(
const queue = createGPUQueue(descriptor.label, inner, queueRid);
inner.trackResource(queue);
const device = createGPUDevice(
descriptor.label,
inner,
createGPUQueue(descriptor.label, inner),
queue,
);
inner.device = device;
return device;
}
/**
* @param {string[]} unmaskHints
* @returns {Promise<GPUAdapterInfo>}
*/
requestAdapterInfo(unmaskHints = []) {
requestAdapterInfo() {
webidl.assertBranded(this, GPUAdapterPrototype);
const prefix = "Failed to execute 'requestAdapterInfo' on 'GPUAdapter'";
unmaskHints = webidl.converters["sequence<DOMString>"](
unmaskHints,
prefix,
"Argument 1",
);
const {
vendor,
@ -474,16 +504,10 @@ class GPUAdapter {
} = op_webgpu_request_adapter_info(this[_adapter].rid);
const adapterInfo = webidl.createBranded(GPUAdapterInfo);
adapterInfo[_vendor] = ArrayPrototypeIncludes(unmaskHints, "vendor")
? vendor
: "";
adapterInfo[_architecture] =
ArrayPrototypeIncludes(unmaskHints, "architecture") ? architecture : "";
adapterInfo[_device] = ArrayPrototypeIncludes(unmaskHints, "device")
? device
: "";
adapterInfo[_description] =
ArrayPrototypeIncludes(unmaskHints, "description") ? description : "";
adapterInfo[_vendor] = vendor;
adapterInfo[_architecture] = architecture;
adapterInfo[_device] = device;
adapterInfo[_description] = description;
return PromiseResolve(adapterInfo);
}
@ -687,6 +711,14 @@ class GPUSupportedLimits {
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxInterStageShaderComponents;
}
get maxColorAttachments() {
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxColorAttachments;
}
get maxColorAttachmentBytesPerSample() {
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxColorAttachmentBytesPerSample;
}
get maxComputeWorkgroupStorageSize() {
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
return this[_limits].maxComputeWorkgroupStorageSize;
@ -743,6 +775,8 @@ class GPUSupportedLimits {
"maxVertexAttributes",
"maxVertexBufferArrayStride",
"maxInterStageShaderComponents",
"maxColorAttachments",
"maxColorAttachmentBytesPerSample",
"maxComputeWorkgroupStorageSize",
"maxComputeInvocationsPerWorkgroup",
"maxComputeWorkgroupSizeX",
@ -773,6 +807,7 @@ class GPUSupportedFeatures {
constructor() {
webidl.illegalConstructor();
}
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
if (ObjectPrototypeIsPrototypeOf(GPUSupportedFeaturesPrototype, this)) {
return `${this.constructor.name} ${
@ -783,7 +818,6 @@ class GPUSupportedFeatures {
}
}
}
const GPUSupportedFeaturesPrototype = GPUSupportedFeatures.prototype;
/**
@ -870,7 +904,7 @@ function GPUObjectBaseMixin(name, type) {
/**
* @typedef ErrorScope
* @property {string} filter
* @property {Promise<void>[]} operations
* @property {GPUError[]} errors
*/
/**
@ -879,6 +913,7 @@ function GPUObjectBaseMixin(name, type) {
* @property {number | undefined} rid
* @property {GPUSupportedFeatures} features
* @property {GPUSupportedLimits} limits
* @property {GPUDevice} device
*/
class InnerGPUDevice {
@ -900,6 +935,8 @@ class InnerGPUDevice {
resolveLost;
/** @type {ErrorScope[]} */
errorScopeStack;
/** @type {GPUDevice} */
device;
/**
* @param {InnerGPUDeviceOptions} options
@ -923,79 +960,51 @@ class InnerGPUDevice {
ArrayPrototypePush(this.resources, new SafeWeakRef(resource));
}
/** @param {{ type: string, value: string | null } | undefined} err */
pushError(err) {
this.pushErrorPromise(PromiseResolve(err));
// Ref: https://gpuweb.github.io/gpuweb/#abstract-opdef-dispatch-error
/** @param {{ type: string, value: string | null } | undefined} error */
pushError(error) {
if (!error) {
return;
}
/** @param {Promise<{ type: string, value: string | null } | undefined>} promise */
pushErrorPromise(promise) {
const operation = PromisePrototypeThen(promise, (err) => {
if (err) {
switch (err.type) {
let constructedError;
switch (error.type) {
case "lost":
this.isLost = true;
this.resolveLost(
createGPUDeviceLostInfo(undefined, "device was lost"),
);
break;
return;
case "validation":
return PromiseReject(
new GPUValidationError(err.value ?? "validation error"),
constructedError = new GPUValidationError(
error.value ?? "validation error",
);
break;
case "out-of-memory":
return PromiseReject(new GPUOutOfMemoryError());
constructedError = new GPUOutOfMemoryError();
break;
case "internal":
constructedError = new GPUInternalError();
break;
}
}
});
const validationStack = ArrayPrototypeFilter(
this.errorScopeStack,
({ filter }) => filter == "validation",
);
const validationScope = validationStack[validationStack.length - 1];
const validationFilteredPromise = PromisePrototypeCatch(
operation,
(err) => {
if (ObjectPrototypeIsPrototypeOf(GPUValidationErrorPrototype, err)) {
return PromiseReject(err);
if (this.isLost) {
return;
}
return PromiseResolve();
},
);
if (validationScope) {
ArrayPrototypePush(
validationScope.operations,
validationFilteredPromise,
);
} else {
PromisePrototypeCatch(validationFilteredPromise, () => {
// TODO(lucacasonato): emit an UncapturedErrorEvent
});
}
// prevent uncaptured promise rejections
PromisePrototypeCatch(validationFilteredPromise, (_err) => {});
const oomStack = ArrayPrototypeFilter(
const scope = ArrayPrototypeFindLast(
this.errorScopeStack,
({ filter }) => filter == "out-of-memory",
({ filter }) => filter === error.type,
);
const oomScope = oomStack[oomStack.length - 1];
const oomFilteredPromise = PromisePrototypeCatch(operation, (err) => {
if (ObjectPrototypeIsPrototypeOf(GPUOutOfMemoryErrorPrototype, err)) {
return PromiseReject(err);
}
return PromiseResolve();
});
if (oomScope) {
ArrayPrototypePush(oomScope.operations, oomFilteredPromise);
if (scope) {
ArrayPrototypePush(scope.errors, constructedError);
} else {
PromisePrototypeCatch(oomFilteredPromise, () => {
// TODO(lucacasonato): emit an UncapturedErrorEvent
});
this.device.dispatchEvent(
new GPUUncapturedErrorEvent("uncapturederror", {
error: constructedError,
}),
);
}
// prevent uncaptured promise rejections
PromisePrototypeCatch(oomFilteredPromise, (_err) => {});
}
}
@ -1011,6 +1020,7 @@ function createGPUDevice(label, inner, queue) {
device[_label] = label;
device[_device] = inner;
device[_queue] = queue;
setEventTargetData(device);
return device;
}
@ -1283,11 +1293,6 @@ class GPUDevice extends EventTarget {
const resource = entry.resource;
if (ObjectPrototypeIsPrototypeOf(GPUSamplerPrototype, resource)) {
const rid = assertResource(resource, prefix, context);
assertDeviceMatch(device, resource, {
prefix,
resourceContext: context,
selfContext: "this",
});
return {
binding: entry.binding,
kind: "GPUSampler",
@ -1298,11 +1303,6 @@ class GPUDevice extends EventTarget {
) {
const rid = assertResource(resource, prefix, context);
assertResource(resource[_texture], prefix, context);
assertDeviceMatch(device, resource[_texture], {
prefix,
resourceContext: context,
selfContext: "this",
});
return {
binding: entry.binding,
kind: "GPUTextureView",
@ -1311,12 +1311,6 @@ class GPUDevice extends EventTarget {
} else {
// deno-lint-ignore prefer-primordials
const rid = assertResource(resource.buffer, prefix, context);
// deno-lint-ignore prefer-primordials
assertDeviceMatch(device, resource.buffer, {
prefix,
resourceContext: context,
selfContext: "this",
});
return {
binding: entry.binding,
kind: "GPUBufferBinding",
@ -1509,12 +1503,166 @@ class GPUDevice extends EventTarget {
createComputePipelineAsync(descriptor) {
// TODO(lucacasonato): this should be real async
return PromiseResolve(this.createComputePipeline(descriptor));
webidl.assertBranded(this, GPUDevicePrototype);
const prefix =
"Failed to execute 'createComputePipelineAsync' on 'GPUDevice'";
webidl.requiredArguments(arguments.length, 1, prefix);
descriptor = webidl.converters.GPUComputePipelineDescriptor(
descriptor,
prefix,
"Argument 1",
);
const device = assertDevice(this, prefix, "this");
let layout = descriptor.layout;
if (typeof descriptor.layout !== "string") {
const context = "layout";
layout = assertResource(descriptor.layout, prefix, context);
assertDeviceMatch(device, descriptor.layout, {
prefix,
resourceContext: context,
selfContext: "this",
});
}
const module = assertResource(
descriptor.compute.module,
prefix,
"compute shader module",
);
assertDeviceMatch(device, descriptor.compute.module, {
prefix,
resourceContext: "compute shader module",
selfContext: "this",
});
const { rid, err } = op_webgpu_create_compute_pipeline(
device.rid,
descriptor.label,
layout,
{
module,
entryPoint: descriptor.compute.entryPoint,
constants: descriptor.compute.constants,
},
);
device.pushError(err);
if (err) {
switch (err.type) {
case "validation":
return PromiseReject(
new GPUPipelineError(err.value ?? "validation error", {
reason: "validation",
}),
);
case "internal":
return PromiseReject(
new GPUPipelineError("internal error", {
reason: "validation",
}),
);
}
}
const computePipeline = createGPUComputePipeline(
descriptor.label,
device,
rid,
);
device.trackResource(computePipeline);
return PromiseResolve(computePipeline);
}
createRenderPipelineAsync(descriptor) {
// TODO(lucacasonato): this should be real async
return PromiseResolve(this.createRenderPipeline(descriptor));
webidl.assertBranded(this, GPUDevicePrototype);
const prefix =
"Failed to execute 'createRenderPipelineAsync' on 'GPUDevice'";
webidl.requiredArguments(arguments.length, 1, prefix);
descriptor = webidl.converters.GPURenderPipelineDescriptor(
descriptor,
prefix,
"Argument 1",
);
const device = assertDevice(this, prefix, "this");
let layout = descriptor.layout;
if (typeof descriptor.layout !== "string") {
const context = "layout";
layout = assertResource(descriptor.layout, prefix, context);
assertDeviceMatch(device, descriptor.layout, {
prefix,
resourceContext: context,
selfContext: "this",
});
}
const module = assertResource(
descriptor.vertex.module,
prefix,
"vertex shader module",
);
assertDeviceMatch(device, descriptor.vertex.module, {
prefix,
resourceContext: "vertex shader module",
selfContext: "this",
});
let fragment = undefined;
if (descriptor.fragment) {
const module = assertResource(
descriptor.fragment.module,
prefix,
"fragment shader module",
);
assertDeviceMatch(device, descriptor.fragment.module, {
prefix,
resourceContext: "fragment shader module",
selfContext: "this",
});
fragment = {
module,
entryPoint: descriptor.fragment.entryPoint,
targets: descriptor.fragment.targets,
};
}
const { rid, err } = op_webgpu_create_render_pipeline({
deviceRid: device.rid,
label: descriptor.label,
layout,
vertex: {
module,
entryPoint: descriptor.vertex.entryPoint,
buffers: descriptor.vertex.buffers,
},
primitive: descriptor.primitive,
depthStencil: descriptor.depthStencil,
multisample: descriptor.multisample,
fragment,
});
device.pushError(err);
if (err) {
switch (err.type) {
case "validation":
return PromiseReject(
new GPUPipelineError(err.value ?? "validation error", {
reason: "validation",
}),
);
case "internal":
return PromiseReject(
new GPUPipelineError("internal error", {
reason: "validation",
}),
);
}
}
const renderPipeline = createGPURenderPipeline(
descriptor.label,
device,
rid,
);
device.trackResource(renderPipeline);
return renderPipeline;
}
/**
@ -1626,7 +1774,7 @@ class GPUDevice extends EventTarget {
webidl.requiredArguments(arguments.length, 1, prefix);
filter = webidl.converters.GPUErrorFilter(filter, prefix, "Argument 1");
const device = assertDevice(this, prefix, "this");
ArrayPrototypePush(device.errorScopeStack, { filter, operations: [] });
ArrayPrototypePush(device.errorScopeStack, { filter, errors: [] });
}
/**
@ -1647,12 +1795,7 @@ class GPUDevice extends EventTarget {
"OperationError",
);
}
const operations = SafePromiseAll(scope.operations);
return PromisePrototypeThen(
operations,
() => PromiseResolve(null),
(err) => PromiseResolve(err),
);
return PromiseResolve(scope.errors[0] ?? null);
}
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
@ -1676,23 +1819,60 @@ class GPUDevice extends EventTarget {
}
GPUObjectBaseMixin("GPUDevice", GPUDevice);
const GPUDevicePrototype = GPUDevice.prototype;
defineEventHandler(GPUDevice.prototype, "uncapturederror");
class GPUPipelineError extends DOMException {
#reason;
constructor(message = "", options = {}) {
const prefix = "Failed to construct 'GPUPipelineError'";
message = webidl.converters.DOMString(message, prefix, "Argument 1");
options = webidl.converters.GPUPipelineErrorInit(
options,
prefix,
"Argument 2",
);
super(message, "GPUPipelineError");
this.#reason = options.reason;
}
get reason() {
webidl.assertBranded(this, GPUPipelineErrorPrototype);
return this.#reason;
}
}
const GPUPipelineErrorPrototype = GPUPipelineError.prototype;
/**
* @param {string | null} label
* @param {InnerGPUDevice} device
* @param {number} rid
* @returns {GPUQueue}
*/
function createGPUQueue(label, device) {
function createGPUQueue(label, device, rid) {
/** @type {GPUQueue} */
const queue = webidl.createBranded(GPUQueue);
queue[_label] = label;
queue[_device] = device;
queue[_rid] = rid;
return queue;
}
class GPUQueue {
/** @type {InnerGPUDevice} */
[_device];
/** @type {number} */
[_rid];
[_cleanup]() {
const rid = this[_rid];
if (rid !== undefined) {
core.close(rid);
/** @type {number | undefined} */
this[_rid] = undefined;
}
}
constructor() {
webidl.illegalConstructor();
@ -1726,7 +1906,7 @@ class GPUQueue {
return rid;
},
);
const { err } = op_webgpu_queue_submit(device.rid, commandBufferRids);
const { err } = op_webgpu_queue_submit(this[_rid], commandBufferRids);
for (let i = 0; i < commandBuffers.length; ++i) {
commandBuffers[i][_rid] = undefined;
}
@ -1782,7 +1962,7 @@ class GPUQueue {
}
const { err } = op_webgpu_write_buffer(
device.rid,
this[_rid],
bufferRid,
bufferOffset,
dataOffset,
@ -1833,7 +2013,7 @@ class GPUQueue {
}
const { err } = op_webgpu_write_texture(
device.rid,
this[_rid],
{
texture: textureRid,
mipLevel: destination.mipLevel,
@ -2027,19 +2207,15 @@ class GPUBuffer {
this[_mapMode] = mode;
this[_state] = "pending";
const promise = PromisePrototypeThen(
op_webgpu_buffer_get_map_async(
const { err } = await op_webgpu_buffer_get_map_async(
bufferRid,
device.rid,
mode,
offset,
rangeSize,
),
({ err }) => err,
);
device.pushErrorPromise(promise);
const err = await promise;
if (err) {
device.pushError(err);
throw new DOMException("validation error occurred", "OperationError");
}
this[_state] = "mapped";
@ -5136,6 +5312,7 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
"texture-compression-astc",
"rg11b10ufloat-renderable",
"bgra8unorm-storage",
"float32-filterable",
// extended from spec
@ -5174,6 +5351,27 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
],
);
// DICTIONARY: GPUPipelineErrorInit
webidl.converters["GPUPipelineErrorInit"] = webidl.createDictionaryConverter(
"GPUPipelineErrorInit",
[
{
key: "reason",
converter: webidl.converters.GPUPipelineErrorReason,
required: true,
},
],
);
// ENUM: GPUPipelineErrorReason
webidl.converters["GPUPipelineErrorReason"] = webidl.createEnumConverter(
"GPUPipelineErrorReason",
[
"validation",
"internal",
],
);
// TYPEDEF: GPUSize32
webidl.converters["GPUSize32"] = (V, opts) =>
webidl.converters["unsigned long"](V, { ...opts, enforceRange: true });
@ -5353,6 +5551,7 @@ webidl.converters["GPUTextureFormat"] = webidl.createEnumConverter(
"bgra8unorm",
"bgra8unorm-srgb",
"rgb9e5ufloat",
"rgb10a2uint",
"rgb10a2unorm",
"rg11b10ufloat",
"rg32uint",
@ -5768,6 +5967,8 @@ webidl.converters["GPUStorageTextureAccess"] = webidl.createEnumConverter(
"GPUStorageTextureAccess",
[
"write-only",
"read-only",
"read-write",
],
);
@ -6027,7 +6228,6 @@ const dictMembersGPUProgrammableStage = [
{
key: "entryPoint",
converter: webidl.converters["USVString"],
required: true,
},
{
key: "constants",
@ -6110,6 +6310,7 @@ webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter(
"sint32x2",
"sint32x3",
"sint32x4",
"unorm10-10-10-2",
],
);
@ -7070,6 +7271,7 @@ webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter(
[
"out-of-memory",
"validation",
"internal",
],
);
@ -7209,6 +7411,7 @@ export {
GPUDevice,
GPUDeviceLostInfo,
GPUError,
GPUInternalError,
GPUMapMode,
GPUOutOfMemoryError,
GPUPipelineLayout,
@ -7226,5 +7429,6 @@ export {
GPUTexture,
GPUTextureUsage,
GPUTextureView,
GPUUncapturedErrorEvent,
GPUValidationError,
};

View file

@ -19,22 +19,30 @@ path = "lib.rs"
deno_core.workspace = true
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
wgpu-types = { workspace = true, features = ["trace", "replay", "serde"] }
wgpu-types = { workspace = true, features = ["serde"] }
raw-window-handle = { workspace = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgpu-core]
workspace = true
features = ["trace", "replay", "serde", "strict_asserts", "wgsl", "gles"]
features = [
"raw-window-handle",
"trace",
"replay",
"serde",
"strict_asserts",
"wgsl",
"gles",
]
# We want the wgpu-core Metal backend on macOS and iOS.
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgpu-core]
workspace = true
features = ["metal"]
# We want the wgpu-core Direct3D backends on Windows.
# We want the wgpu-core Direct3D backend on Windows.
[target.'cfg(windows)'.dependencies.wgpu-core]
workspace = true
features = ["dx11", "dx12"]
features = ["dx12"]
[target.'cfg(windows)'.dependencies.wgpu-hal]
workspace = true

View file

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

View file

@ -2,7 +2,7 @@
This op crate implements the WebGPU API as defined in
https://gpuweb.github.io/gpuweb/ in Deno. The implementation targets the spec
draft as of October 4, 2023. The spec is still very much in flux. This op crate
draft as of March 31, 2024. The spec is still very much in flux. This extension
tries to stay up to date with the spec, but is constrained by the features
implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu).
@ -19,7 +19,7 @@ running through our WPT runner. This will be used to validate implementation
conformance.
GitHub CI doesn't run with GPUs, so testing relies on software like DX WARP &
Vulkan lavapipe. Currently only using DX WARP works, so tests are only run on
Vulkan lavapipe. Currently, only using DX WARP works, so tests are only run on
Windows.
## Links

View file

@ -21,8 +21,7 @@ impl Resource for WebGpuBindGroupLayout {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.bind_group_layout_drop(self.1));
gfx_select!(self.1 => self.0.bind_group_layout_drop(self.1));
}
}
@ -36,8 +35,7 @@ impl Resource for WebGpuBindGroup {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.bind_group_drop(self.1));
gfx_select!(self.1 => self.0.bind_group_drop(self.1));
}
}
@ -114,27 +112,11 @@ impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuStorageTextureBindingLayout {
access: GpuStorageTextureAccess,
access: wgpu_types::StorageTextureAccess,
format: wgpu_types::TextureFormat,
view_dimension: wgpu_types::TextureViewDimension,
}
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
enum GpuStorageTextureAccess {
WriteOnly,
}
impl From<GpuStorageTextureAccess> for wgpu_types::StorageTextureAccess {
fn from(access: GpuStorageTextureAccess) -> Self {
match access {
GpuStorageTextureAccess::WriteOnly => {
wgpu_types::StorageTextureAccess::WriteOnly
}
}
}
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuBindGroupLayoutEntry {
@ -171,7 +153,7 @@ impl From<GpuBindingType> for wgpu_types::BindingType {
},
GpuBindingType::StorageTexture(storage_texture) => {
wgpu_types::BindingType::StorageTexture {
access: storage_texture.access.into(),
access: storage_texture.access,
format: storage_texture.format,
view_dimension: storage_texture.view_dimension,
}
@ -215,7 +197,7 @@ pub fn op_webgpu_create_bind_group_layout(
gfx_put!(device => instance.device_create_bind_group_layout(
device,
&descriptor,
()
None
) => state, WebGpuBindGroupLayout)
}
@ -251,7 +233,7 @@ pub fn op_webgpu_create_pipeline_layout(
gfx_put!(device => instance.device_create_pipeline_layout(
device,
&descriptor,
()
None
) => state, super::pipeline::WebGpuPipelineLayout)
}
@ -335,6 +317,6 @@ pub fn op_webgpu_create_bind_group(
gfx_put!(device => instance.device_create_bind_group(
device,
&descriptor,
()
None
) => state, WebGpuBindGroup)
}

View file

@ -26,8 +26,7 @@ impl Resource for WebGpuBuffer {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.buffer_drop(self.1, true));
gfx_select!(self.1 => self.0.buffer_drop(self.1, true));
}
}
@ -65,7 +64,7 @@ pub fn op_webgpu_create_buffer(
gfx_put!(device => instance.device_create_buffer(
device,
&descriptor,
()
None
) => state, WebGpuBuffer)
}
@ -100,14 +99,15 @@ pub async fn op_webgpu_buffer_get_map_async(
// TODO(lucacasonato): error handling
let maybe_err = gfx_select!(buffer => instance.buffer_map_async(
buffer,
offset..(offset + size),
offset,
Some(size),
wgpu_core::resource::BufferMapOperation {
host: match mode {
1 => wgpu_core::device::HostMap::Read,
2 => wgpu_core::device::HostMap::Write,
_ => unreachable!(),
},
callback: wgpu_core::resource::BufferMapCallback::from_rust(callback),
callback: Some(wgpu_core::resource::BufferMapCallback::from_rust(callback)),
}
))
.err();
@ -124,7 +124,7 @@ pub async fn op_webgpu_buffer_get_map_async(
{
let state = state.borrow();
let instance = state.borrow::<super::Instance>();
gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::Wait))
gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::wait()))
.unwrap();
}
tokio::time::sleep(Duration::from_millis(10)).await;

View file

@ -32,8 +32,7 @@ impl Resource for WebGpuRenderBundle {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.render_bundle_drop(self.1));
gfx_select!(self.1 => self.0.render_bundle_drop(self.1));
}
}
@ -118,7 +117,7 @@ pub fn op_webgpu_render_bundle_encoder_finish(
&wgpu_core::command::RenderBundleDescriptor {
label: Some(label),
},
()
None
) => state, WebGpuRenderBundle)
}

View file

@ -6,6 +6,8 @@ use deno_core::op2;
use deno_core::OpState;
use deno_core::ResourceId;
use std::ffi::c_void;
#[cfg(any(target_os = "linux", target_os = "macos"))]
use std::ptr::NonNull;
use crate::surface::WebGpuSurface;
@ -36,8 +38,10 @@ pub fn op_webgpu_surface_create(
}
let (win_handle, display_handle) = raw_window(system, p1, p2)?;
let surface =
instance.instance_create_surface(display_handle, win_handle, ());
// SAFETY: see above comment
let surface = unsafe {
instance.instance_create_surface(display_handle, win_handle, None)?
};
let rid = state
.resource_table
@ -53,22 +57,22 @@ type RawHandles = (
#[cfg(target_os = "macos")]
fn raw_window(
system: &str,
ns_window: *const c_void,
_ns_window: *const c_void,
ns_view: *const c_void,
) -> Result<RawHandles, AnyError> {
if system != "cocoa" {
return Err(type_error("Invalid system on macOS"));
}
let win_handle = {
let mut handle = raw_window_handle::AppKitWindowHandle::empty();
handle.ns_window = ns_window as *mut c_void;
handle.ns_view = ns_view as *mut c_void;
let win_handle = raw_window_handle::RawWindowHandle::AppKit(
raw_window_handle::AppKitWindowHandle::new(
NonNull::new(ns_view as *mut c_void)
.ok_or(type_error("ns_view is null"))?,
),
);
raw_window_handle::RawWindowHandle::AppKit(handle)
};
let display_handle = raw_window_handle::RawDisplayHandle::AppKit(
raw_window_handle::AppKitDisplayHandle::empty(),
raw_window_handle::AppKitDisplayHandle::new(),
);
Ok((win_handle, display_handle))
}
@ -85,17 +89,17 @@ fn raw_window(
}
let win_handle = {
use raw_window_handle::Win32WindowHandle;
let mut handle = Win32WindowHandle::empty();
handle.hwnd = window as *mut c_void;
handle.hinstance = hinstance as *mut c_void;
let mut handle = raw_window_handle::Win32WindowHandle::new(
std::num::NonZeroIsize::new(window as isize)
.ok_or(type_error("window is null"))?,
);
handle.hinstance = std::num::NonZeroIsize::new(hinstance as isize);
raw_window_handle::RawWindowHandle::Win32(handle)
};
let display_handle =
raw_window_handle::RawDisplayHandle::Windows(WindowsDisplayHandle::empty());
raw_window_handle::RawDisplayHandle::Windows(WindowsDisplayHandle::new());
Ok((win_handle, display_handle))
}
@ -107,33 +111,30 @@ fn raw_window(
) -> Result<RawHandles, AnyError> {
let (win_handle, display_handle);
if system == "x11" {
win_handle = {
let mut handle = raw_window_handle::XlibWindowHandle::empty();
handle.window = window as *mut c_void as _;
win_handle = raw_window_handle::RawWindowHandle::Xlib(
raw_window_handle::XlibWindowHandle::new(window as *mut c_void as _),
);
raw_window_handle::RawWindowHandle::Xlib(handle)
};
display_handle = {
let mut handle = raw_window_handle::XlibDisplayHandle::empty();
handle.display = display as *mut c_void;
raw_window_handle::RawDisplayHandle::Xlib(handle)
};
display_handle = raw_window_handle::RawDisplayHandle::Xlib(
raw_window_handle::XlibDisplayHandle::new(
NonNull::new(display as *mut c_void),
0,
),
);
} else if system == "wayland" {
win_handle = {
let mut handle = raw_window_handle::WaylandWindowHandle::empty();
handle.surface = window as _;
win_handle = raw_window_handle::RawWindowHandle::Wayland(
raw_window_handle::WaylandWindowHandle::new(
NonNull::new(window as *mut c_void)
.ok_or(type_error("window is null"))?,
),
);
raw_window_handle::RawWindowHandle::Wayland(handle)
};
display_handle = {
let mut handle = raw_window_handle::WaylandDisplayHandle::empty();
handle.display = display as _;
raw_window_handle::RawDisplayHandle::Wayland(handle)
};
display_handle = raw_window_handle::RawDisplayHandle::Wayland(
raw_window_handle::WaylandDisplayHandle::new(
NonNull::new(display as *mut c_void)
.ok_or(type_error("display is null"))?,
),
);
} else {
return Err(type_error("Invalid system on Linux"));
}

View file

@ -23,8 +23,7 @@ impl Resource for WebGpuCommandEncoder {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.command_encoder_drop(self.1));
gfx_select!(self.1 => self.0.command_encoder_drop(self.1));
}
}
@ -39,8 +38,7 @@ impl Resource for WebGpuCommandBuffer {
fn close(self: Rc<Self>) {
if let Some(id) = *self.1.borrow() {
let instance = &self.0;
gfx_select!(id => instance.command_buffer_drop(id));
gfx_select!(id => self.0.command_buffer_drop(id));
}
}
}
@ -63,7 +61,7 @@ pub fn op_webgpu_create_command_encoder(
gfx_put!(device => instance.device_create_command_encoder(
device,
&descriptor,
()
None
) => state, WebGpuCommandEncoder)
}
@ -493,7 +491,7 @@ pub fn op_webgpu_command_encoder_clear_buffer(
command_encoder,
destination_resource.1,
offset,
std::num::NonZeroU64::new(size)
Some(size)
))
}

View file

@ -34,7 +34,7 @@ pub fn op_webgpu_compute_pass_set_pipeline(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_set_pipeline(
wgpu_core::command::compute_commands::wgpu_compute_pass_set_pipeline(
&mut compute_pass_resource.0.borrow_mut(),
compute_pipeline_resource.1,
);
@ -55,7 +55,7 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_workgroups(
wgpu_core::command::compute_commands::wgpu_compute_pass_dispatch_workgroups(
&mut compute_pass_resource.0.borrow_mut(),
x,
y,
@ -80,7 +80,7 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups_indirect(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_workgroups_indirect(
wgpu_core::command::compute_commands::wgpu_compute_pass_dispatch_workgroups_indirect(
&mut compute_pass_resource.0.borrow_mut(),
buffer_resource.1,
indirect_offset,
@ -142,17 +142,12 @@ pub fn op_webgpu_compute_pass_set_bind_group(
let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len];
// SAFETY: the raw pointer and length are of the same slice, and that slice
// lives longer than the below function invocation.
unsafe {
wgpu_core::command::compute_ffi::wgpu_compute_pass_set_bind_group(
wgpu_core::command::compute_commands::wgpu_compute_pass_set_bind_group(
&mut compute_pass_resource.0.borrow_mut(),
index,
bind_group_resource.1,
dynamic_offsets_data.as_ptr(),
dynamic_offsets_data.len(),
dynamic_offsets_data,
);
}
Ok(WebGpuResult::empty())
}
@ -168,16 +163,11 @@ pub fn op_webgpu_compute_pass_push_debug_group(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
let label = std::ffi::CString::new(group_label).unwrap();
// SAFETY: the string the raw pointer points to lives longer than the below
// function invocation.
unsafe {
wgpu_core::command::compute_ffi::wgpu_compute_pass_push_debug_group(
wgpu_core::command::compute_commands::wgpu_compute_pass_push_debug_group(
&mut compute_pass_resource.0.borrow_mut(),
label.as_ptr(),
group_label,
0, // wgpu#975
);
}
Ok(WebGpuResult::empty())
}
@ -192,7 +182,7 @@ pub fn op_webgpu_compute_pass_pop_debug_group(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
wgpu_core::command::compute_ffi::wgpu_compute_pass_pop_debug_group(
wgpu_core::command::compute_commands::wgpu_compute_pass_pop_debug_group(
&mut compute_pass_resource.0.borrow_mut(),
);
@ -210,16 +200,11 @@ pub fn op_webgpu_compute_pass_insert_debug_marker(
.resource_table
.get::<WebGpuComputePass>(compute_pass_rid)?;
let label = std::ffi::CString::new(marker_label).unwrap();
// SAFETY: the string the raw pointer points to lives longer than the below
// function invocation.
unsafe {
wgpu_core::command::compute_ffi::wgpu_compute_pass_insert_debug_marker(
wgpu_core::command::compute_commands::wgpu_compute_pass_insert_debug_marker(
&mut compute_pass_resource.0.borrow_mut(),
label.as_ptr(),
marker_label,
0, // wgpu#975
);
}
Ok(WebGpuResult::empty())
}

View file

@ -1,4 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError;
use deno_core::ResourceId;
use serde::Serialize;
@ -89,6 +90,7 @@ pub enum WebGpuError {
Lost,
OutOfMemory,
Validation(String),
Internal,
}
impl From<CreateBufferError> for WebGpuError {
@ -106,9 +108,7 @@ impl From<DeviceError> for WebGpuError {
match err {
DeviceError::Lost => WebGpuError::Lost,
DeviceError::OutOfMemory => WebGpuError::OutOfMemory,
DeviceError::ResourceCreationFailed
| DeviceError::Invalid
| DeviceError::WrongDevice => WebGpuError::Validation(fmt_err(&err)),
_ => WebGpuError::Validation(fmt_err(&err)),
}
}
}

View file

@ -24,25 +24,31 @@ pub const UNSTABLE_FEATURE_NAME: &str = "webgpu";
#[macro_use]
mod macros {
macro_rules! gfx_select {
($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {
($id:expr => $p0:ident.$p1:tt.$method:ident $params:tt) => {
gfx_select!($id => {$p0.$p1}, $method $params)
};
($id:expr => $p0:ident.$method:ident $params:tt) => {
gfx_select!($id => {$p0}, $method $params)
};
($id:expr => {$($c:tt)*}, $method:ident $params:tt) => {
match $id.backend() {
#[cfg(any(
all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")),
feature = "vulkan-portability"
))]
wgpu_types::Backend::Vulkan => $global.$method::<wgpu_core::api::Vulkan>( $($param),* ),
wgpu_types::Backend::Vulkan => $($c)*.$method::<wgpu_core::api::Vulkan> $params,
#[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
wgpu_types::Backend::Metal => $global.$method::<wgpu_core::api::Metal>( $($param),* ),
wgpu_types::Backend::Metal => $($c)*.$method::<wgpu_core::api::Metal> $params,
#[cfg(all(not(target_arch = "wasm32"), windows))]
wgpu_types::Backend::Dx12 => $global.$method::<wgpu_core::api::Dx12>( $($param),* ),
#[cfg(all(not(target_arch = "wasm32"), windows))]
wgpu_types::Backend::Dx11 => $global.$method::<wgpu_core::api::Dx11>( $($param),* ),
wgpu_types::Backend::Dx12 => $($c)*.$method::<wgpu_core::api::Dx12> $params,
#[cfg(any(
all(unix, not(target_os = "macos"), not(target_os = "ios")),
feature = "angle",
target_arch = "wasm32"
))]
wgpu_types::Backend::Gl => $global.$method::<wgpu_core::api::Gles>( $($param),+ ),
wgpu_types::Backend::Gl => $($c)*.$method::<wgpu_core::api::Gles> $params,
other => panic!("Unexpected backend {:?}", other),
}
};
@ -79,9 +85,7 @@ pub mod shader;
pub mod surface;
pub mod texture;
pub type Instance = std::sync::Arc<
wgpu_core::global::Global<wgpu_core::identity::IdentityManagerFactory>,
>;
pub type Instance = std::sync::Arc<wgpu_core::global::Global>;
struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId);
impl Resource for WebGpuAdapter {
@ -90,8 +94,7 @@ impl Resource for WebGpuAdapter {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.adapter_drop(self.1));
gfx_select!(self.1 => self.0.adapter_drop(self.1));
}
}
@ -102,8 +105,7 @@ impl Resource for WebGpuDevice {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.device_drop(self.1));
gfx_select!(self.1 => self.0.device_drop(self.1));
}
}
@ -114,8 +116,7 @@ impl Resource for WebGpuQuerySet {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.query_set_drop(self.1));
gfx_select!(self.1 => self.0.query_set_drop(self.1));
}
}
@ -259,6 +260,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) {
return_features.push("bgra8unorm-storage");
}
if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) {
return_features.push("float32-filterable");
}
// extended from spec
@ -367,27 +371,37 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> {
#[derive(Serialize)]
#[serde(untagged)]
pub enum GpuAdapterDeviceOrErr {
pub enum GpuAdapterResOrErr {
Error { err: String },
Features(GpuAdapterDevice),
Features(GpuAdapterRes),
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuAdapterDevice {
pub struct GpuAdapterRes {
rid: ResourceId,
limits: wgpu_types::Limits,
features: Vec<&'static str>,
is_software: bool,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GpuDeviceRes {
rid: ResourceId,
queue_rid: ResourceId,
limits: wgpu_types::Limits,
features: Vec<&'static str>,
is_software: bool,
}
#[op2]
#[serde]
pub fn op_webgpu_request_adapter(
state: Rc<RefCell<OpState>>,
#[serde] power_preference: Option<wgpu_types::PowerPreference>,
force_fallback_adapter: bool,
) -> Result<GpuAdapterDeviceOrErr, AnyError> {
) -> Result<GpuAdapterResOrErr, AnyError> {
let mut state = state.borrow_mut();
// TODO(bartlomieju): replace with `state.feature_checker.check_or_exit`
@ -406,7 +420,6 @@ pub fn op_webgpu_request_adapter(
} else {
state.put(std::sync::Arc::new(wgpu_core::global::Global::new(
"webgpu",
wgpu_core::identity::IdentityManagerFactory,
wgpu_types::InstanceDescriptor {
backends,
flags: wgpu_types::InstanceFlags::from_build_config(),
@ -424,13 +437,13 @@ pub fn op_webgpu_request_adapter(
};
let res = instance.request_adapter(
&descriptor,
wgpu_core::instance::AdapterInputs::Mask(backends, |_| ()),
wgpu_core::instance::AdapterInputs::Mask(backends, |_| None),
);
let adapter = match res {
Ok(adapter) => adapter,
Err(err) => {
return Ok(GpuAdapterDeviceOrErr::Error {
return Ok(GpuAdapterResOrErr::Error {
err: err.to_string(),
})
}
@ -445,7 +458,7 @@ pub fn op_webgpu_request_adapter(
let rid = state.resource_table.add(WebGpuAdapter(instance, adapter));
Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice {
Ok(GpuAdapterResOrErr::Features(GpuAdapterRes {
rid,
features,
limits: adapter_limits,
@ -502,6 +515,10 @@ impl From<GpuRequiredFeatures> for wgpu_types::Features {
wgpu_types::Features::BGRA8UNORM_STORAGE,
required_features.0.contains("bgra8unorm-storage"),
);
features.set(
wgpu_types::Features::FLOAT32_FILTERABLE,
required_features.0.contains("float32-filterable"),
);
// extended from spec
@ -653,7 +670,7 @@ pub fn op_webgpu_request_device(
#[string] label: String,
#[serde] required_features: GpuRequiredFeatures,
#[serde] required_limits: Option<wgpu_types::Limits>,
) -> Result<GpuAdapterDevice, AnyError> {
) -> Result<GpuDeviceRes, AnyError> {
let mut state = state.borrow_mut();
let adapter_resource =
state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
@ -662,15 +679,16 @@ pub fn op_webgpu_request_device(
let descriptor = wgpu_types::DeviceDescriptor {
label: Some(Cow::Owned(label)),
features: required_features.into(),
limits: required_limits.unwrap_or_default(),
required_features: required_features.into(),
required_limits: required_limits.unwrap_or_default(),
};
let (device, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
let (device, queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
adapter,
&descriptor,
std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new),
()
None,
None
));
if let Some(err) = maybe_err {
return Err(DomExceptionOperationError::new(&err.to_string()).into());
@ -682,10 +700,15 @@ pub fn op_webgpu_request_device(
let limits = gfx_select!(device => instance.device_limits(device))?;
let instance = instance.clone();
let instance2 = instance.clone();
let rid = state.resource_table.add(WebGpuDevice(instance, device));
let queue_rid = state
.resource_table
.add(queue::WebGpuQueue(instance2, queue));
Ok(GpuAdapterDevice {
Ok(GpuDeviceRes {
rid,
queue_rid,
features,
limits,
// TODO(lucacasonato): report correctly from wgpu
@ -770,6 +793,6 @@ pub fn op_webgpu_create_query_set(
gfx_put!(device => instance.device_create_query_set(
device,
&descriptor,
()
None
) => state, WebGpuQuerySet)
}

View file

@ -8,6 +8,7 @@ use deno_core::ResourceId;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use std::collections::HashMap;
use std::rc::Rc;
use super::error::WebGpuError;
@ -25,8 +26,7 @@ impl Resource for WebGpuPipelineLayout {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.pipeline_layout_drop(self.1));
gfx_select!(self.1 => self.0.pipeline_layout_drop(self.1));
}
}
@ -40,8 +40,7 @@ impl Resource for WebGpuComputePipeline {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.compute_pipeline_drop(self.1));
gfx_select!(self.1 => self.0.compute_pipeline_drop(self.1));
}
}
@ -55,8 +54,7 @@ impl Resource for WebGpuRenderPipeline {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.render_pipeline_drop(self.1));
gfx_select!(self.1 => self.0.render_pipeline_drop(self.1));
}
}
@ -77,8 +75,8 @@ pub enum GPUPipelineLayoutOrGPUAutoLayoutMode {
#[serde(rename_all = "camelCase")]
pub struct GpuProgrammableStage {
module: ResourceId,
entry_point: String,
// constants: HashMap<String, GPUPipelineConstantValue>
entry_point: Option<String>,
constants: Option<HashMap<String, f64>>,
}
#[op2]
@ -114,16 +112,17 @@ pub fn op_webgpu_create_compute_pipeline(
layout: pipeline_layout,
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: compute_shader_module_resource.1,
entry_point: Cow::from(compute.entry_point),
// TODO(lucacasonato): support args.compute.constants
entry_point: compute.entry_point.map(Cow::from),
constants: Cow::Owned(compute.constants.unwrap_or_default()),
zero_initialize_workgroup_memory: true,
},
};
let implicit_pipelines = match layout {
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
Some(wgpu_core::device::ImplicitPipelineIds {
root_id: (),
group_ids: &[(); MAX_BIND_GROUPS],
root_id: None,
group_ids: &[None; MAX_BIND_GROUPS],
})
}
};
@ -131,7 +130,7 @@ pub fn op_webgpu_create_compute_pipeline(
let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline(
device,
&descriptor,
(),
None,
implicit_pipelines
));
@ -163,7 +162,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
.get::<WebGpuComputePipeline>(compute_pipeline_rid)?;
let compute_pipeline = compute_pipeline_resource.1;
let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, ()));
let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, None));
let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));
@ -285,7 +284,8 @@ impl<'a> From<GpuVertexBufferLayout>
#[serde(rename_all = "camelCase")]
struct GpuVertexState {
module: ResourceId,
entry_point: String,
entry_point: Option<String>,
constants: Option<HashMap<String, f64>>,
buffers: Vec<Option<GpuVertexBufferLayout>>,
}
@ -312,8 +312,8 @@ impl From<GpuMultisampleState> for wgpu_types::MultisampleState {
struct GpuFragmentState {
targets: Vec<Option<wgpu_types::ColorTargetState>>,
module: u32,
entry_point: String,
// TODO(lucacasonato): constants
entry_point: Option<String>,
constants: Option<HashMap<String, f64>>,
}
#[derive(Deserialize)]
@ -364,9 +364,12 @@ pub fn op_webgpu_create_render_pipeline(
Some(wgpu_core::pipeline::FragmentState {
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: fragment_shader_module_resource.1,
entry_point: Cow::from(fragment.entry_point),
entry_point: fragment.entry_point.map(Cow::from),
constants: Cow::Owned(fragment.constants.unwrap_or_default()),
// Required to be true for WebGPU
zero_initialize_workgroup_memory: true,
},
targets: Cow::from(fragment.targets),
targets: Cow::Owned(fragment.targets),
})
} else {
None
@ -386,7 +389,10 @@ pub fn op_webgpu_create_render_pipeline(
vertex: wgpu_core::pipeline::VertexState {
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_shader_module_resource.1,
entry_point: Cow::Owned(args.vertex.entry_point),
entry_point: args.vertex.entry_point.map(Cow::Owned),
constants: Cow::Owned(args.vertex.constants.unwrap_or_default()),
// Required to be true for WebGPU
zero_initialize_workgroup_memory: true,
},
buffers: Cow::Owned(vertex_buffers),
},
@ -401,8 +407,8 @@ pub fn op_webgpu_create_render_pipeline(
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
Some(wgpu_core::device::ImplicitPipelineIds {
root_id: (),
group_ids: &[(); MAX_BIND_GROUPS],
root_id: None,
group_ids: &[None; MAX_BIND_GROUPS],
})
}
};
@ -410,7 +416,7 @@ pub fn op_webgpu_create_render_pipeline(
let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline(
device,
&descriptor,
(),
None,
implicit_pipelines
));
@ -434,7 +440,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout(
.get::<WebGpuRenderPipeline>(render_pipeline_rid)?;
let render_pipeline = render_pipeline_resource.1;
let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, index, ()));
let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, index, None));
let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout));

View file

@ -1,16 +1,28 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::command_encoder::WebGpuCommandBuffer;
use crate::Instance;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult;
type WebGpuQueue = super::WebGpuDevice;
pub struct WebGpuQueue(pub Instance, pub wgpu_core::id::QueueId);
impl Resource for WebGpuQueue {
fn name(&self) -> Cow<str> {
"webGPUQueue".into()
}
fn close(self: Rc<Self>) {
gfx_select!(self.1 => self.0.queue_drop(self.1));
}
}
#[op2]
#[serde]
@ -19,7 +31,7 @@ pub fn op_webgpu_queue_submit(
#[smi] queue_rid: ResourceId,
#[serde] command_buffers: Vec<ResourceId>,
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let instance = state.borrow::<Instance>();
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
let queue = queue_resource.1;
@ -73,7 +85,7 @@ pub fn op_webgpu_write_buffer(
#[number] size: Option<usize>,
#[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let instance = state.borrow::<Instance>();
let buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(buffer)?;
@ -106,7 +118,7 @@ pub fn op_webgpu_write_texture(
#[serde] size: wgpu_types::Extent3d,
#[buffer] buf: &[u8],
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let instance = state.borrow::<Instance>();
let texture_resource = state
.resource_table
.get::<super::texture::WebGpuTexture>(destination.texture)?;

View file

@ -43,7 +43,7 @@ pub fn op_webgpu_render_pass_set_viewport(
.resource_table
.get::<WebGpuRenderPass>(args.render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_set_viewport(
wgpu_core::command::render_commands::wgpu_render_pass_set_viewport(
&mut render_pass_resource.0.borrow_mut(),
args.x,
args.y,
@ -70,7 +70,7 @@ pub fn op_webgpu_render_pass_set_scissor_rect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_set_scissor_rect(
wgpu_core::command::render_commands::wgpu_render_pass_set_scissor_rect(
&mut render_pass_resource.0.borrow_mut(),
x,
y,
@ -92,7 +92,7 @@ pub fn op_webgpu_render_pass_set_blend_constant(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant(
wgpu_core::command::render_commands::wgpu_render_pass_set_blend_constant(
&mut render_pass_resource.0.borrow_mut(),
&color,
);
@ -111,7 +111,7 @@ pub fn op_webgpu_render_pass_set_stencil_reference(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_set_stencil_reference(
wgpu_core::command::render_commands::wgpu_render_pass_set_stencil_reference(
&mut render_pass_resource.0.borrow_mut(),
reference,
);
@ -130,7 +130,7 @@ pub fn op_webgpu_render_pass_begin_occlusion_query(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_begin_occlusion_query(
wgpu_core::command::render_commands::wgpu_render_pass_begin_occlusion_query(
&mut render_pass_resource.0.borrow_mut(),
query_index,
);
@ -148,7 +148,7 @@ pub fn op_webgpu_render_pass_end_occlusion_query(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_end_occlusion_query(
wgpu_core::command::render_commands::wgpu_render_pass_end_occlusion_query(
&mut render_pass_resource.0.borrow_mut(),
);
@ -177,15 +177,10 @@ pub fn op_webgpu_render_pass_execute_bundles(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
// SAFETY: the raw pointer and length are of the same slice, and that slice
// lives longer than the below function invocation.
unsafe {
wgpu_core::command::render_ffi::wgpu_render_pass_execute_bundles(
wgpu_core::command::render_commands::wgpu_render_pass_execute_bundles(
&mut render_pass_resource.0.borrow_mut(),
bundles.as_ptr(),
bundles.len(),
&bundles,
);
}
Ok(WebGpuResult::empty())
}
@ -240,17 +235,12 @@ pub fn op_webgpu_render_pass_set_bind_group(
let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len];
// SAFETY: the raw pointer and length are of the same slice, and that slice
// lives longer than the below function invocation.
unsafe {
wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group(
wgpu_core::command::render_commands::wgpu_render_pass_set_bind_group(
&mut render_pass_resource.0.borrow_mut(),
index,
bind_group_resource.1,
dynamic_offsets_data.as_ptr(),
dynamic_offsets_data.len(),
dynamic_offsets_data,
);
}
Ok(WebGpuResult::empty())
}
@ -266,16 +256,11 @@ pub fn op_webgpu_render_pass_push_debug_group(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
let label = std::ffi::CString::new(group_label).unwrap();
// SAFETY: the string the raw pointer points to lives longer than the below
// function invocation.
unsafe {
wgpu_core::command::render_ffi::wgpu_render_pass_push_debug_group(
wgpu_core::command::render_commands::wgpu_render_pass_push_debug_group(
&mut render_pass_resource.0.borrow_mut(),
label.as_ptr(),
group_label,
0, // wgpu#975
);
}
Ok(WebGpuResult::empty())
}
@ -290,7 +275,7 @@ pub fn op_webgpu_render_pass_pop_debug_group(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_pop_debug_group(
wgpu_core::command::render_commands::wgpu_render_pass_pop_debug_group(
&mut render_pass_resource.0.borrow_mut(),
);
@ -308,16 +293,11 @@ pub fn op_webgpu_render_pass_insert_debug_marker(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
let label = std::ffi::CString::new(marker_label).unwrap();
// SAFETY: the string the raw pointer points to lives longer than the below
// function invocation.
unsafe {
wgpu_core::command::render_ffi::wgpu_render_pass_insert_debug_marker(
wgpu_core::command::render_commands::wgpu_render_pass_insert_debug_marker(
&mut render_pass_resource.0.borrow_mut(),
label.as_ptr(),
marker_label,
0, // wgpu#975
);
}
Ok(WebGpuResult::empty())
}
@ -337,7 +317,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_set_pipeline(
wgpu_core::command::render_commands::wgpu_render_pass_set_pipeline(
&mut render_pass_resource.0.borrow_mut(),
render_pipeline_resource.1,
);
@ -407,7 +387,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer(
None
};
wgpu_core::command::render_ffi::wgpu_render_pass_set_vertex_buffer(
wgpu_core::command::render_commands::wgpu_render_pass_set_vertex_buffer(
&mut render_pass_resource.0.borrow_mut(),
slot,
buffer_resource.1,
@ -432,7 +412,7 @@ pub fn op_webgpu_render_pass_draw(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_draw(
wgpu_core::command::render_commands::wgpu_render_pass_draw(
&mut render_pass_resource.0.borrow_mut(),
vertex_count,
instance_count,
@ -458,7 +438,7 @@ pub fn op_webgpu_render_pass_draw_indexed(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed(
wgpu_core::command::render_commands::wgpu_render_pass_draw_indexed(
&mut render_pass_resource.0.borrow_mut(),
index_count,
instance_count,
@ -485,7 +465,7 @@ pub fn op_webgpu_render_pass_draw_indirect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_draw_indirect(
wgpu_core::command::render_commands::wgpu_render_pass_draw_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.1,
indirect_offset,
@ -509,7 +489,7 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed_indirect(
wgpu_core::command::render_commands::wgpu_render_pass_draw_indexed_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.1,
indirect_offset,

View file

@ -21,8 +21,7 @@ impl Resource for WebGpuSampler {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.sampler_drop(self.1));
gfx_select!(self.1 => self.0.sampler_drop(self.1));
}
}
@ -75,6 +74,6 @@ pub fn op_webgpu_create_sampler(
gfx_put!(device => instance.device_create_sampler(
device,
&descriptor,
()
None
) => state, WebGpuSampler)
}

View file

@ -20,8 +20,7 @@ impl Resource for WebGpuShaderModule {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.shader_module_drop(self.1));
gfx_select!(self.1 => self.0.shader_module_drop(self.1));
}
}
@ -50,6 +49,6 @@ pub fn op_webgpu_create_shader_module(
device,
&descriptor,
source,
()
None
) => state, WebGpuShaderModule)
}

View file

@ -60,6 +60,7 @@ pub fn op_webgpu_surface_configure(
present_mode: args.present_mode.unwrap_or_default(),
alpha_mode: args.alpha_mode,
view_formats: args.view_formats,
desired_maximum_frame_latency: 2,
};
let err =
@ -85,7 +86,7 @@ pub fn op_webgpu_surface_get_current_texture(
let surface = surface_resource.1;
let output =
gfx_select!(device => instance.surface_get_current_texture(surface, ()))?;
gfx_select!(device => instance.surface_get_current_texture(surface, None))?;
match output.status {
SurfaceStatus::Good | SurfaceStatus::Suboptimal => {

View file

@ -39,8 +39,7 @@ impl Resource for WebGpuTextureView {
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.texture_view_drop(self.1, true)).unwrap();
gfx_select!(self.1 => self.0.texture_view_drop(self.1, true)).unwrap();
}
}
@ -84,7 +83,7 @@ pub fn op_webgpu_create_texture(
let (val, maybe_err) = gfx_select!(device => instance.device_create_texture(
device,
&descriptor,
()
None
));
let rid = state.resource_table.add(WebGpuTexture {
@ -129,6 +128,6 @@ pub fn op_webgpu_create_texture_view(
gfx_put!(texture => instance.texture_create_view(
texture,
&descriptor,
()
None
) => state, WebGpuTextureView)
}

View file

@ -6,7 +6,7 @@ dictionary GPUObjectDescriptorBase {
USVString label = "";
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension1D;
readonly attribute unsigned long maxTextureDimension2D;
@ -30,6 +30,8 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxVertexAttributes;
readonly attribute unsigned long maxVertexBufferArrayStride;
readonly attribute unsigned long maxInterStageShaderComponents;
readonly attribute unsigned long maxColorAttachments;
readonly attribute unsigned long maxColorAttachmentBytesPerSample;
readonly attribute unsigned long maxComputeWorkgroupStorageSize;
readonly attribute unsigned long maxComputeInvocationsPerWorkgroup;
readonly attribute unsigned long maxComputeWorkgroupSizeX;
@ -38,12 +40,12 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUSupportedFeatures {
readonly setlike<DOMString>;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUAdapterInfo {
readonly attribute DOMString vendor;
readonly attribute DOMString architecture;
@ -57,9 +59,10 @@ interface mixin NavigatorGPU {
Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPU {
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
GPUTextureFormat getPreferredCanvasFormat();
};
dictionary GPURequestAdapterOptions {
@ -72,14 +75,14 @@ enum GPUPowerPreference {
"high-performance",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUAdapter {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
readonly attribute boolean isFallbackAdapter;
Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {});
Promise<GPUAdapterInfo> requestAdapterInfo(optional sequence<DOMString> unmaskHints = []);
Promise<GPUAdapterInfo> requestAdapterInfo();
};
dictionary GPUDeviceDescriptor
@ -103,6 +106,7 @@ enum GPUFeatureName {
"shader-f16",
"rg11b10ufloat-renderable",
"bgra8unorm-storage",
"float32-filterable",
// extended from spec
@ -140,7 +144,7 @@ enum GPUFeatureName {
"shader-early-depth-test",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
@ -170,7 +174,7 @@ interface GPUDevice : EventTarget {
};
GPUDevice includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUBuffer {
readonly attribute GPUSize64Out size;
readonly attribute GPUFlagsConstant usage;
@ -199,7 +203,7 @@ dictionary GPUBufferDescriptor
};
typedef [EnforceRange] unsigned long GPUBufferUsageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
namespace GPUBufferUsage {
const GPUFlagsConstant MAP_READ = 0x0001;
const GPUFlagsConstant MAP_WRITE = 0x0002;
@ -214,13 +218,13 @@ namespace GPUBufferUsage {
};
typedef [EnforceRange] unsigned long GPUMapModeFlags;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
namespace GPUMapMode {
const GPUFlagsConstant READ = 0x0001;
const GPUFlagsConstant WRITE = 0x0002;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@ -255,7 +259,7 @@ enum GPUTextureDimension {
};
typedef [EnforceRange] unsigned long GPUTextureUsageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
namespace GPUTextureUsage {
const GPUFlagsConstant COPY_SRC = 0x01;
const GPUFlagsConstant COPY_DST = 0x02;
@ -264,7 +268,7 @@ namespace GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUTextureView {
};
GPUTextureView includes GPUObjectBase;
@ -327,6 +331,7 @@ enum GPUTextureFormat {
"bgra8unorm-srgb",
// Packed 32-bit formats
"rgb9e5ufloat",
"rgb10a2uint",
"rgb10a2unorm",
"rg11b10ufloat",
@ -415,7 +420,7 @@ enum GPUTextureFormat {
"astc-12x12-unorm-srgb",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUSampler {
};
GPUSampler includes GPUObjectBase;
@ -461,7 +466,7 @@ enum GPUCompareFunction {
"always",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUBindGroupLayout {
};
GPUBindGroupLayout includes GPUObjectBase;
@ -482,7 +487,7 @@ dictionary GPUBindGroupLayoutEntry {
};
typedef [EnforceRange] unsigned long GPUShaderStageFlags;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
namespace GPUShaderStage {
const GPUFlagsConstant VERTEX = 0x1;
const GPUFlagsConstant FRAGMENT = 0x2;
@ -527,6 +532,8 @@ dictionary GPUTextureBindingLayout {
enum GPUStorageTextureAccess {
"write-only",
"read-only",
"read-write",
};
dictionary GPUStorageTextureBindingLayout {
@ -535,7 +542,7 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d";
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUBindGroup {
};
GPUBindGroup includes GPUObjectBase;
@ -559,7 +566,7 @@ dictionary GPUBufferBinding {
GPUSize64 size;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUPipelineLayout {
};
GPUPipelineLayout includes GPUObjectBase;
@ -569,7 +576,7 @@ dictionary GPUPipelineLayoutDescriptor
required sequence<GPUBindGroupLayout> bindGroupLayouts;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUShaderModule {
};
GPUShaderModule includes GPUObjectBase;
@ -585,7 +592,7 @@ enum GPUCompilationMessageType {
"info",
};
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
[Exposed=(Window, Worker), Serializable, SecureContext]
interface GPUCompilationMessage {
readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type;
@ -595,11 +602,26 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length;
};
[Exposed=(Window, DedicatedWorker), Serializable, SecureContext]
[Exposed=(Window, Worker), Serializable, SecureContext]
interface GPUCompilationInfo {
readonly attribute FrozenArray<GPUCompilationMessage> messages;
};
[Exposed=(Window, Worker), SecureContext, Serializable]
interface GPUPipelineError : DOMException {
constructor(optional DOMString message = "", GPUPipelineErrorInit options);
readonly attribute GPUPipelineErrorReason reason;
};
dictionary GPUPipelineErrorInit {
required GPUPipelineErrorReason reason;
};
enum GPUPipelineErrorReason {
"validation",
"internal",
};
enum GPUAutoLayoutMode {
"auto",
};
@ -615,13 +637,13 @@ interface mixin GPUPipelineBase {
dictionary GPUProgrammableStage {
required GPUShaderModule module;
required USVString entryPoint;
USVString entryPoint;
record<USVString, GPUPipelineConstantValue> constants;
};
typedef double GPUPipelineConstantValue; // May represent WGSLs bool, f32, i32, u32, and f16 if enabled.
typedef double GPUPipelineConstantValue; // May represent WGSL's bool, f32, i32, u32, and f16 if enabled.
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUComputePipeline {
};
GPUComputePipeline includes GPUObjectBase;
@ -632,7 +654,7 @@ dictionary GPUComputePipelineDescriptor
required GPUProgrammableStage compute;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPURenderPipeline {
};
GPURenderPipeline includes GPUObjectBase;
@ -700,7 +722,7 @@ dictionary GPUBlendState {
};
typedef [EnforceRange] unsigned long GPUColorWriteFlags;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
namespace GPUColorWrite {
const GPUFlagsConstant RED = 0x1;
const GPUFlagsConstant GREEN = 0x2;
@ -810,6 +832,7 @@ enum GPUVertexFormat {
"sint32x2",
"sint32x3",
"sint32x4",
"unorm10-10-10-2",
};
enum GPUVertexStepMode {
@ -853,7 +876,7 @@ dictionary GPUImageCopyTexture {
GPUTextureAspect aspect = "all";
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUCommandBuffer {
};
GPUCommandBuffer includes GPUObjectBase;
@ -865,7 +888,7 @@ dictionary GPUCommandBufferDescriptor
interface mixin GPUCommandsMixin {
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@ -932,7 +955,7 @@ interface mixin GPUDebugCommandsMixin {
undefined insertDebugMarker(USVString markerLabel);
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1);
@ -956,7 +979,7 @@ dictionary GPUComputePassDescriptor
GPUComputePassTimestampWrites timestampWrites;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPURenderPassEncoder {
undefined setViewport(float x, float y,
float width, float height,
@ -1051,7 +1074,7 @@ interface mixin GPURenderCommandsMixin {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPURenderBundle {
};
GPURenderBundle includes GPUObjectBase;
@ -1060,7 +1083,7 @@ dictionary GPURenderBundleDescriptor
: GPUObjectDescriptorBase {
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
};
@ -1076,7 +1099,7 @@ dictionary GPURenderBundleEncoderDescriptor
boolean stencilReadOnly = false;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> commandBuffers);
@ -1097,7 +1120,7 @@ interface GPUQueue {
};
GPUQueue includes GPUObjectBase;
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUQuerySet {
undefined destroy();
@ -1117,7 +1140,7 @@ enum GPUQueryType {
"timestamp",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUCanvasContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
@ -1145,7 +1168,7 @@ enum GPUDeviceLostReason {
"destroyed",
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUDeviceLostInfo {
readonly attribute GPUDeviceLostReason reason;
readonly attribute DOMString message;
@ -1155,26 +1178,33 @@ partial interface GPUDevice {
readonly attribute Promise<GPUDeviceLostInfo> lost;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUError {
readonly attribute DOMString message;
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUValidationError
: GPUError {
constructor(DOMString message);
};
[Exposed=(Window, DedicatedWorker), SecureContext]
[Exposed=(Window, Worker), SecureContext]
interface GPUOutOfMemoryError
: GPUError {
constructor(DOMString message);
};
[Exposed=(Window, Worker), SecureContext]
interface GPUInternalError
: GPUError {
constructor(DOMString message);
};
enum GPUErrorFilter {
"validation",
"out-of-memory",
"internal",
};
partial interface GPUDevice {
@ -1182,8 +1212,21 @@ partial interface GPUDevice {
Promise<GPUError?> popErrorScope();
};
[Exposed=(Window, Worker), SecureContext]
interface GPUUncapturedErrorEvent : Event {
constructor(
DOMString type,
GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict
);
[SameObject] readonly attribute GPUError error;
};
dictionary GPUUncapturedErrorEventInit : EventInit {
required GPUError error;
};
partial interface GPUDevice {
[Exposed=(Window, DedicatedWorker)]
[Exposed=(Window, Worker)]
attribute EventHandler onuncapturederror;
};

View file

@ -5145,7 +5145,7 @@ fn lsp_jsr_auto_import_completion() {
json!({ "triggerKind": 1 }),
);
assert!(!list.is_incomplete);
assert_eq!(list.items.len(), 264);
assert_eq!(list.items.len(), 267);
let item = list.items.iter().find(|i| i.label == "add").unwrap();
assert_eq!(&item.label, "add");
assert_eq!(
@ -5225,7 +5225,7 @@ fn lsp_jsr_auto_import_completion_import_map() {
json!({ "triggerKind": 1 }),
);
assert!(!list.is_incomplete);
assert_eq!(list.items.len(), 264);
assert_eq!(list.items.len(), 267);
let item = list.items.iter().find(|i| i.label == "add").unwrap();
assert_eq!(&item.label, "add");
assert_eq!(json!(&item.label_details), json!({ "description": "add" }));

View file

@ -3,9 +3,9 @@
import { join, ROOT_PATH } from "./util.js";
const COMMIT = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4";
const COMMIT = "4521502da69bcf4f92c8350042c268573ef216d4";
const REPO = "gfx-rs/wgpu";
const V_WGPU = "0.18";
const V_WGPU = "0.20";
const TARGET_DIR = join(ROOT_PATH, "ext", "webgpu");
async function bash(subcmd, opts = {}) {