From f5c31b56e3fb57a92dbaaec17690bfa9d787164e Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Sun, 15 May 2022 13:27:56 +0200 Subject: Revert "core: don't include_str extension js code (#10786)" (#14614) This reverts commit 10e50a120744de71d6915af4ae93f8231607573d Alternative to #13217, IMO the tradeoffs made by #10786 aren't worth it. It breaks abstractions (crates being self-contained, deno_core without snapshotting etc...) and causes pain points / gotchas for both embedders & devs for a relatively minimal gain in incremental build time ... Closes #11030 --- ext/url/benches/url_ops.rs | 4 +- ext/web/benches/timers_ops.rs | 10 +- ext/webgpu/01_webgpu.js | 5200 ---------------------------------------- ext/webgpu/02_idl_types.js | 2002 ---------------- ext/webgpu/src/01_webgpu.js | 5200 ++++++++++++++++++++++++++++++++++++++++ ext/webgpu/src/02_idl_types.js | 2002 ++++++++++++++++ 6 files changed, 7207 insertions(+), 7211 deletions(-) delete mode 100644 ext/webgpu/01_webgpu.js delete mode 100644 ext/webgpu/02_idl_types.js create mode 100644 ext/webgpu/src/01_webgpu.js create mode 100644 ext/webgpu/src/02_idl_types.js (limited to 'ext') diff --git a/ext/url/benches/url_ops.rs b/ext/url/benches/url_ops.rs index ed27b6f80..315ea7260 100644 --- a/ext/url/benches/url_ops.rs +++ b/ext/url/benches/url_ops.rs @@ -11,9 +11,7 @@ fn setup() -> Vec { Extension::builder() .js(vec![( "setup", - Box::new(|| { - Ok(r#"const { URL } = globalThis.__bootstrap.url;"#.to_owned()) - }), + "const { URL } = globalThis.__bootstrap.url;", )]) .build(), ] diff --git a/ext/web/benches/timers_ops.rs b/ext/web/benches/timers_ops.rs index 30f50b7d9..f5d03d6c3 100644 --- a/ext/web/benches/timers_ops.rs +++ b/ext/web/benches/timers_ops.rs @@ -26,12 +26,10 @@ fn setup() -> Vec { deno_web::init::(BlobStore::default(), None), Extension::builder() .js(vec![ - ("setup", - Box::new(|| Ok(r#" - const { opNow, setTimeout, handleTimerMacrotask } = globalThis.__bootstrap.timers; - Deno.core.setMacrotaskCallback(handleTimerMacrotask); - "#.to_owned())), - ), + ("setup", r#" + const { opNow, setTimeout, handleTimerMacrotask } = globalThis.__bootstrap.timers; + Deno.core.setMacrotaskCallback(handleTimerMacrotask); + "#), ]) .state(|state| { state.put(Permissions{}); diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js deleted file mode 100644 index be880d81d..000000000 --- a/ext/webgpu/01_webgpu.js +++ /dev/null @@ -1,5200 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -// @ts-check -/// -/// -/// -/// - -"use strict"; - -((window) => { - const core = window.Deno.core; - const webidl = window.__bootstrap.webidl; - const eventTarget = window.__bootstrap.eventTarget; - const { DOMException } = window.__bootstrap.domException; - const { - ArrayBuffer, - ArrayBufferIsView, - ArrayIsArray, - ArrayPrototypeFilter, - ArrayPrototypeMap, - ArrayPrototypePop, - ArrayPrototypePush, - Error, - MathMax, - ObjectDefineProperty, - ObjectFreeze, - ObjectPrototypeIsPrototypeOf, - Promise, - PromiseAll, - PromisePrototypeCatch, - PromisePrototypeThen, - PromiseReject, - PromiseResolve, - SafeArrayIterator, - Set, - SetPrototypeEntries, - SetPrototypeForEach, - SetPrototypeHas, - SetPrototypeKeys, - SetPrototypeValues, - Symbol, - SymbolFor, - SymbolIterator, - TypeError, - Uint32Array, - Uint32ArrayPrototype, - Uint8Array, - } = window.__bootstrap.primordials; - - /** - * @param {any} self - * @param {{prefix: string, context: string}} opts - * @returns {InnerGPUDevice & {rid: number}} - */ - function assertDevice(self, { prefix, context }) { - const device = self[_device]; - const deviceRid = device?.rid; - if (deviceRid === undefined) { - throw new DOMException( - `${prefix}: ${context} references an invalid or destroyed device.`, - "OperationError", - ); - } - return device; - } - - /** - * @param {InnerGPUDevice} self - * @param {any} resource - * @param {{prefix: string, resourceContext: string, selfContext: string}} opts - * @returns {InnerGPUDevice & {rid: number}} - */ - function assertDeviceMatch( - self, - resource, - { prefix, resourceContext, selfContext }, - ) { - const resourceDevice = assertDevice(resource, { - prefix, - context: resourceContext, - }); - if (resourceDevice.rid !== self.rid) { - throw new DOMException( - `${prefix}: ${resourceContext} belongs to a diffent device than ${selfContext}.`, - "OperationError", - ); - } - return { ...resourceDevice, rid: resourceDevice.rid }; - } - - /** - * @param {any} self - * @param {{prefix: string, context: string}} opts - * @returns {number} - */ - function assertResource(self, { prefix, context }) { - const rid = self[_rid]; - if (rid === undefined) { - throw new DOMException( - `${prefix}: ${context} an invalid or destroyed resource.`, - "OperationError", - ); - } - return rid; - } - - /** - * @param {number[] | GPUExtent3DDict} data - * @returns {GPUExtent3DDict} - */ - function normalizeGPUExtent3D(data) { - if (ArrayIsArray(data)) { - return { - width: data[0], - height: data[1], - depthOrArrayLayers: data[2], - }; - } else { - return data; - } - } - - /** - * @param {number[] | GPUOrigin3DDict} data - * @returns {GPUOrigin3DDict} - */ - function normalizeGPUOrigin3D(data) { - if (ArrayIsArray(data)) { - return { - x: data[0], - y: data[1], - z: data[2], - }; - } else { - return data; - } - } - - /** - * @param {number[] | GPUColor} data - * @returns {GPUColor} - */ - function normalizeGPUColor(data) { - if (ArrayIsArray(data)) { - return { - r: data[0], - g: data[1], - b: data[2], - a: data[3], - }; - } else { - return data; - } - } - - class GPUOutOfMemoryError extends Error { - name = "GPUOutOfMemoryError"; - constructor() { - super("device out of memory"); - } - } - const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError.prototype; - - class GPUValidationError extends Error { - name = "GPUValidationError"; - /** @param {string} message */ - constructor(message) { - const prefix = "Failed to construct 'GPUValidationError'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - message = webidl.converters.DOMString(message, { - prefix, - context: "Argument 1", - }); - super(message); - } - } - const GPUValidationErrorPrototype = GPUValidationError.prototype; - - class GPU { - [webidl.brand] = webidl.brand; - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPURequestAdapterOptions} options - */ - async requestAdapter(options = {}) { - webidl.assertBranded(this, GPUPrototype); - options = webidl.converters.GPURequestAdapterOptions(options, { - prefix: "Failed to execute 'requestAdapter' on 'GPU'", - context: "Argument 1", - }); - - const { err, ...data } = await core.opAsync( - "op_webgpu_request_adapter", - { ...options }, - ); - - if (err) { - return null; - } else { - return createGPUAdapter(data.name, data); - } - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect({})}`; - } - } - const GPUPrototype = GPU.prototype; - - const _name = Symbol("[[name]]"); - const _adapter = Symbol("[[adapter]]"); - const _cleanup = Symbol("[[cleanup]]"); - - /** - * @typedef InnerGPUAdapter - * @property {number} rid - * @property {GPUSupportedFeatures} features - * @property {GPUSupportedLimits} limits - * @property {boolean} isFallbackAdapter - */ - - /** - * @param {string} name - * @param {InnerGPUAdapter} inner - * @returns {GPUAdapter} - */ - function createGPUAdapter(name, inner) { - /** @type {GPUAdapter} */ - const adapter = webidl.createBranded(GPUAdapter); - adapter[_name] = name; - adapter[_adapter] = { - ...inner, - features: createGPUSupportedFeatures(inner.features), - limits: createGPUSupportedLimits(inner.limits), - }; - return adapter; - } - - class GPUAdapter { - /** @type {string} */ - [_name]; - /** @type {InnerGPUAdapter} */ - [_adapter]; - - /** @returns {string} */ - get name() { - webidl.assertBranded(this, GPUAdapterPrototype); - return this[_name]; - } - /** @returns {GPUSupportedFeatures} */ - get features() { - webidl.assertBranded(this, GPUAdapterPrototype); - return this[_adapter].features; - } - /** @returns {GPUSupportedLimits} */ - get limits() { - webidl.assertBranded(this, GPUAdapterPrototype); - return this[_adapter].limits; - } - /** @returns {boolean} */ - get isFallbackAdapter() { - return this[_adapter].isFallbackAdapter; - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPUDeviceDescriptor} descriptor - * @returns {Promise} - */ - async requestDevice(descriptor = {}) { - webidl.assertBranded(this, GPUAdapterPrototype); - const prefix = "Failed to execute 'requestDevice' on 'GPUAdapter'"; - descriptor = webidl.converters.GPUDeviceDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const requiredFeatures = descriptor.requiredFeatures ?? []; - for (const feature of requiredFeatures) { - if (!SetPrototypeHas(this[_adapter].features[_features], feature)) { - throw new TypeError( - `${prefix}: nonGuaranteedFeatures must be a subset of the adapter features.`, - ); - } - } - const requiredLimits = descriptor.requiredLimits; - // TODO(lucacasonato): validate requiredLimits - - const { rid, features, limits } = await core.opAsync( - "op_webgpu_request_device", - { - adapterRid: this[_adapter].rid, - labe: descriptor.label, - requiredFeatures, - requiredLimits, - }, - ); - - const inner = new InnerGPUDevice({ - rid, - adapter: this, - features: ObjectFreeze(features), - limits: ObjectFreeze(limits), - }); - return createGPUDevice( - descriptor.label ?? null, - inner, - createGPUQueue(descriptor.label ?? null, inner), - ); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - name: this.name, - features: this.features, - limits: this.limits, - }) - }`; - } - } - const GPUAdapterPrototype = GPUAdapter.prototype; - - const _limits = Symbol("[[limits]]"); - - function createGPUSupportedLimits(features) { - /** @type {GPUSupportedLimits} */ - const adapterFeatures = webidl.createBranded(GPUSupportedLimits); - adapterFeatures[_limits] = features; - return adapterFeatures; - } - - /** - * @typedef InnerAdapterLimits - * @property {number} maxTextureDimension1D - * @property {number} maxTextureDimension2D - * @property {number} maxTextureDimension3D - * @property {number} maxTextureArrayLayers - * @property {number} maxBindGroups - * @property {number} maxDynamicUniformBuffersPerPipelineLayout - * @property {number} maxDynamicStorageBuffersPerPipelineLayout - * @property {number} maxSampledTexturesPerShaderStage - * @property {number} maxSamplersPerShaderStage - * @property {number} maxStorageBuffersPerShaderStage - * @property {number} maxStorageTexturesPerShaderStage - * @property {number} maxUniformBuffersPerShaderStage - * @property {number} maxUniformBufferBindingSize - * @property {number} maxStorageBufferBindingSize - * @property {number} minUniformBufferOffsetAlignment - * @property {number} minStorageBufferOffsetAlignment - * @property {number} maxVertexBuffers - * @property {number} maxVertexAttributes - * @property {number} maxVertexBufferArrayStride - * @property {number} maxInterStageShaderComponents - * @property {number} maxComputeWorkgroupStorageSize - * @property {number} maxComputeInvocationsPerWorkgroup - * @property {number} maxComputeWorkgroupSizeX - * @property {number} maxComputeWorkgroupSizeY - * @property {number} maxComputeWorkgroupSizeZ - * @property {number} maxComputeWorkgroupsPerDimension - */ - - class GPUSupportedLimits { - /** @type {InnerAdapterLimits} */ - [_limits]; - constructor() { - webidl.illegalConstructor(); - } - - get maxTextureDimension1D() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxTextureDimension1D; - } - get maxTextureDimension2D() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxTextureDimension2D; - } - get maxTextureDimension3D() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxTextureDimension3D; - } - get maxTextureArrayLayers() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxTextureArrayLayers; - } - get maxBindGroups() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxBindGroups; - } - get maxDynamicUniformBuffersPerPipelineLayout() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxDynamicUniformBuffersPerPipelineLayout; - } - get maxDynamicStorageBuffersPerPipelineLayout() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxDynamicStorageBuffersPerPipelineLayout; - } - get maxSampledTexturesPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxSampledTexturesPerShaderStage; - } - get maxSamplersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxSamplersPerShaderStage; - } - get maxStorageBuffersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxStorageBuffersPerShaderStage; - } - get maxStorageTexturesPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxStorageTexturesPerShaderStage; - } - get maxUniformBuffersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxUniformBuffersPerShaderStage; - } - get maxUniformBufferBindingSize() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxUniformBufferBindingSize; - } - get maxStorageBufferBindingSize() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxStorageBufferBindingSize; - } - get minUniformBufferOffsetAlignment() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].minUniformBufferOffsetAlignment; - } - get minStorageBufferOffsetAlignment() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].minStorageBufferOffsetAlignment; - } - get maxVertexBuffers() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxVertexBuffers; - } - get maxVertexAttributes() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxVertexAttributes; - } - get maxVertexBufferArrayStride() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxVertexBufferArrayStride; - } - get maxInterStageShaderComponents() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxInterStageShaderComponents; - } - get maxComputeWorkgroupStorageSize() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeWorkgroupStorageSize; - } - get maxComputeInvocationsPerWorkgroup() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeInvocationsPerWorkgroup; - } - get maxComputeWorkgroupSizeX() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeWorkgroupSizeX; - } - get maxComputeWorkgroupSizeY() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeWorkgroupSizeY; - } - get maxComputeWorkgroupSizeZ() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeWorkgroupSizeZ; - } - get maxComputeWorkgroupsPerDimension() { - webidl.assertBranded(this, GPUSupportedLimitsPrototype); - return this[_limits].maxComputeWorkgroupsPerDimension; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect(this[_limits])}`; - } - } - const GPUSupportedLimitsPrototype = GPUSupportedLimits.prototype; - - const _features = Symbol("[[features]]"); - - function createGPUSupportedFeatures(features) { - /** @type {GPUSupportedFeatures} */ - const adapterFeatures = webidl.createBranded(GPUSupportedFeatures); - adapterFeatures[_features] = new Set(features); - return adapterFeatures; - } - - class GPUSupportedFeatures { - /** @type {Set} */ - [_features]; - - constructor() { - webidl.illegalConstructor(); - } - - /** @return {IterableIterator<[string, string]>} */ - entries() { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return SetPrototypeEntries(this[_features]); - } - - /** @return {void} */ - forEach(callbackfn, thisArg) { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - SetPrototypeForEach(this[_features], callbackfn, thisArg); - } - - /** @return {boolean} */ - has(value) { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return SetPrototypeHas(this[_features], value); - } - - /** @return {IterableIterator} */ - keys() { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return SetPrototypeKeys(this[_features]); - } - - /** @return {IterableIterator} */ - values() { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return SetPrototypeValues(this[_features]); - } - - /** @return {number} */ - get size() { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return this[_features].size; - } - - [SymbolIterator]() { - webidl.assertBranded(this, GPUSupportedFeaturesPrototype); - return this[_features][SymbolIterator](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect([...new SafeArrayIterator(this.values())]) - }`; - } - } - - const GPUSupportedFeaturesPrototype = GPUSupportedFeatures.prototype; - - const _reason = Symbol("[[reason]]"); - const _message = Symbol("[[message]]"); - - /** - * @param {string | undefined} reason - * @param {string} message - * @returns {GPUDeviceLostInfo} - */ - function createGPUDeviceLostInfo(reason, message) { - /** @type {GPUDeviceLostInfo} */ - const deviceLostInfo = webidl.createBranded(GPUDeviceLostInfo); - deviceLostInfo[_reason] = reason; - deviceLostInfo[_message] = message; - return deviceLostInfo; - } - - class GPUDeviceLostInfo { - /** @type {string | undefined} */ - [_reason]; - /** @type {string} */ - [_message]; - - constructor() { - webidl.illegalConstructor(); - } - - get reason() { - webidl.assertBranded(this, GPUDeviceLostInfoPrototype); - return this[_reason]; - } - get message() { - webidl.assertBranded(this, GPUDeviceLostInfoPrototype); - return this[_message]; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ reason: this[_reason], message: this[_message] }) - }`; - } - } - - const GPUDeviceLostInfoPrototype = GPUDeviceLostInfo.prototype; - - const _label = Symbol("[[label]]"); - - /** - * @param {string} name - * @param {any} type - */ - function GPUObjectBaseMixin(name, type) { - type.prototype[_label] = null; - ObjectDefineProperty(type.prototype, "label", { - /** - * @return {string | null} - */ - get() { - webidl.assertBranded(this, type.prototype); - return this[_label]; - }, - /** - * @param {string | null} label - */ - set(label) { - webidl.assertBranded(this, type.prototype); - label = webidl.converters["UVString?"](label, { - prefix: `Failed to set 'label' on '${name}'`, - context: "Argument 1", - }); - this[_label] = label; - }, - }); - } - - const _device = Symbol("[[device]]"); - const _queue = Symbol("[[queue]]"); - - /** - * @typedef ErrorScope - * @property {string} filter - * @property {Promise[]} operations - */ - - /** - * @typedef InnerGPUDeviceOptions - * @property {GPUAdapter} adapter - * @property {number | undefined} rid - * @property {GPUFeatureName[]} features - * @property {object} limits - */ - - class InnerGPUDevice { - /** @type {GPUAdapter} */ - adapter; - /** @type {number | undefined} */ - rid; - /** @type {GPUFeatureName[]} */ - features; - /** @type {object} */ - limits; - /** @type {WeakRef[]} */ - resources; - /** @type {boolean} */ - isLost; - /** @type {Promise} */ - lost; - /** @type {(info: GPUDeviceLostInfo) => void} */ - resolveLost; - /** @type {ErrorScope[]} */ - errorScopeStack; - - /** - * @param {InnerGPUDeviceOptions} options - */ - constructor(options) { - this.adapter = options.adapter; - this.rid = options.rid; - this.features = options.features; - this.limits = options.limits; - this.resources = []; - this.isLost = false; - this.resolveLost = () => {}; - this.lost = new Promise((resolve) => { - this.resolveLost = resolve; - }); - this.errorScopeStack = []; - } - - /** @param {any} resource */ - trackResource(resource) { - ArrayPrototypePush(this.resources, new WeakRef(resource)); - } - - /** @param {{ type: string, value: string | null } | undefined} err */ - pushError(err) { - this.pushErrorPromise(PromiseResolve(err)); - } - - /** @param {Promise<{ type: string, value: string | null } | undefined>} promise */ - pushErrorPromise(promise) { - const operation = PromisePrototypeThen(promise, (err) => { - if (err) { - switch (err.type) { - case "lost": - this.isLost = true; - this.resolveLost( - createGPUDeviceLostInfo(undefined, "device was lost"), - ); - break; - case "validation": - return PromiseReject( - new GPUValidationError(err.value ?? "validation error"), - ); - case "out-of-memory": - return PromiseReject(new GPUOutOfMemoryError()); - } - } - }); - - 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); - } - 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( - this.errorScopeStack, - ({ filter }) => filter == "out-of-memory", - ); - 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); - } else { - PromisePrototypeCatch(oomFilteredPromise, () => { - // TODO(lucacasonato): emit an UncapturedErrorEvent - }); - } - // prevent uncaptured promise rejections - PromisePrototypeCatch(oomFilteredPromise, (_err) => {}); - } - } - - /** - * @param {string | null} label - * @param {InnerGPUDevice} inner - * @param {GPUQueue} queue - * @returns {GPUDevice} - */ - function createGPUDevice(label, inner, queue) { - /** @type {GPUDevice} */ - const device = webidl.createBranded(GPUDevice); - device[_label] = label; - device[_device] = inner; - device[_queue] = queue; - return device; - } - - // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging - class GPUDevice extends eventTarget.EventTarget { - /** @type {InnerGPUDevice} */ - [_device]; - - /** @type {GPUQueue} */ - [_queue]; - - [_cleanup]() { - const device = this[_device]; - const resources = device.resources; - while (resources.length > 0) { - const resource = ArrayPrototypePop(resources)?.deref(); - if (resource) { - resource[_cleanup](); - } - } - const rid = device.rid; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - device.rid = undefined; - } - } - - get features() { - webidl.assertBranded(this, GPUDevicePrototype); - return this[_device].features; - } - get limits() { - webidl.assertBranded(this, GPUDevicePrototype); - return this[_device].limits; - } - get queue() { - webidl.assertBranded(this, GPUDevicePrototype); - return this[_queue]; - } - - constructor() { - webidl.illegalConstructor(); - super(); - } - - destroy() { - webidl.assertBranded(this, GPUDevicePrototype); - this[_cleanup](); - } - - /** - * @param {GPUBufferDescriptor} descriptor - * @returns {GPUBuffer} - */ - createBuffer(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createBuffer' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUBufferDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_buffer", { - deviceRid: device.rid, - ...descriptor, - }); - device.pushError(err); - /** @type {CreateGPUBufferOptions} */ - let options; - if (descriptor.mappedAtCreation) { - options = { - mapping: new ArrayBuffer(descriptor.size), - mappingRange: [0, descriptor.size], - mappedRanges: [], - state: "mapped at creation", - }; - } else { - options = { - mapping: null, - mappedRanges: null, - mappingRange: null, - state: "unmapped", - }; - } - const buffer = createGPUBuffer( - descriptor.label ?? null, - device, - rid, - descriptor.size, - descriptor.usage, - options, - ); - device.trackResource(buffer); - return buffer; - } - - /** - * @param {GPUTextureDescriptor} descriptor - * @returns {GPUTexture} - */ - createTexture(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createTexture' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUTextureDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_texture", { - deviceRid: device.rid, - ...descriptor, - size: normalizeGPUExtent3D(descriptor.size), - }); - device.pushError(err); - - const texture = createGPUTexture( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(texture); - return texture; - } - - /** - * @param {GPUSamplerDescriptor} descriptor - * @returns {GPUSampler} - */ - createSampler(descriptor = {}) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createSampler' on 'GPUDevice'"; - descriptor = webidl.converters.GPUSamplerDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_sampler", { - deviceRid: device.rid, - ...descriptor, - }); - device.pushError(err); - - const sampler = createGPUSampler( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(sampler); - return sampler; - } - - /** - * @param {GPUBindGroupLayoutDescriptor} descriptor - * @returns {GPUBindGroupLayout} - */ - createBindGroupLayout(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createBindGroupLayout' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUBindGroupLayoutDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - for (const entry of descriptor.entries) { - let i = 0; - if (entry.buffer) i++; - if (entry.sampler) i++; - if (entry.texture) i++; - if (entry.storageTexture) i++; - - if (i !== 1) { - throw new Error(); // TODO(@crowlKats): correct error - } - } - - const { rid, err } = core.opSync( - "op_webgpu_create_bind_group_layout", - { - deviceRid: device.rid, - ...descriptor, - }, - ); - device.pushError(err); - - const bindGroupLayout = createGPUBindGroupLayout( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(bindGroupLayout); - return bindGroupLayout; - } - - /** - * @param {GPUPipelineLayoutDescriptor} descriptor - * @returns {GPUPipelineLayout} - */ - createPipelineLayout(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createPipelineLayout' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUPipelineLayoutDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const bindGroupLayouts = ArrayPrototypeMap( - descriptor.bindGroupLayouts, - (layout, i) => { - const context = `bind group layout ${i + 1}`; - const rid = assertResource(layout, { prefix, context }); - assertDeviceMatch(device, layout, { - prefix, - selfContext: "this", - resourceContext: context, - }); - return rid; - }, - ); - const { rid, err } = core.opSync("op_webgpu_create_pipeline_layout", { - deviceRid: device.rid, - label: descriptor.label, - bindGroupLayouts, - }); - device.pushError(err); - - const pipelineLayout = createGPUPipelineLayout( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(pipelineLayout); - return pipelineLayout; - } - - /** - * @param {GPUBindGroupDescriptor} descriptor - * @returns {GPUBindGroup} - */ - createBindGroup(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createBindGroup' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUBindGroupDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const layout = assertResource(descriptor.layout, { - prefix, - context: "layout", - }); - assertDeviceMatch(device, descriptor.layout, { - prefix, - resourceContext: "layout", - selfContext: "this", - }); - const entries = ArrayPrototypeMap(descriptor.entries, (entry, i) => { - const context = `entry ${i + 1}`; - 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", - resource: rid, - }; - } else if ( - ObjectPrototypeIsPrototypeOf(GPUTextureViewPrototype, resource) - ) { - 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", - resource: rid, - }; - } else { - const rid = assertResource(resource.buffer, { prefix, context }); - assertDeviceMatch(device, resource.buffer, { - prefix, - resourceContext: context, - selfContext: "this", - }); - return { - binding: entry.binding, - kind: "GPUBufferBinding", - resource: rid, - offset: entry.resource.offset, - size: entry.resource.size, - }; - } - }); - - const { rid, err } = core.opSync("op_webgpu_create_bind_group", { - deviceRid: device.rid, - label: descriptor.label, - layout, - entries, - }); - device.pushError(err); - - const bindGroup = createGPUBindGroup( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(bindGroup); - return bindGroup; - } - - /** - * @param {GPUShaderModuleDescriptor} descriptor - */ - createShaderModule(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createShaderModule' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUShaderModuleDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync( - "op_webgpu_create_shader_module", - { - deviceRid: device.rid, - label: descriptor.label, - code: descriptor.code, - sourceMap: descriptor.sourceMap, - }, - ); - device.pushError(err); - - const shaderModule = createGPUShaderModule( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(shaderModule); - return shaderModule; - } - - /** - * @param {GPUComputePipelineDescriptor} descriptor - * @returns {GPUComputePipeline} - */ - createComputePipeline(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createComputePipeline' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUComputePipelineDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - let layout = undefined; - if (descriptor.layout) { - 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, - context: "compute shader module", - }); - assertDeviceMatch(device, descriptor.compute.module, { - prefix, - resourceContext: "compute shader module", - selfContext: "this", - }); - - const { rid, err } = core.opSync( - "op_webgpu_create_compute_pipeline", - { - deviceRid: device.rid, - label: descriptor.label, - layout, - compute: { - module, - entryPoint: descriptor.compute.entryPoint, - constants: descriptor.compute.constants, - }, - }, - ); - device.pushError(err); - - const computePipeline = createGPUComputePipeline( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(computePipeline); - return computePipeline; - } - - /** - * @param {GPURenderPipelineDescriptor} descriptor - * @returns {GPURenderPipeline} - */ - createRenderPipeline(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createRenderPipeline' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPURenderPipelineDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - let layout = undefined; - if (descriptor.layout) { - 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, - context: "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, - context: "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 } = core.opSync("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); - - const renderPipeline = createGPURenderPipeline( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(renderPipeline); - return renderPipeline; - } - - createComputePipelineAsync(descriptor) { - // TODO(lucacasonato): this should be real async - return PromiseResolve(this.createComputePipeline(descriptor)); - } - - createRenderPipelineAsync(descriptor) { - // TODO(lucacasonato): this should be real async - return PromiseResolve(this.createRenderPipeline(descriptor)); - } - - /** - * @param {GPUCommandEncoderDescriptor} descriptor - * @returns {GPUCommandEncoder} - */ - createCommandEncoder(descriptor = {}) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createCommandEncoder' on 'GPUDevice'"; - descriptor = webidl.converters.GPUCommandEncoderDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_command_encoder", { - deviceRid: device.rid, - ...descriptor, - }); - device.pushError(err); - - const commandEncoder = createGPUCommandEncoder( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(commandEncoder); - return commandEncoder; - } - - /** - * @param {GPURenderBundleEncoderDescriptor} descriptor - * @returns {GPURenderBundleEncoder} - */ - createRenderBundleEncoder(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = - "Failed to execute 'createRenderBundleEncoder' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPURenderBundleEncoderDescriptor( - descriptor, - { - prefix, - context: "Argument 1", - }, - ); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync( - "op_webgpu_create_render_bundle_encoder", - { - deviceRid: device.rid, - ...descriptor, - }, - ); - device.pushError(err); - - const renderBundleEncoder = createGPURenderBundleEncoder( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(renderBundleEncoder); - return renderBundleEncoder; - } - - /** - * @param {GPUQuerySetDescriptor} descriptor - * @returns {GPUQuerySet} - */ - createQuerySet(descriptor) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'createQuerySet' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPUQuerySetDescriptor( - descriptor, - { - prefix, - context: "Argument 1", - }, - ); - const device = assertDevice(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_query_set", { - deviceRid: device.rid, - ...descriptor, - }); - device.pushError(err); - - const querySet = createGPUQuerySet( - descriptor.label ?? null, - device, - rid, - descriptor, - ); - device.trackResource(querySet); - return querySet; - } - - get lost() { - webidl.assertBranded(this, GPUDevicePrototype); - const device = this[_device]; - if (!device) { - return PromiseResolve(true); - } - if (device.rid === undefined) { - return PromiseResolve(true); - } - return device.lost; - } - - /** - * @param {GPUErrorFilter} filter - */ - pushErrorScope(filter) { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'pushErrorScope' on 'GPUDevice'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - filter = webidl.converters.GPUErrorFilter(filter, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - ArrayPrototypePush(device.errorScopeStack, { filter, operations: [] }); - } - - /** - * @returns {Promise} - */ - // deno-lint-ignore require-await - async popErrorScope() { - webidl.assertBranded(this, GPUDevicePrototype); - const prefix = "Failed to execute 'popErrorScope' on 'GPUDevice'"; - const device = assertDevice(this, { prefix, context: "this" }); - if (device.isLost) { - throw new DOMException("Device has been lost.", "OperationError"); - } - const scope = ArrayPrototypePop(device.errorScopeStack); - if (!scope) { - throw new DOMException( - "There are no error scopes on the error scope stack.", - "OperationError", - ); - } - const operations = PromiseAll(scope.operations); - return PromisePrototypeThen( - operations, - () => PromiseResolve(null), - (err) => PromiseResolve(err), - ); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - features: this.features, - label: this.label, - limits: this.limits, - queue: this.queue, - }) - }`; - } - } - GPUObjectBaseMixin("GPUDevice", GPUDevice); - const GPUDevicePrototype = GPUDevice.prototype; - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @returns {GPUQueue} - */ - function createGPUQueue(label, device) { - /** @type {GPUQueue} */ - const queue = webidl.createBranded(GPUQueue); - queue[_label] = label; - queue[_device] = device; - return queue; - } - - class GPUQueue { - /** @type {InnerGPUDevice} */ - [_device]; - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPUCommandBuffer[]} commandBuffers - */ - submit(commandBuffers) { - webidl.assertBranded(this, GPUQueue.prototype); - const prefix = "Failed to execute 'submit' on 'GPUQueue'"; - webidl.requiredArguments(arguments.length, 1, { - prefix, - }); - commandBuffers = webidl.converters["sequence"]( - commandBuffers, - { prefix, context: "Argument 1" }, - ); - const device = assertDevice(this, { prefix, context: "this" }); - const commandBufferRids = ArrayPrototypeMap( - commandBuffers, - (buffer, i) => { - const context = `command buffer ${i + 1}`; - const rid = assertResource(buffer, { prefix, context }); - assertDeviceMatch(device, buffer, { - prefix, - selfContext: "this", - resourceContext: context, - }); - return rid; - }, - ); - const { err } = core.opSync("op_webgpu_queue_submit", { - queueRid: device.rid, - commandBuffers: commandBufferRids, - }); - device.pushError(err); - } - - onSubmittedWorkDone() { - webidl.assertBranded(this, GPUQueue.prototype); - return PromiseResolve(); - } - - /** - * @param {GPUBuffer} buffer - * @param {number} bufferOffset - * @param {BufferSource} data - * @param {number} [dataOffset] - * @param {number} [size] - */ - writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { - webidl.assertBranded(this, GPUQueue.prototype); - const prefix = "Failed to execute 'writeBuffer' on 'GPUQueue'"; - webidl.requiredArguments(arguments.length, 3, { prefix }); - buffer = webidl.converters["GPUBuffer"](buffer, { - prefix, - context: "Argument 1", - }); - bufferOffset = webidl.converters["GPUSize64"](bufferOffset, { - prefix, - context: "Argument 2", - }); - data = webidl.converters.BufferSource(data, { - prefix, - context: "Argument 3", - }); - dataOffset = webidl.converters["GPUSize64"](dataOffset, { - prefix, - context: "Argument 4", - }); - size = size === undefined - ? undefined - : webidl.converters["GPUSize64"](size, { - prefix, - context: "Argument 5", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const bufferRid = assertResource(buffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, buffer, { - prefix, - selfContext: "this", - resourceContext: "Argument 1", - }); - const { err } = core.opSync( - "op_webgpu_write_buffer", - { - queueRid: device.rid, - buffer: bufferRid, - bufferOffset, - dataOffset, - size, - }, - new Uint8Array(ArrayBufferIsView(data) ? data.buffer : data), - ); - device.pushError(err); - } - - /** - * @param {GPUImageCopyTexture} destination - * @param {BufferSource} data - * @param {GPUImageDataLayout} dataLayout - * @param {GPUExtent3D} size - */ - writeTexture(destination, data, dataLayout, size) { - webidl.assertBranded(this, GPUQueue.prototype); - const prefix = "Failed to execute 'writeTexture' on 'GPUQueue'"; - webidl.requiredArguments(arguments.length, 4, { prefix }); - destination = webidl.converters.GPUImageCopyTexture(destination, { - prefix, - context: "Argument 1", - }); - data = webidl.converters.BufferSource(data, { - prefix, - context: "Argument 2", - }); - dataLayout = webidl.converters.GPUImageDataLayout(dataLayout, { - prefix, - context: "Argument 3", - }); - size = webidl.converters.GPUExtent3D(size, { - prefix, - context: "Argument 4", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const textureRid = assertResource(destination.texture, { - prefix, - context: "texture", - }); - assertDeviceMatch(device, destination.texture, { - prefix, - selfContext: "this", - resourceContext: "texture", - }); - const { err } = core.opSync( - "op_webgpu_write_texture", - { - queueRid: device.rid, - destination: { - texture: textureRid, - mipLevel: destination.mipLevel, - origin: destination.origin - ? normalizeGPUOrigin3D(destination.origin) - : undefined, - aspect: destination.aspect, - }, - dataLayout, - size: normalizeGPUExtent3D(size), - }, - new Uint8Array(ArrayBufferIsView(data) ? data.buffer : data), - ); - device.pushError(err); - } - - copyImageBitmapToTexture(_source, _destination, _copySize) { - throw new Error("Not yet implemented"); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUQueue", GPUQueue); - - const _rid = Symbol("[[rid]]"); - - const _size = Symbol("[[size]]"); - const _usage = Symbol("[[usage]]"); - const _state = Symbol("[[state]]"); - const _mappingRange = Symbol("[[mapping_range]]"); - const _mappedRanges = Symbol("[[mapped_ranges]]"); - const _mapMode = Symbol("[[map_mode]]"); - - /** - * @typedef CreateGPUBufferOptions - * @property {ArrayBuffer | null} mapping - * @property {number[] | null} mappingRange - * @property {[ArrayBuffer, number, number][] | null} mappedRanges - * @property {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy" } state - */ - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @param {number} size - * @param {number} usage - * @param {CreateGPUBufferOptions} options - * @returns {GPUBuffer} - */ - function createGPUBuffer(label, device, rid, size, usage, options) { - /** @type {GPUBuffer} */ - const buffer = webidl.createBranded(GPUBuffer); - buffer[_label] = label; - buffer[_device] = device; - buffer[_rid] = rid; - buffer[_size] = size; - buffer[_usage] = usage; - buffer[_mappingRange] = options.mappingRange; - buffer[_mappedRanges] = options.mappedRanges; - buffer[_state] = options.state; - return buffer; - } - - class GPUBuffer { - /** @type {InnerGPUDevice} */ - [_device]; - - /** @type {number} */ - [_rid]; - - /** @type {number} */ - [_size]; - - /** @type {number} */ - [_usage]; - - /** @type {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy"} */ - [_state]; - - /** @type {[number, number] | null} */ - [_mappingRange]; - - /** @type {[ArrayBuffer, number, number][] | null} */ - [_mappedRanges]; - - /** @type {number} */ - [_mapMode]; - - [_cleanup]() { - const mappedRanges = this[_mappedRanges]; - if (mappedRanges) { - while (mappedRanges.length > 0) { - const mappedRange = ArrayPrototypePop(mappedRanges); - if (mappedRange !== undefined) { - core.close(mappedRange[1]); - } - } - } - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - this[_state] = "destroy"; - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {number} mode - * @param {number} offset - * @param {number} [size] - */ - async mapAsync(mode, offset = 0, size) { - webidl.assertBranded(this, GPUBuffer.prototype); - const prefix = "Failed to execute 'mapAsync' on 'GPUBuffer'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - mode = webidl.converters.GPUMapModeFlags(mode, { - prefix, - context: "Argument 1", - }); - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 2", - }); - size = size === undefined - ? undefined - : webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 3", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const bufferRid = assertResource(this, { prefix, context: "this" }); - /** @type {number} */ - let rangeSize; - if (size === undefined) { - rangeSize = MathMax(0, this[_size] - offset); - } else { - rangeSize = this[_size]; - } - if ((offset % 8) !== 0) { - throw new DOMException( - `${prefix}: offset must be a multiple of 8.`, - "OperationError", - ); - } - if ((rangeSize % 4) !== 0) { - throw new DOMException( - `${prefix}: rangeSize must be a multiple of 4.`, - "OperationError", - ); - } - if ((offset + rangeSize) > this[_size]) { - throw new DOMException( - `${prefix}: offset + rangeSize must be less than or equal to buffer size.`, - "OperationError", - ); - } - if (this[_state] !== "unmapped") { - throw new DOMException( - `${prefix}: GPUBuffer is not currently unmapped.`, - "OperationError", - ); - } - const readMode = (mode & 0x0001) === 0x0001; - const writeMode = (mode & 0x0002) === 0x0002; - if ((readMode && writeMode) || (!readMode && !writeMode)) { - throw new DOMException( - `${prefix}: exactly one of READ or WRITE map mode must be set.`, - "OperationError", - ); - } - if (readMode && !((this[_usage] && 0x0001) === 0x0001)) { - throw new DOMException( - `${prefix}: READ map mode not valid because buffer does not have MAP_READ usage.`, - "OperationError", - ); - } - if (writeMode && !((this[_usage] && 0x0002) === 0x0002)) { - throw new DOMException( - `${prefix}: WRITE map mode not valid because buffer does not have MAP_WRITE usage.`, - "OperationError", - ); - } - - this[_mapMode] = mode; - this[_state] = "mapping pending"; - const promise = PromisePrototypeThen( - core.opAsync( - "op_webgpu_buffer_get_map_async", - { - bufferRid, - deviceRid: device.rid, - mode, - offset, - size: rangeSize, - }, - ), - ({ err }) => err, - ); - device.pushErrorPromise(promise); - const err = await promise; - if (err) { - throw new DOMException("validation error occured", "OperationError"); - } - this[_state] = "mapped"; - this[_mappingRange] = [offset, offset + rangeSize]; - /** @type {[ArrayBuffer, number, number][] | null} */ - this[_mappedRanges] = []; - } - - /** - * @param {number} offset - * @param {number} size - */ - getMappedRange(offset = 0, size) { - webidl.assertBranded(this, GPUBuffer.prototype); - const prefix = "Failed to execute 'getMappedRange' on 'GPUBuffer'"; - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 1", - }); - if (size !== undefined) { - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 2", - }); - } - assertDevice(this, { prefix, context: "this" }); - const bufferRid = assertResource(this, { prefix, context: "this" }); - /** @type {number} */ - let rangeSize; - if (size === undefined) { - rangeSize = MathMax(0, this[_size] - offset); - } else { - rangeSize = size; - } - - const mappedRanges = this[_mappedRanges]; - if (!mappedRanges) { - throw new DOMException(`${prefix}: invalid state.`, "OperationError"); - } - for (const [buffer, _rid, start] of mappedRanges) { - // TODO(lucacasonato): is this logic correct? - const end = start + buffer.byteLength; - if ( - (start >= offset && start < (offset + rangeSize)) || - (end >= offset && end < (offset + rangeSize)) - ) { - throw new DOMException( - `${prefix}: requested buffer overlaps with another mapped range.`, - "OperationError", - ); - } - } - - const buffer = new ArrayBuffer(rangeSize); - const { rid } = core.opSync( - "op_webgpu_buffer_get_mapped_range", - { - bufferRid, - offset, - size, - }, - new Uint8Array(buffer), - ); - - ArrayPrototypePush(mappedRanges, [buffer, rid, offset]); - - return buffer; - } - - unmap() { - webidl.assertBranded(this, GPUBuffer.prototype); - const prefix = "Failed to execute 'unmap' on 'GPUBuffer'"; - const device = assertDevice(this, { prefix, context: "this" }); - const bufferRid = assertResource(this, { prefix, context: "this" }); - if (this[_state] === "unmapped" || this[_state] === "destroyed") { - throw new DOMException( - `${prefix}: buffer is not ready to be unmapped.`, - "OperationError", - ); - } - if (this[_state] === "mapping pending") { - // TODO(lucacasonato): this is not spec compliant. - throw new DOMException( - `${prefix}: can not unmap while mapping. This is a Deno limitation.`, - "OperationError", - ); - } else if ( - this[_state] === "mapped" || this[_state] === "mapped at creation" - ) { - /** @type {boolean} */ - let write = false; - if (this[_state] === "mapped at creation") { - write = true; - } else if (this[_state] === "mapped") { - const mapMode = this[_mapMode]; - if (mapMode === undefined) { - throw new DOMException( - `${prefix}: invalid state.`, - "OperationError", - ); - } - if ((mapMode & 0x0002) === 0x0002) { - write = true; - } - } - - const mappedRanges = this[_mappedRanges]; - if (!mappedRanges) { - throw new DOMException(`${prefix}: invalid state.`, "OperationError"); - } - for (const [buffer, mappedRid] of mappedRanges) { - const { err } = core.opSync("op_webgpu_buffer_unmap", { - bufferRid, - mappedRid, - }, ...new SafeArrayIterator(write ? [new Uint8Array(buffer)] : [])); - device.pushError(err); - if (err) return; - } - this[_mappingRange] = null; - this[_mappedRanges] = null; - } - - this[_state] = "unmapped"; - } - - destroy() { - webidl.assertBranded(this, GPUBuffer.prototype); - this[_cleanup](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUBuffer", GPUBuffer); - - class GPUBufferUsage { - constructor() { - webidl.illegalConstructor(); - } - - static get MAP_READ() { - return 0x0001; - } - static get MAP_WRITE() { - return 0x0002; - } - static get COPY_SRC() { - return 0x0004; - } - static get COPY_DST() { - return 0x0008; - } - static get INDEX() { - return 0x0010; - } - static get VERTEX() { - return 0x0020; - } - static get UNIFORM() { - return 0x0040; - } - static get STORAGE() { - return 0x0080; - } - static get INDIRECT() { - return 0x0100; - } - static get QUERY_RESOLVE() { - return 0x0200; - } - } - - class GPUMapMode { - constructor() { - webidl.illegalConstructor(); - } - - static get READ() { - return 0x0001; - } - static get WRITE() { - return 0x0002; - } - } - - const _views = Symbol("[[views]]"); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUTexture} - */ - function createGPUTexture(label, device, rid) { - /** @type {GPUTexture} */ - const texture = webidl.createBranded(GPUTexture); - texture[_label] = label; - texture[_device] = device; - texture[_rid] = rid; - texture[_views] = []; - return texture; - } - - class GPUTexture { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - /** @type {WeakRef[]} */ - [_views]; - - [_cleanup]() { - const views = this[_views]; - while (views.length > 0) { - const view = ArrayPrototypePop(views)?.deref(); - if (view) { - view[_cleanup](); - } - } - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPUTextureViewDescriptor} descriptor - */ - createView(descriptor = {}) { - webidl.assertBranded(this, GPUTexture.prototype); - const prefix = "Failed to execute 'createView' on 'GPUTexture'"; - webidl.requiredArguments(arguments.length, 0, { prefix }); - descriptor = webidl.converters.GPUTextureViewDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const textureRid = assertResource(this, { prefix, context: "this" }); - const { rid, err } = core.opSync("op_webgpu_create_texture_view", { - textureRid, - ...descriptor, - }); - device.pushError(err); - - const textureView = createGPUTextureView( - descriptor.label ?? null, - this, - rid, - ); - ArrayPrototypePush(this[_views], new WeakRef(textureView)); - return textureView; - } - - destroy() { - webidl.assertBranded(this, GPUTexture.prototype); - this[_cleanup](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUTexture", GPUTexture); - - class GPUTextureUsage { - constructor() { - webidl.illegalConstructor(); - } - - static get COPY_SRC() { - return 0x01; - } - static get COPY_DST() { - return 0x02; - } - static get TEXTURE_BINDING() { - return 0x04; - } - static get STORAGE_BINDING() { - return 0x08; - } - static get RENDER_ATTACHMENT() { - return 0x10; - } - } - - const _texture = Symbol("[[texture]]"); - - /** - * @param {string | null} label - * @param {GPUTexture} texture - * @param {number} rid - * @returns {GPUTextureView} - */ - function createGPUTextureView(label, texture, rid) { - /** @type {GPUTextureView} */ - const textureView = webidl.createBranded(GPUTextureView); - textureView[_label] = label; - textureView[_texture] = texture; - textureView[_rid] = rid; - return textureView; - } - class GPUTextureView { - /** @type {GPUTexture} */ - [_texture]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUTextureView", GPUTextureView); - const GPUTextureViewPrototype = GPUTextureView.prototype; - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUSampler} - */ - function createGPUSampler(label, device, rid) { - /** @type {GPUSampler} */ - const sampler = webidl.createBranded(GPUSampler); - sampler[_label] = label; - sampler[_device] = device; - sampler[_rid] = rid; - return sampler; - } - class GPUSampler { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUSampler", GPUSampler); - const GPUSamplerPrototype = GPUSampler.prototype; - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUBindGroupLayout} - */ - function createGPUBindGroupLayout(label, device, rid) { - /** @type {GPUBindGroupLayout} */ - const bindGroupLayout = webidl.createBranded(GPUBindGroupLayout); - bindGroupLayout[_label] = label; - bindGroupLayout[_device] = device; - bindGroupLayout[_rid] = rid; - return bindGroupLayout; - } - class GPUBindGroupLayout { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUBindGroupLayout", GPUBindGroupLayout); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUPipelineLayout} - */ - function createGPUPipelineLayout(label, device, rid) { - /** @type {GPUPipelineLayout} */ - const pipelineLayout = webidl.createBranded(GPUPipelineLayout); - pipelineLayout[_label] = label; - pipelineLayout[_device] = device; - pipelineLayout[_rid] = rid; - return pipelineLayout; - } - class GPUPipelineLayout { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUPipelineLayout", GPUPipelineLayout); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUBindGroup} - */ - function createGPUBindGroup(label, device, rid) { - /** @type {GPUBindGroup} */ - const bindGroup = webidl.createBranded(GPUBindGroup); - bindGroup[_label] = label; - bindGroup[_device] = device; - bindGroup[_rid] = rid; - return bindGroup; - } - class GPUBindGroup { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUBindGroup", GPUBindGroup); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUShaderModule} - */ - function createGPUShaderModule(label, device, rid) { - /** @type {GPUShaderModule} */ - const bindGroup = webidl.createBranded(GPUShaderModule); - bindGroup[_label] = label; - bindGroup[_device] = device; - bindGroup[_rid] = rid; - return bindGroup; - } - class GPUShaderModule { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - compilationInfo() { - throw new Error("Not yet implemented"); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); - - class GPUShaderStage { - constructor() { - webidl.illegalConstructor(); - } - - static get VERTEX() { - return 0x1; - } - - static get FRAGMENT() { - return 0x2; - } - - static get COMPUTE() { - return 0x4; - } - } - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUComputePipeline} - */ - function createGPUComputePipeline(label, device, rid) { - /** @type {GPUComputePipeline} */ - const pipeline = webidl.createBranded(GPUComputePipeline); - pipeline[_label] = label; - pipeline[_device] = device; - pipeline[_rid] = rid; - return pipeline; - } - class GPUComputePipeline { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {number} index - * @returns {GPUBindGroupLayout} - */ - getBindGroupLayout(index) { - webidl.assertBranded(this, GPUComputePipelinePrototype); - const prefix = - "Failed to execute 'getBindGroupLayout' on 'GPUComputePipeline'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - index = webidl.converters["unsigned long"](index, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const computePipelineRid = assertResource(this, { - prefix, - context: "this", - }); - const { rid, label, err } = core.opSync( - "op_webgpu_compute_pipeline_get_bind_group_layout", - { computePipelineRid, index }, - ); - device.pushError(err); - - const bindGroupLayout = createGPUBindGroupLayout( - label, - device, - rid, - ); - device.trackResource(bindGroupLayout); - return bindGroupLayout; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); - const GPUComputePipelinePrototype = GPUComputePipeline.prototype; - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPURenderPipeline} - */ - function createGPURenderPipeline(label, device, rid) { - /** @type {GPURenderPipeline} */ - const pipeline = webidl.createBranded(GPURenderPipeline); - pipeline[_label] = label; - pipeline[_device] = device; - pipeline[_rid] = rid; - return pipeline; - } - class GPURenderPipeline { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {number} index - */ - getBindGroupLayout(index) { - webidl.assertBranded(this, GPURenderPipelinePrototype); - const prefix = - "Failed to execute 'getBindGroupLayout' on 'GPURenderPipeline'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - index = webidl.converters["unsigned long"](index, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderPipelineRid = assertResource(this, { - prefix, - context: "this", - }); - const { rid, label, err } = core.opSync( - "op_webgpu_render_pipeline_get_bind_group_layout", - { renderPipelineRid, index }, - ); - device.pushError(err); - - const bindGroupLayout = createGPUBindGroupLayout( - label, - device, - rid, - ); - device.trackResource(bindGroupLayout); - return bindGroupLayout; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); - const GPURenderPipelinePrototype = GPURenderPipeline.prototype; - - class GPUColorWrite { - constructor() { - webidl.illegalConstructor(); - } - - static get RED() { - return 0x1; - } - static get GREEN() { - return 0x2; - } - static get BLUE() { - return 0x4; - } - static get ALPHA() { - return 0x8; - } - static get ALL() { - return 0xF; - } - } - - const _encoders = Symbol("[[encoders]]"); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUCommandEncoder} - */ - function createGPUCommandEncoder(label, device, rid) { - /** @type {GPUCommandEncoder} */ - const encoder = webidl.createBranded(GPUCommandEncoder); - encoder[_label] = label; - encoder[_device] = device; - encoder[_rid] = rid; - encoder[_encoders] = []; - return encoder; - } - class GPUCommandEncoder { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - /** @type {WeakRef[]} */ - [_encoders]; - - [_cleanup]() { - const encoders = this[_encoders]; - while (encoders.length > 0) { - const encoder = ArrayPrototypePop(encoders)?.deref(); - if (encoder) { - encoder[_cleanup](); - } - } - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPURenderPassDescriptor} descriptor - * @return {GPURenderPassEncoder} - */ - beginRenderPass(descriptor) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - descriptor = webidl.converters.GPURenderPassDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - - if (this[_rid] === undefined) { - throw new DOMException( - "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", - "OperationError", - ); - } - - let depthStencilAttachment; - if (descriptor.depthStencilAttachment) { - const view = assertResource(descriptor.depthStencilAttachment.view, { - prefix, - context: "texture view for depth stencil attachment", - }); - assertDeviceMatch( - device, - descriptor.depthStencilAttachment.view[_texture], - { - prefix, - resourceContext: "texture view for depth stencil attachment", - selfContext: "this", - }, - ); - - depthStencilAttachment = { - ...descriptor.depthStencilAttachment, - view, - }; - - if ( - typeof descriptor.depthStencilAttachment.depthLoadValue === "string" - ) { - depthStencilAttachment.depthLoadOp = - descriptor.depthStencilAttachment.depthLoadValue; - } else { - depthStencilAttachment.depthLoadOp = { - clear: descriptor.depthStencilAttachment.depthLoadValue, - }; - } - - if ( - typeof descriptor.depthStencilAttachment.stencilLoadValue === "string" - ) { - depthStencilAttachment.stencilLoadOp = - descriptor.depthStencilAttachment.stencilLoadValue; - } else { - depthStencilAttachment.stencilLoadOp = { - clear: descriptor.depthStencilAttachment.stencilLoadValue, - }; - } - } - const colorAttachments = ArrayPrototypeMap( - descriptor.colorAttachments, - (colorAttachment, i) => { - const context = `color attachment ${i + 1}`; - const view = assertResource(colorAttachment.view, { - prefix, - context: `texture view for ${context}`, - }); - assertResource(colorAttachment.view[_texture], { - prefix, - context: `texture backing texture view for ${context}`, - }); - assertDeviceMatch( - device, - colorAttachment.view[_texture], - { - prefix, - resourceContext: `texture view for ${context}`, - selfContext: "this", - }, - ); - let resolveTarget; - if (colorAttachment.resolveTarget) { - resolveTarget = assertResource( - colorAttachment.resolveTarget, - { - prefix, - context: `resolve target texture view for ${context}`, - }, - ); - assertResource(colorAttachment.resolveTarget[_texture], { - prefix, - context: - `texture backing resolve target texture view for ${context}`, - }); - assertDeviceMatch( - device, - colorAttachment.resolveTarget[_texture], - { - prefix, - resourceContext: `resolve target texture view for ${context}`, - selfContext: "this", - }, - ); - } - const attachment = { - view: view, - resolveTarget, - storeOp: colorAttachment.storeOp, - }; - - if (typeof colorAttachment.loadValue === "string") { - attachment.loadOp = colorAttachment.loadValue; - } else { - attachment.loadOp = { - clear: normalizeGPUColor(colorAttachment.loadValue), - }; - } - - return attachment; - }, - ); - - const { rid } = core.opSync( - "op_webgpu_command_encoder_begin_render_pass", - { - commandEncoderRid, - ...descriptor, - colorAttachments, - depthStencilAttachment, - }, - ); - - const renderPassEncoder = createGPURenderPassEncoder( - descriptor.label ?? null, - this, - rid, - ); - ArrayPrototypePush(this[_encoders], new WeakRef(renderPassEncoder)); - return renderPassEncoder; - } - - /** - * @param {GPUComputePassDescriptor} descriptor - */ - beginComputePass(descriptor = {}) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; - descriptor = webidl.converters.GPUComputePassDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - - assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - - const { rid } = core.opSync( - "op_webgpu_command_encoder_begin_compute_pass", - { - commandEncoderRid, - ...descriptor, - }, - ); - - const computePassEncoder = createGPUComputePassEncoder( - descriptor.label ?? null, - this, - rid, - ); - ArrayPrototypePush(this[_encoders], new WeakRef(computePassEncoder)); - return computePassEncoder; - } - - /** - * @param {GPUBuffer} source - * @param {number} sourceOffset - * @param {GPUBuffer} destination - * @param {number} destinationOffset - * @param {number} size - */ - copyBufferToBuffer( - source, - sourceOffset, - destination, - destinationOffset, - size, - ) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 5, { prefix }); - source = webidl.converters.GPUBuffer(source, { - prefix, - context: "Argument 1", - }); - sourceOffset = webidl.converters.GPUSize64(sourceOffset, { - prefix, - context: "Argument 2", - }); - destination = webidl.converters.GPUBuffer(destination, { - prefix, - context: "Argument 3", - }); - destinationOffset = webidl.converters.GPUSize64(destinationOffset, { - prefix, - context: "Argument 4", - }); - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 5", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const sourceRid = assertResource(source, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, source, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - const destinationRid = assertResource(destination, { - prefix, - context: "Argument 3", - }); - assertDeviceMatch(device, destination, { - prefix, - resourceContext: "Argument 3", - selfContext: "this", - }); - - const { err } = core.opSync( - "op_webgpu_command_encoder_copy_buffer_to_buffer", - { - commandEncoderRid, - source: sourceRid, - sourceOffset, - destination: destinationRid, - destinationOffset, - size, - }, - ); - device.pushError(err); - } - - /** - * @param {GPUImageCopyBuffer} source - * @param {GPUImageCopyTexture} destination - * @param {GPUExtent3D} copySize - */ - copyBufferToTexture(source, destination, copySize) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 3, { prefix }); - source = webidl.converters.GPUImageCopyBuffer(source, { - prefix, - context: "Argument 1", - }); - destination = webidl.converters.GPUImageCopyTexture(destination, { - prefix, - context: "Argument 2", - }); - copySize = webidl.converters.GPUExtent3D(copySize, { - prefix, - context: "Argument 3", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const sourceBufferRid = assertResource(source.buffer, { - prefix, - context: "source in Argument 1", - }); - assertDeviceMatch(device, source.buffer, { - prefix, - resourceContext: "source in Argument 1", - selfContext: "this", - }); - const destinationTextureRid = assertResource(destination.texture, { - prefix, - context: "texture in Argument 2", - }); - assertDeviceMatch(device, destination.texture, { - prefix, - resourceContext: "texture in Argument 2", - selfContext: "this", - }); - - const { err } = core.opSync( - "op_webgpu_command_encoder_copy_buffer_to_texture", - { - commandEncoderRid, - source: { - ...source, - buffer: sourceBufferRid, - }, - destination: { - texture: destinationTextureRid, - mipLevel: destination.mipLevel, - origin: destination.origin - ? normalizeGPUOrigin3D(destination.origin) - : undefined, - aspect: destination.aspect, - }, - copySize: normalizeGPUExtent3D(copySize), - }, - ); - device.pushError(err); - } - - /** - * @param {GPUImageCopyTexture} source - * @param {GPUImageCopyBuffer} destination - * @param {GPUExtent3D} copySize - */ - copyTextureToBuffer(source, destination, copySize) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 3, { prefix }); - source = webidl.converters.GPUImageCopyTexture(source, { - prefix, - context: "Argument 1", - }); - destination = webidl.converters.GPUImageCopyBuffer(destination, { - prefix, - context: "Argument 2", - }); - copySize = webidl.converters.GPUExtent3D(copySize, { - prefix, - context: "Argument 3", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const sourceTextureRid = assertResource(source.texture, { - prefix, - context: "texture in Argument 1", - }); - assertDeviceMatch(device, source.texture, { - prefix, - resourceContext: "texture in Argument 1", - selfContext: "this", - }); - const destinationBufferRid = assertResource(destination.buffer, { - prefix, - context: "buffer in Argument 2", - }); - assertDeviceMatch(device, destination.buffer, { - prefix, - resourceContext: "buffer in Argument 2", - selfContext: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_copy_texture_to_buffer", - { - commandEncoderRid, - source: { - texture: sourceTextureRid, - mipLevel: source.mipLevel, - origin: source.origin - ? normalizeGPUOrigin3D(source.origin) - : undefined, - aspect: source.aspect, - }, - destination: { - ...destination, - buffer: destinationBufferRid, - }, - copySize: normalizeGPUExtent3D(copySize), - }, - ); - device.pushError(err); - } - - /** - * @param {GPUImageCopyTexture} source - * @param {GPUImageCopyTexture} destination - * @param {GPUExtent3D} copySize - */ - copyTextureToTexture(source, destination, copySize) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 3, { prefix }); - source = webidl.converters.GPUImageCopyTexture(source, { - prefix, - context: "Argument 1", - }); - destination = webidl.converters.GPUImageCopyTexture(destination, { - prefix, - context: "Argument 2", - }); - copySize = webidl.converters.GPUExtent3D(copySize, { - prefix, - context: "Argument 3", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const sourceTextureRid = assertResource(source.texture, { - prefix, - context: "texture in Argument 1", - }); - assertDeviceMatch(device, source.texture, { - prefix, - resourceContext: "texture in Argument 1", - selfContext: "this", - }); - const destinationTextureRid = assertResource(destination.texture, { - prefix, - context: "texture in Argument 2", - }); - assertDeviceMatch(device, destination.texture, { - prefix, - resourceContext: "texture in Argument 2", - selfContext: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_copy_texture_to_texture", - { - commandEncoderRid, - source: { - texture: sourceTextureRid, - mipLevel: source.mipLevel, - origin: source.origin - ? normalizeGPUOrigin3D(source.origin) - : undefined, - aspect: source.aspect, - }, - destination: { - texture: destinationTextureRid, - mipLevel: destination.mipLevel, - origin: destination.origin - ? normalizeGPUOrigin3D(destination.origin) - : undefined, - aspect: source.aspect, - }, - copySize: normalizeGPUExtent3D(copySize), - }, - ); - device.pushError(err); - } - - /** - * @param {GPUBuffer} destination - * @param {GPUSize64} destinationOffset - * @param {GPUSize64} size - */ - clearBuffer(destination, destinationOffset, size) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = "Failed to execute 'clearBuffer' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 3, { prefix }); - destination = webidl.converters.GPUBuffer(destination, { - prefix, - context: "Argument 1", - }); - destinationOffset = webidl.converters.GPUSize64(destinationOffset, { - prefix, - context: "Argument 2", - }); - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 3", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const destinationRid = assertResource(destination, { - prefix, - context: "Argument 1", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_clear_buffer", - { - commandEncoderRid, - destinationRid, - destinationOffset, - size, - }, - ); - device.pushError(err); - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.USVString(groupLabel, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_push_debug_group", - { - commandEncoderRid, - groupLabel, - }, - ); - device.pushError(err); - } - - popDebugGroup() { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder'"; - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_pop_debug_group", - { - commandEncoderRid, - }, - ); - device.pushError(err); - } - - /** - * @param {string} markerLabel - */ - insertDebugMarker(markerLabel) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.USVString(markerLabel, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_insert_debug_marker", - { - commandEncoderRid, - markerLabel, - }, - ); - device.pushError(err); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - writeTimestamp(querySet, queryIndex) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - queryIndex = webidl.converters.GPUSize32(queryIndex, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_write_timestamp", - { - commandEncoderRid, - querySet: querySetRid, - queryIndex, - }, - ); - device.pushError(err); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} firstQuery - * @param {number} queryCount - * @param {GPUBuffer} destination - * @param {number} destinationOffset - */ - resolveQuerySet( - querySet, - firstQuery, - queryCount, - destination, - destinationOffset, - ) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = - "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; - webidl.requiredArguments(arguments.length, 5, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - firstQuery = webidl.converters.GPUSize32(firstQuery, { - prefix, - context: "Argument 2", - }); - queryCount = webidl.converters.GPUSize32(queryCount, { - prefix, - context: "Argument 3", - }); - destination = webidl.converters.GPUBuffer(destination, { - prefix, - context: "Argument 4", - }); - destinationOffset = webidl.converters.GPUSize64(destinationOffset, { - prefix, - context: "Argument 5", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - const destinationRid = assertResource(destination, { - prefix, - context: "Argument 3", - }); - assertDeviceMatch(device, destination, { - prefix, - resourceContext: "Argument 3", - selfContext: "this", - }); - const { err } = core.opSync( - "op_webgpu_command_encoder_resolve_query_set", - { - commandEncoderRid, - querySet: querySetRid, - firstQuery, - queryCount, - destination: destinationRid, - destinationOffset, - }, - ); - device.pushError(err); - } - - /** - * @param {GPUCommandBufferDescriptor} descriptor - * @returns {GPUCommandBuffer} - */ - finish(descriptor = {}) { - webidl.assertBranded(this, GPUCommandEncoderPrototype); - const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; - descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const commandEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const { rid, err } = core.opSync("op_webgpu_command_encoder_finish", { - commandEncoderRid, - ...descriptor, - }); - device.pushError(err); - /** @type {number | undefined} */ - this[_rid] = undefined; - - const commandBuffer = createGPUCommandBuffer( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(commandBuffer); - return commandBuffer; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); - const GPUCommandEncoderPrototype = GPUCommandEncoder.prototype; - - const _encoder = Symbol("[[encoder]]"); - - /** - * @param {string | null} label - * @param {GPUCommandEncoder} encoder - * @param {number} rid - * @returns {GPURenderPassEncoder} - */ - function createGPURenderPassEncoder(label, encoder, rid) { - /** @type {GPURenderPassEncoder} */ - const passEncoder = webidl.createBranded(GPURenderPassEncoder); - passEncoder[_label] = label; - passEncoder[_encoder] = encoder; - passEncoder[_rid] = rid; - return passEncoder; - } - - class GPURenderPassEncoder { - /** @type {GPUCommandEncoder} */ - [_encoder]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height - * @param {number} minDepth - * @param {number} maxDepth - */ - setViewport(x, y, width, height, minDepth, maxDepth) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setViewport' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 6, { prefix }); - x = webidl.converters.float(x, { prefix, context: "Argument 1" }); - y = webidl.converters.float(y, { prefix, context: "Argument 2" }); - width = webidl.converters.float(width, { prefix, context: "Argument 3" }); - height = webidl.converters.float(height, { - prefix, - context: "Argument 4", - }); - minDepth = webidl.converters.float(minDepth, { - prefix, - context: "Argument 5", - }); - maxDepth = webidl.converters.float(maxDepth, { - prefix, - context: "Argument 6", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_set_viewport", { - renderPassRid, - x, - y, - width, - height, - minDepth, - maxDepth, - }); - } - - /** - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height - */ - setScissorRect(x, y, width, height) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setScissorRect' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 4, { prefix }); - x = webidl.converters.GPUIntegerCoordinate(x, { - prefix, - context: "Argument 1", - }); - y = webidl.converters.GPUIntegerCoordinate(y, { - prefix, - context: "Argument 2", - }); - width = webidl.converters.GPUIntegerCoordinate(width, { - prefix, - context: "Argument 3", - }); - height = webidl.converters.GPUIntegerCoordinate(height, { - prefix, - context: "Argument 4", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_set_scissor_rect", { - renderPassRid, - x, - y, - width, - height, - }); - } - - /** - * @param {GPUColor} color - */ - setBlendConstant(color) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setBlendConstant' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - color = webidl.converters.GPUColor(color, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_set_blend_constant", { - renderPassRid, - color: normalizeGPUColor(color), - }); - } - - /** - * @param {number} reference - */ - setStencilReference(reference) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - reference = webidl.converters.GPUStencilValue(reference, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_set_stencil_reference", { - renderPassRid, - reference, - }); - } - - beginOcclusionQuery(_queryIndex) { - throw new Error("Not yet implemented"); - } - - endOcclusionQuery() { - throw new Error("Not yet implemented"); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - beginPipelineStatisticsQuery(querySet, queryIndex) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - queryIndex = webidl.converters.GPUSize32(queryIndex, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { - renderPassRid, - querySet: querySetRid, - queryIndex, - }); - } - - endPipelineStatisticsQuery() { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_end_pipeline_statistics_query", { - renderPassRid, - }); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - writeTimestamp(querySet, queryIndex) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - queryIndex = webidl.converters.GPUSize32(queryIndex, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_write_timestamp", { - renderPassRid, - querySet: querySetRid, - queryIndex, - }); - } - - /** - * @param {GPURenderBundle[]} bundles - */ - executeBundles(bundles) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - bundles = webidl.converters["sequence"](bundles, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const bundleRids = ArrayPrototypeMap(bundles, (bundle, i) => { - const context = `bundle ${i + 1}`; - const rid = assertResource(bundle, { prefix, context }); - assertDeviceMatch(device, bundle, { - prefix, - resourceContext: context, - selfContext: "this", - }); - return rid; - }); - core.opSync("op_webgpu_render_pass_execute_bundles", { - renderPassRid, - bundles: bundleRids, - }); - } - - endPass() { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const commandEncoderRid = assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const { err } = core.opSync("op_webgpu_render_pass_end_pass", { - commandEncoderRid, - renderPassRid, - }); - device.pushError(err); - this[_rid] = undefined; - } - - // TODO(lucacasonato): has an overload - setBindGroup( - index, - bindGroup, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - ) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setBindGroup' on 'GPURenderPassEncoder'"; - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const bindGroupRid = assertResource(bindGroup, { - prefix, - context: "Argument 2", - }); - assertDeviceMatch(device, bindGroup, { - prefix, - resourceContext: "Argument 2", - selfContext: "this", - }); - if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) - ) { - dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); - dynamicOffsetsDataStart = 0; - dynamicOffsetsDataLength = dynamicOffsetsData.length; - } - core.opSync("op_webgpu_render_pass_set_bind_group", { - renderPassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }); - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.USVString(groupLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_push_debug_group", { - renderPassRid, - groupLabel, - }); - } - - popDebugGroup() { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder'"; - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_pop_debug_group", { - renderPassRid, - }); - } - - /** - * @param {string} markerLabel - */ - insertDebugMarker(markerLabel) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.USVString(markerLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_insert_debug_marker", { - renderPassRid, - markerLabel, - }); - } - - /** - * @param {GPURenderPipeline} pipeline - */ - setPipeline(pipeline) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setPipeline' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - pipeline = webidl.converters.GPURenderPipeline(pipeline, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const pipelineRid = assertResource(pipeline, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, pipeline, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_set_pipeline", { - renderPassRid, - pipeline: pipelineRid, - }); - } - - /** - * @param {GPUBuffer} buffer - * @param {GPUIndexFormat} indexFormat - * @param {number} offset - * @param {number} size - */ - setIndexBuffer(buffer, indexFormat, offset = 0, size) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - buffer = webidl.converters.GPUBuffer(buffer, { - prefix, - context: "Argument 1", - }); - indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { - prefix, - context: "Argument 2", - }); - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 3", - }); - if (size !== undefined) { - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 4", - }); - } - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const bufferRid = assertResource(buffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, buffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_set_index_buffer", { - renderPassRid, - buffer: bufferRid, - indexFormat, - offset, - size, - }); - } - - /** - * @param {number} slot - * @param {GPUBuffer} buffer - * @param {number} offset - * @param {number} size - */ - setVertexBuffer(slot, buffer, offset = 0, size) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - slot = webidl.converters.GPUSize32(slot, { - prefix, - context: "Argument 2", - }); - buffer = webidl.converters.GPUBuffer(buffer, { - prefix, - context: "Argument 2", - }); - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 3", - }); - if (size !== undefined) { - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 4", - }); - } - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const bufferRid = assertResource(buffer, { - prefix, - context: "Argument 2", - }); - assertDeviceMatch(device, buffer, { - prefix, - resourceContext: "Argument 2", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_set_vertex_buffer", { - renderPassRid, - slot, - buffer: bufferRid, - offset, - size, - }); - } - - /** - * @param {number} vertexCount - * @param {number} instanceCount - * @param {number} firstVertex - * @param {number} firstInstance - */ - draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = "Failed to execute 'draw' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - vertexCount = webidl.converters.GPUSize32(vertexCount, { - prefix, - context: "Argument 1", - }); - instanceCount = webidl.converters.GPUSize32(instanceCount, { - prefix, - context: "Argument 2", - }); - firstVertex = webidl.converters.GPUSize32(firstVertex, { - prefix, - context: "Argument 3", - }); - firstInstance = webidl.converters.GPUSize32(firstInstance, { - prefix, - context: "Argument 4", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_draw", { - renderPassRid, - vertexCount, - instanceCount, - firstVertex, - firstInstance, - }); - } - - /** - * @param {number} indexCount - * @param {number} instanceCount - * @param {number} firstIndex - * @param {number} baseVertex - * @param {number} firstInstance - */ - drawIndexed( - indexCount, - instanceCount = 1, - firstIndex = 0, - baseVertex = 0, - firstInstance = 0, - ) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - indexCount = webidl.converters.GPUSize32(indexCount, { - prefix, - context: "Argument 1", - }); - instanceCount = webidl.converters.GPUSize32(instanceCount, { - prefix, - context: "Argument 2", - }); - firstIndex = webidl.converters.GPUSize32(firstIndex, { - prefix, - context: "Argument 3", - }); - baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { - prefix, - context: "Argument 4", - }); - firstInstance = webidl.converters.GPUSize32(firstInstance, { - prefix, - context: "Argument 5", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_render_pass_draw_indexed", { - renderPassRid, - indexCount, - instanceCount, - firstIndex, - baseVertex, - firstInstance, - }); - } - - /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset - */ - drawIndirect(indirectBuffer, indirectOffset) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { - prefix, - context: "Argument 1", - }); - indirectOffset = webidl.converters.GPUSize64(indirectOffset, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const indirectBufferRid = assertResource(indirectBuffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, indirectBuffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_draw_indirect", { - renderPassRid, - indirectBuffer: indirectBufferRid, - indirectOffset, - }); - } - - /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset - */ - drawIndexedIndirect(indirectBuffer, indirectOffset) { - webidl.assertBranded(this, GPURenderPassEncoderPrototype); - const prefix = - "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { - prefix, - context: "Argument 1", - }); - indirectOffset = webidl.converters.GPUSize64(indirectOffset, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const renderPassRid = assertResource(this, { prefix, context: "this" }); - const indirectBufferRid = assertResource(indirectBuffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, indirectBuffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_pass_draw_indexed_indirect", { - renderPassRid, - indirectBuffer: indirectBufferRid, - indirectOffset, - }); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPURenderPassEncoder", GPURenderPassEncoder); - const GPURenderPassEncoderPrototype = GPURenderPassEncoder.prototype; - - /** - * @param {string | null} label - * @param {GPUCommandEncoder} encoder - * @param {number} rid - * @returns {GPUComputePassEncoder} - */ - function createGPUComputePassEncoder(label, encoder, rid) { - /** @type {GPUComputePassEncoder} */ - const computePassEncoder = webidl.createBranded(GPUComputePassEncoder); - computePassEncoder[_label] = label; - computePassEncoder[_encoder] = encoder; - computePassEncoder[_rid] = rid; - return computePassEncoder; - } - - class GPUComputePassEncoder { - /** @type {GPUCommandEncoder} */ - [_encoder]; - - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPUComputePipeline} pipeline - */ - setPipeline(pipeline) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'setPipeline' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - pipeline = webidl.converters.GPUComputePipeline(pipeline, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const pipelineRid = assertResource(pipeline, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, pipeline, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_compute_pass_set_pipeline", { - computePassRid, - pipeline: pipelineRid, - }); - } - - /** - * @param {number} x - * @param {number} y - * @param {number} z - */ - dispatch(x, y = 1, z = 1) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); - y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); - z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_compute_pass_dispatch", { - computePassRid, - x, - y, - z, - }); - } - - /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset - */ - dispatchIndirect(indirectBuffer, indirectOffset) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { - prefix, - context: "Argument 1", - }); - indirectOffset = webidl.converters.GPUSize64(indirectOffset, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const indirectBufferRid = assertResource(indirectBuffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, indirectBuffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_compute_pass_dispatch_indirect", { - computePassRid: computePassRid, - indirectBuffer: indirectBufferRid, - indirectOffset, - }); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - beginPipelineStatisticsQuery(querySet, queryIndex) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - queryIndex = webidl.converters.GPUSize32(queryIndex, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync( - "op_webgpu_compute_pass_begin_pipeline_statistics_query", - { - computePassRid, - querySet: querySetRid, - queryIndex, - }, - ); - } - - endPipelineStatisticsQuery() { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { - computePassRid, - }); - } - - /** - * @param {GPUQuerySet} querySet - * @param {number} queryIndex - */ - writeTimestamp(querySet, queryIndex) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - querySet = webidl.converters.GPUQuerySet(querySet, { - prefix, - context: "Argument 1", - }); - queryIndex = webidl.converters.GPUSize32(queryIndex, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const querySetRid = assertResource(querySet, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, querySet, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_compute_pass_write_timestamp", { - computePassRid, - querySet: querySetRid, - queryIndex, - }); - } - - endPass() { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = "Failed to execute 'endPass' on 'GPUComputePassEncoder'"; - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const commandEncoderRid = assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const { err } = core.opSync("op_webgpu_compute_pass_end_pass", { - commandEncoderRid, - computePassRid, - }); - device.pushError(err); - this[_rid] = undefined; - } - - // TODO(lucacasonato): has an overload - setBindGroup( - index, - bindGroup, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - ) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; - const device = assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - const bindGroupRid = assertResource(bindGroup, { - prefix, - context: "Argument 2", - }); - assertDeviceMatch(device, bindGroup, { - prefix, - resourceContext: "Argument 2", - selfContext: "this", - }); - if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) - ) { - dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); - dynamicOffsetsDataStart = 0; - dynamicOffsetsDataLength = dynamicOffsetsData.length; - } - core.opSync("op_webgpu_compute_pass_set_bind_group", { - computePassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }); - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.USVString(groupLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_compute_pass_push_debug_group", { - computePassRid, - groupLabel, - }); - } - - popDebugGroup() { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder'"; - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_compute_pass_pop_debug_group", { - computePassRid, - }); - } - - /** - * @param {string} markerLabel - */ - insertDebugMarker(markerLabel) { - webidl.assertBranded(this, GPUComputePassEncoderPrototype); - const prefix = - "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.USVString(markerLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - assertResource(this[_encoder], { - prefix, - context: "encoder referenced by this", - }); - const computePassRid = assertResource(this, { prefix, context: "this" }); - core.opSync("op_webgpu_compute_pass_insert_debug_marker", { - computePassRid, - markerLabel, - }); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUComputePassEncoder", GPUComputePassEncoder); - const GPUComputePassEncoderPrototype = GPUComputePassEncoder.prototype; - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUCommandBuffer} - */ - function createGPUCommandBuffer(label, device, rid) { - /** @type {GPUCommandBuffer} */ - const commandBuffer = webidl.createBranded(GPUCommandBuffer); - commandBuffer[_label] = label; - commandBuffer[_device] = device; - commandBuffer[_rid] = rid; - return commandBuffer; - } - - class GPUCommandBuffer { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUCommandBuffer", GPUCommandBuffer); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPURenderBundleEncoder} - */ - function createGPURenderBundleEncoder(label, device, rid) { - /** @type {GPURenderBundleEncoder} */ - const bundleEncoder = webidl.createBranded(GPURenderBundleEncoder); - bundleEncoder[_label] = label; - bundleEncoder[_device] = device; - bundleEncoder[_rid] = rid; - return bundleEncoder; - } - - class GPURenderBundleEncoder { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPURenderBundleDescriptor} descriptor - */ - finish(descriptor = {}) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'"; - descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const { rid, err } = core.opSync( - "op_webgpu_render_bundle_encoder_finish", - { - renderBundleEncoderRid, - ...descriptor, - }, - ); - device.pushError(err); - this[_rid] = undefined; - - const renderBundle = createGPURenderBundle( - descriptor.label ?? null, - device, - rid, - ); - device.trackResource(renderBundle); - return renderBundle; - } - - // TODO(lucacasonato): has an overload - setBindGroup( - index, - bindGroup, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - ) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'setBindGroup' on 'GPURenderBundleEncoder'"; - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const bindGroupRid = assertResource(bindGroup, { - prefix, - context: "Argument 2", - }); - assertDeviceMatch(device, bindGroup, { - prefix, - resourceContext: "Argument 2", - selfContext: "this", - }); - if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) - ) { - dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); - dynamicOffsetsDataStart = 0; - dynamicOffsetsDataLength = dynamicOffsetsData.length; - } - core.opSync("op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }); - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - groupLabel = webidl.converters.USVString(groupLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid, - groupLabel, - }); - } - - popDebugGroup() { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'popDebugGroup' on 'GPURenderBundleEncoder'"; - assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_pop_debug_group", { - renderBundleEncoderRid, - }); - } - - /** - * @param {string} markerLabel - */ - insertDebugMarker(markerLabel) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - markerLabel = webidl.converters.USVString(markerLabel, { - prefix, - context: "Argument 1", - }); - assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_push_debug_group", { - renderBundleEncoderRid, - markerLabel, - }); - } - - /** - * @param {GPURenderPipeline} pipeline - */ - setPipeline(pipeline) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - pipeline = webidl.converters.GPURenderPipeline(pipeline, { - prefix, - context: "Argument 1", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const pipelineRid = assertResource(pipeline, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, pipeline, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_set_pipeline", { - renderBundleEncoderRid, - pipeline: pipelineRid, - }); - } - - /** - * @param {GPUBuffer} buffer - * @param {GPUIndexFormat} indexFormat - * @param {number} offset - * @param {number} size - */ - setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - buffer = webidl.converters.GPUBuffer(buffer, { - prefix, - context: "Argument 1", - }); - indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { - prefix, - context: "Argument 2", - }); - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 3", - }); - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 4", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const bufferRid = assertResource(buffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, buffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_set_index_buffer", { - renderBundleEncoderRid, - buffer: bufferRid, - indexFormat, - offset, - size, - }); - } - - /** - * @param {number} slot - * @param {GPUBuffer} buffer - * @param {number} offset - * @param {number} size - */ - setVertexBuffer(slot, buffer, offset = 0, size = 0) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - slot = webidl.converters.GPUSize32(slot, { - prefix, - context: "Argument 2", - }); - buffer = webidl.converters.GPUBuffer(buffer, { - prefix, - context: "Argument 2", - }); - offset = webidl.converters.GPUSize64(offset, { - prefix, - context: "Argument 3", - }); - size = webidl.converters.GPUSize64(size, { - prefix, - context: "Argument 4", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const bufferRid = assertResource(buffer, { - prefix, - context: "Argument 2", - }); - assertDeviceMatch(device, buffer, { - prefix, - resourceContext: "Argument 2", - selfContext: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { - renderBundleEncoderRid, - slot, - buffer: bufferRid, - offset, - size, - }); - } - - /** - * @param {number} vertexCount - * @param {number} instanceCount - * @param {number} firstVertex - * @param {number} firstInstance - */ - draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - vertexCount = webidl.converters.GPUSize32(vertexCount, { - prefix, - context: "Argument 1", - }); - instanceCount = webidl.converters.GPUSize32(instanceCount, { - prefix, - context: "Argument 2", - }); - firstVertex = webidl.converters.GPUSize32(firstVertex, { - prefix, - context: "Argument 3", - }); - firstInstance = webidl.converters.GPUSize32(firstInstance, { - prefix, - context: "Argument 4", - }); - assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_draw", { - renderBundleEncoderRid, - vertexCount, - instanceCount, - firstVertex, - firstInstance, - }); - } - - /** - * @param {number} indexCount - * @param {number} instanceCount - * @param {number} firstIndex - * @param {number} baseVertex - * @param {number} firstInstance - */ - drawIndexed( - indexCount, - instanceCount = 1, - firstIndex = 0, - baseVertex = 0, - firstInstance = 0, - ) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - indexCount = webidl.converters.GPUSize32(indexCount, { - prefix, - context: "Argument 1", - }); - instanceCount = webidl.converters.GPUSize32(instanceCount, { - prefix, - context: "Argument 2", - }); - firstIndex = webidl.converters.GPUSize32(firstIndex, { - prefix, - context: "Argument 3", - }); - baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { - prefix, - context: "Argument 4", - }); - firstInstance = webidl.converters.GPUSize32(firstInstance, { - prefix, - context: "Argument 5", - }); - assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_draw_indexed", { - renderBundleEncoderRid, - indexCount, - instanceCount, - firstIndex, - baseVertex, - firstInstance, - }); - } - - /** - * @param {GPUBuffer} indirectBuffer - * @param {number} indirectOffset - */ - drawIndirect(indirectBuffer, indirectOffset) { - webidl.assertBranded(this, GPURenderBundleEncoder.prototype); - const prefix = - "Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { - prefix, - context: "Argument 1", - }); - indirectOffset = webidl.converters.GPUSize64(indirectOffset, { - prefix, - context: "Argument 2", - }); - const device = assertDevice(this, { prefix, context: "this" }); - const renderBundleEncoderRid = assertResource(this, { - prefix, - context: "this", - }); - const indirectBufferRid = assertResource(indirectBuffer, { - prefix, - context: "Argument 1", - }); - assertDeviceMatch(device, indirectBuffer, { - prefix, - resourceContext: "Argument 1", - selfContext: "this", - }); - core.opSync("op_webgpu_render_bundle_encoder_draw_indirect", { - renderBundleEncoderRid, - indirectBuffer: indirectBufferRid, - indirectOffset, - }); - } - - drawIndexedIndirect(_indirectBuffer, _indirectOffset) { - throw new Error("Not yet implemented"); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPURenderBundle} - */ - function createGPURenderBundle(label, device, rid) { - /** @type {GPURenderBundle} */ - const bundle = webidl.createBranded(GPURenderBundle); - bundle[_label] = label; - bundle[_device] = device; - bundle[_rid] = rid; - return bundle; - } - - class GPURenderBundle { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); - - const _descriptor = Symbol("[[descriptor]]"); - - /** - * @param {string | null} label - * @param {InnerGPUDevice} device - * @param {number} rid - * @returns {GPUQuerySet} - */ - function createGPUQuerySet(label, device, rid, descriptor) { - /** @type {GPUQuerySet} */ - const queue = webidl.createBranded(GPUQuerySet); - queue[_label] = label; - queue[_device] = device; - queue[_rid] = rid; - queue[_descriptor] = descriptor; - return queue; - } - - class GPUQuerySet { - /** @type {InnerGPUDevice} */ - [_device]; - /** @type {number | undefined} */ - [_rid]; - /** @type {GPUQuerySetDescriptor} */ - [_descriptor]; - - [_cleanup]() { - const rid = this[_rid]; - if (rid !== undefined) { - core.close(rid); - /** @type {number | undefined} */ - this[_rid] = undefined; - } - } - - constructor() { - webidl.illegalConstructor(); - } - - destroy() { - webidl.assertBranded(this, GPUQuerySetPrototype); - this[_cleanup](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); - const GPUQuerySetPrototype = GPUQuerySet.prototype; - - window.__bootstrap.webgpu = { - gpu: webidl.createBranded(GPU), - GPU, - GPUAdapter, - GPUSupportedLimits, - GPUSupportedFeatures, - GPUDevice, - GPUQueue, - GPUBuffer, - GPUBufferUsage, - GPUMapMode, - GPUTextureUsage, - GPUTexture, - GPUTextureView, - GPUSampler, - GPUBindGroupLayout, - GPUPipelineLayout, - GPUBindGroup, - GPUShaderModule, - GPUShaderStage, - GPUComputePipeline, - GPURenderPipeline, - GPUColorWrite, - GPUCommandEncoder, - GPURenderPassEncoder, - GPUComputePassEncoder, - GPUCommandBuffer, - GPURenderBundleEncoder, - GPURenderBundle, - GPUQuerySet, - GPUOutOfMemoryError, - GPUValidationError, - }; -})(this); diff --git a/ext/webgpu/02_idl_types.js b/ext/webgpu/02_idl_types.js deleted file mode 100644 index 0dd8c00f9..000000000 --- a/ext/webgpu/02_idl_types.js +++ /dev/null @@ -1,2002 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -// @ts-check -/// - -"use strict"; - -((window) => { - const webidl = window.__bootstrap.webidl; - const { - GPU, - GPUAdapter, - GPUSupportedLimits, - GPUSupportedFeatures, - GPUDevice, - GPUQueue, - GPUBuffer, - GPUBufferUsage, - GPUMapMode, - GPUTextureUsage, - GPUTexture, - GPUTextureView, - GPUSampler, - GPUBindGroupLayout, - GPUPipelineLayout, - GPUBindGroup, - GPUShaderModule, - GPUShaderStage, - GPUComputePipeline, - GPURenderPipeline, - GPUColorWrite, - GPUCommandEncoder, - GPURenderPassEncoder, - GPUComputePassEncoder, - GPUCommandBuffer, - GPURenderBundleEncoder, - GPURenderBundle, - GPUQuerySet, - GPUOutOfMemoryError, - GPUValidationError, - } = window.__bootstrap.webgpu; - const { SymbolIterator, TypeError } = window.__bootstrap.primordials; - - // This needs to be initialized after all of the base classes are implemented, - // otherwise their converters might not be available yet. - // DICTIONARY: GPUObjectDescriptorBase - const dictMembersGPUObjectDescriptorBase = [ - { key: "label", converter: webidl.converters["USVString"] }, - ]; - webidl.converters["GPUObjectDescriptorBase"] = webidl - .createDictionaryConverter( - "GPUObjectDescriptorBase", - dictMembersGPUObjectDescriptorBase, - ); - - // INTERFACE: GPUSupportedLimits - webidl.converters.GPUSupportedLimits = webidl.createInterfaceConverter( - "GPUSupportedLimits", - GPUSupportedLimits.prototype, - ); - - // INTERFACE: GPUSupportedFeatures - webidl.converters.GPUSupportedFeatures = webidl.createInterfaceConverter( - "GPUSupportedFeatures", - GPUSupportedFeatures.prototype, - ); - - // ENUM: GPUPredefinedColorSpace - webidl.converters.GPUPredefinedColorSpace = webidl.createEnumConverter( - "GPUPredefinedColorSpace", - ["srgb"], - ); - - // INTERFACE: GPU - webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU.prototype); - - // ENUM: GPUPowerPreference - webidl.converters["GPUPowerPreference"] = webidl.createEnumConverter( - "GPUPowerPreference", - [ - "low-power", - "high-performance", - ], - ); - - // DICTIONARY: GPURequestAdapterOptions - const dictMembersGPURequestAdapterOptions = [ - { - key: "powerPreference", - converter: webidl.converters["GPUPowerPreference"], - }, - { - key: "forceFallbackAdapter", - converter: webidl.converters.boolean, - defaultValue: false, - }, - ]; - webidl.converters["GPURequestAdapterOptions"] = webidl - .createDictionaryConverter( - "GPURequestAdapterOptions", - dictMembersGPURequestAdapterOptions, - ); - - // INTERFACE: GPUAdapter - webidl.converters.GPUAdapter = webidl.createInterfaceConverter( - "GPUAdapter", - GPUAdapter.prototype, - ); - - // ENUM: GPUFeatureName - webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( - "GPUFeatureName", - [ - "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", - "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", - "texture-adapter-specific-format-features", - "shader-float64", - "vertex-attribute-64bit", - "conservative-rasterization", - "vertex-writable-storage", - "clear-commands", - "spirv-shader-passthrough", - "shader-primitive-index", - ], - ); - - // TYPEDEF: GPUSize32 - webidl.converters["GPUSize32"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUDeviceDescriptor - const dictMembersGPUDeviceDescriptor = [ - { - key: "nonGuaranteedFeatures", - converter: webidl.createSequenceConverter( - webidl.converters["GPUFeatureName"], - ), - get defaultValue() { - return []; - }, - }, - { - key: "nonGuaranteedLimits", - converter: webidl.createRecordConverter( - webidl.converters["DOMString"], - webidl.converters["GPUSize32"], - ), - get defaultValue() { - return {}; - }, - }, - ]; - webidl.converters["GPUDeviceDescriptor"] = webidl.createDictionaryConverter( - "GPUDeviceDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUDeviceDescriptor, - ); - - // INTERFACE: GPUDevice - webidl.converters.GPUDevice = webidl.createInterfaceConverter( - "GPUDevice", - GPUDevice.prototype, - ); - - // INTERFACE: GPUBuffer - webidl.converters.GPUBuffer = webidl.createInterfaceConverter( - "GPUBuffer", - GPUBuffer.prototype, - ); - - // TYPEDEF: GPUSize64 - webidl.converters["GPUSize64"] = (V, opts) => - webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true }); - - // TYPEDEF: GPUBufferUsageFlags - webidl.converters["GPUBufferUsageFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUBufferDescriptor - const dictMembersGPUBufferDescriptor = [ - { key: "size", converter: webidl.converters["GPUSize64"], required: true }, - { - key: "usage", - converter: webidl.converters["GPUBufferUsageFlags"], - required: true, - }, - { - key: "mappedAtCreation", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - webidl.converters["GPUBufferDescriptor"] = webidl.createDictionaryConverter( - "GPUBufferDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUBufferDescriptor, - ); - - // INTERFACE: GPUBufferUsage - webidl.converters.GPUBufferUsage = webidl.createInterfaceConverter( - "GPUBufferUsage", - GPUBufferUsage.prototype, - ); - - // TYPEDEF: GPUMapModeFlags - webidl.converters["GPUMapModeFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // INTERFACE: GPUMapMode - webidl.converters.GPUMapMode = webidl.createInterfaceConverter( - "GPUMapMode", - GPUMapMode.prototype, - ); - - // INTERFACE: GPUTexture - webidl.converters.GPUTexture = webidl.createInterfaceConverter( - "GPUTexture", - GPUTexture.prototype, - ); - - // TYPEDEF: GPUIntegerCoordinate - webidl.converters["GPUIntegerCoordinate"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - webidl.converters["sequence"] = webidl - .createSequenceConverter(webidl.converters["GPUIntegerCoordinate"]); - - // DICTIONARY: GPUExtent3DDict - const dictMembersGPUExtent3DDict = [ - { - key: "width", - converter: webidl.converters["GPUIntegerCoordinate"], - required: true, - }, - { - key: "height", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 1, - }, - { - key: "depthOrArrayLayers", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 1, - }, - ]; - webidl.converters["GPUExtent3DDict"] = webidl.createDictionaryConverter( - "GPUExtent3DDict", - dictMembersGPUExtent3DDict, - ); - - // TYPEDEF: GPUExtent3D - webidl.converters["GPUExtent3D"] = (V, opts) => { - // Union for (sequence or GPUExtent3DDict) - if (V === null || V === undefined) { - return webidl.converters["GPUExtent3DDict"](V, opts); - } - if (typeof V === "object") { - const method = V[SymbolIterator]; - if (method !== undefined) { - return webidl.converters["sequence"](V, opts); - } - return webidl.converters["GPUExtent3DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence or GPUExtent3DDict.", - opts, - ); - }; - - // ENUM: GPUTextureDimension - webidl.converters["GPUTextureDimension"] = webidl.createEnumConverter( - "GPUTextureDimension", - [ - "1d", - "2d", - "3d", - ], - ); - - // ENUM: GPUTextureFormat - webidl.converters["GPUTextureFormat"] = webidl.createEnumConverter( - "GPUTextureFormat", - [ - "r8unorm", - "r8snorm", - "r8uint", - "r8sint", - "r16uint", - "r16sint", - "r16float", - "rg8unorm", - "rg8snorm", - "rg8uint", - "rg8sint", - "r32uint", - "r32sint", - "r32float", - "rg16uint", - "rg16sint", - "rg16float", - "rgba8unorm", - "rgba8unorm-srgb", - "rgba8snorm", - "rgba8uint", - "rgba8sint", - "bgra8unorm", - "bgra8unorm-srgb", - "rgb9e5ufloat", - "rgb10a2unorm", - "rg11b10ufloat", - "rg32uint", - "rg32sint", - "rg32float", - "rgba16uint", - "rgba16sint", - "rgba16float", - "rgba32uint", - "rgba32sint", - "rgba32float", - "stencil8", - "depth16unorm", - "depth24plus", - "depth24plus-stencil8", - "depth32float", - "bc1-rgba-unorm", - "bc1-rgba-unorm-srgb", - "bc2-rgba-unorm", - "bc2-rgba-unorm-srgb", - "bc3-rgba-unorm", - "bc3-rgba-unorm-srgb", - "bc4-r-unorm", - "bc4-r-snorm", - "bc5-rg-unorm", - "bc5-rg-snorm", - "bc6h-rgb-ufloat", - "bc6h-rgb-float", - "bc7-rgba-unorm", - "bc7-rgba-unorm-srgb", - "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", - ], - ); - - // TYPEDEF: GPUTextureUsageFlags - webidl.converters["GPUTextureUsageFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUTextureDescriptor - const dictMembersGPUTextureDescriptor = [ - { - key: "size", - converter: webidl.converters["GPUExtent3D"], - required: true, - }, - { - key: "mipLevelCount", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 1, - }, - { - key: "sampleCount", - converter: webidl.converters["GPUSize32"], - defaultValue: 1, - }, - { - key: "dimension", - converter: webidl.converters["GPUTextureDimension"], - defaultValue: "2d", - }, - { - key: "format", - converter: webidl.converters["GPUTextureFormat"], - required: true, - }, - { - key: "usage", - converter: webidl.converters["GPUTextureUsageFlags"], - required: true, - }, - ]; - webidl.converters["GPUTextureDescriptor"] = webidl.createDictionaryConverter( - "GPUTextureDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUTextureDescriptor, - ); - - // INTERFACE: GPUTextureUsage - webidl.converters.GPUTextureUsage = webidl.createInterfaceConverter( - "GPUTextureUsage", - GPUTextureUsage.prototype, - ); - - // INTERFACE: GPUTextureView - webidl.converters.GPUTextureView = webidl.createInterfaceConverter( - "GPUTextureView", - GPUTextureView.prototype, - ); - - // ENUM: GPUTextureViewDimension - webidl.converters["GPUTextureViewDimension"] = webidl.createEnumConverter( - "GPUTextureViewDimension", - [ - "1d", - "2d", - "2d-array", - "cube", - "cube-array", - "3d", - ], - ); - - // ENUM: GPUTextureAspect - webidl.converters["GPUTextureAspect"] = webidl.createEnumConverter( - "GPUTextureAspect", - [ - "all", - "stencil-only", - "depth-only", - ], - ); - - // DICTIONARY: GPUTextureViewDescriptor - const dictMembersGPUTextureViewDescriptor = [ - { key: "format", converter: webidl.converters["GPUTextureFormat"] }, - { - key: "dimension", - converter: webidl.converters["GPUTextureViewDimension"], - }, - { - key: "aspect", - converter: webidl.converters["GPUTextureAspect"], - defaultValue: "all", - }, - { - key: "baseMipLevel", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "mipLevelCount", - converter: webidl.converters["GPUIntegerCoordinate"], - }, - { - key: "baseArrayLayer", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "arrayLayerCount", - converter: webidl.converters["GPUIntegerCoordinate"], - }, - ]; - webidl.converters["GPUTextureViewDescriptor"] = webidl - .createDictionaryConverter( - "GPUTextureViewDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUTextureViewDescriptor, - ); - - // INTERFACE: GPUSampler - webidl.converters.GPUSampler = webidl.createInterfaceConverter( - "GPUSampler", - GPUSampler.prototype, - ); - - // ENUM: GPUAddressMode - webidl.converters["GPUAddressMode"] = webidl.createEnumConverter( - "GPUAddressMode", - [ - "clamp-to-edge", - "repeat", - "mirror-repeat", - ], - ); - - // ENUM: GPUFilterMode - webidl.converters["GPUFilterMode"] = webidl.createEnumConverter( - "GPUFilterMode", - [ - "nearest", - "linear", - ], - ); - - // ENUM: GPUCompareFunction - webidl.converters["GPUCompareFunction"] = webidl.createEnumConverter( - "GPUCompareFunction", - [ - "never", - "less", - "equal", - "less-equal", - "greater", - "not-equal", - "greater-equal", - "always", - ], - ); - - // DICTIONARY: GPUSamplerDescriptor - const dictMembersGPUSamplerDescriptor = [ - { - key: "addressModeU", - converter: webidl.converters["GPUAddressMode"], - defaultValue: "clamp-to-edge", - }, - { - key: "addressModeV", - converter: webidl.converters["GPUAddressMode"], - defaultValue: "clamp-to-edge", - }, - { - key: "addressModeW", - converter: webidl.converters["GPUAddressMode"], - defaultValue: "clamp-to-edge", - }, - { - key: "magFilter", - converter: webidl.converters["GPUFilterMode"], - defaultValue: "nearest", - }, - { - key: "minFilter", - converter: webidl.converters["GPUFilterMode"], - defaultValue: "nearest", - }, - { - key: "mipmapFilter", - converter: webidl.converters["GPUFilterMode"], - defaultValue: "nearest", - }, - { - key: "lodMinClamp", - converter: webidl.converters["float"], - defaultValue: 0, - }, - { - key: "lodMaxClamp", - converter: webidl.converters["float"], - defaultValue: 0xffffffff, - }, - { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, - { - key: "maxAnisotropy", - converter: (V, opts) => - webidl.converters["unsigned short"](V, { ...opts, clamp: true }), - defaultValue: 1, - }, - ]; - webidl.converters["GPUSamplerDescriptor"] = webidl.createDictionaryConverter( - "GPUSamplerDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUSamplerDescriptor, - ); - - // INTERFACE: GPUBindGroupLayout - webidl.converters.GPUBindGroupLayout = webidl.createInterfaceConverter( - "GPUBindGroupLayout", - GPUBindGroupLayout.prototype, - ); - - // TYPEDEF: GPUIndex32 - webidl.converters["GPUIndex32"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // TYPEDEF: GPUShaderStageFlags - webidl.converters["GPUShaderStageFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // ENUM: GPUBufferBindingType - webidl.converters["GPUBufferBindingType"] = webidl.createEnumConverter( - "GPUBufferBindingType", - [ - "uniform", - "storage", - "read-only-storage", - ], - ); - - // DICTIONARY: GPUBufferBindingLayout - const dictMembersGPUBufferBindingLayout = [ - { - key: "type", - converter: webidl.converters["GPUBufferBindingType"], - defaultValue: "uniform", - }, - { - key: "hasDynamicOffset", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - { - key: "minBindingSize", - converter: webidl.converters["GPUSize64"], - defaultValue: 0, - }, - ]; - webidl.converters["GPUBufferBindingLayout"] = webidl - .createDictionaryConverter( - "GPUBufferBindingLayout", - dictMembersGPUBufferBindingLayout, - ); - - // ENUM: GPUSamplerBindingType - webidl.converters["GPUSamplerBindingType"] = webidl.createEnumConverter( - "GPUSamplerBindingType", - [ - "filtering", - "non-filtering", - "comparison", - ], - ); - - // DICTIONARY: GPUSamplerBindingLayout - const dictMembersGPUSamplerBindingLayout = [ - { - key: "type", - converter: webidl.converters["GPUSamplerBindingType"], - defaultValue: "filtering", - }, - ]; - webidl.converters["GPUSamplerBindingLayout"] = webidl - .createDictionaryConverter( - "GPUSamplerBindingLayout", - dictMembersGPUSamplerBindingLayout, - ); - - // ENUM: GPUTextureSampleType - webidl.converters["GPUTextureSampleType"] = webidl.createEnumConverter( - "GPUTextureSampleType", - [ - "float", - "unfilterable-float", - "depth", - "sint", - "uint", - ], - ); - - // DICTIONARY: GPUTextureBindingLayout - const dictMembersGPUTextureBindingLayout = [ - { - key: "sampleType", - converter: webidl.converters["GPUTextureSampleType"], - defaultValue: "float", - }, - { - key: "viewDimension", - converter: webidl.converters["GPUTextureViewDimension"], - defaultValue: "2d", - }, - { - key: "multisampled", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - webidl.converters["GPUTextureBindingLayout"] = webidl - .createDictionaryConverter( - "GPUTextureBindingLayout", - dictMembersGPUTextureBindingLayout, - ); - - // ENUM: GPUStorageTextureAccess - webidl.converters["GPUStorageTextureAccess"] = webidl.createEnumConverter( - "GPUStorageTextureAccess", - [ - "write-only", - ], - ); - - // DICTIONARY: GPUStorageTextureBindingLayout - const dictMembersGPUStorageTextureBindingLayout = [ - { - key: "access", - converter: webidl.converters["GPUStorageTextureAccess"], - defaultValue: "write-only", - }, - { - key: "format", - converter: webidl.converters["GPUTextureFormat"], - required: true, - }, - { - key: "viewDimension", - converter: webidl.converters["GPUTextureViewDimension"], - defaultValue: "2d", - }, - ]; - webidl.converters["GPUStorageTextureBindingLayout"] = webidl - .createDictionaryConverter( - "GPUStorageTextureBindingLayout", - dictMembersGPUStorageTextureBindingLayout, - ); - - // DICTIONARY: GPUBindGroupLayoutEntry - const dictMembersGPUBindGroupLayoutEntry = [ - { - key: "binding", - converter: webidl.converters["GPUIndex32"], - required: true, - }, - { - key: "visibility", - converter: webidl.converters["GPUShaderStageFlags"], - required: true, - }, - { key: "buffer", converter: webidl.converters["GPUBufferBindingLayout"] }, - { key: "sampler", converter: webidl.converters["GPUSamplerBindingLayout"] }, - { key: "texture", converter: webidl.converters["GPUTextureBindingLayout"] }, - { - key: "storageTexture", - converter: webidl.converters["GPUStorageTextureBindingLayout"], - }, - ]; - webidl.converters["GPUBindGroupLayoutEntry"] = webidl - .createDictionaryConverter( - "GPUBindGroupLayoutEntry", - dictMembersGPUBindGroupLayoutEntry, - ); - - // DICTIONARY: GPUBindGroupLayoutDescriptor - const dictMembersGPUBindGroupLayoutDescriptor = [ - { - key: "entries", - converter: webidl.createSequenceConverter( - webidl.converters["GPUBindGroupLayoutEntry"], - ), - required: true, - }, - ]; - webidl.converters["GPUBindGroupLayoutDescriptor"] = webidl - .createDictionaryConverter( - "GPUBindGroupLayoutDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUBindGroupLayoutDescriptor, - ); - - // INTERFACE: GPUShaderStage - webidl.converters.GPUShaderStage = webidl.createInterfaceConverter( - "GPUShaderStage", - GPUShaderStage.prototype, - ); - - // INTERFACE: GPUBindGroup - webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( - "GPUBindGroup", - GPUBindGroup.prototype, - ); - - // DICTIONARY: GPUBufferBinding - const dictMembersGPUBufferBinding = [ - { - key: "buffer", - converter: webidl.converters["GPUBuffer"], - required: true, - }, - { - key: "offset", - converter: webidl.converters["GPUSize64"], - defaultValue: 0, - }, - { key: "size", converter: webidl.converters["GPUSize64"] }, - ]; - webidl.converters["GPUBufferBinding"] = webidl.createDictionaryConverter( - "GPUBufferBinding", - dictMembersGPUBufferBinding, - ); - - // TYPEDEF: GPUBindingResource - webidl.converters["GPUBindingResource"] = - webidl.converters.any /** put union here! **/; - - // DICTIONARY: GPUBindGroupEntry - const dictMembersGPUBindGroupEntry = [ - { - key: "binding", - converter: webidl.converters["GPUIndex32"], - required: true, - }, - { - key: "resource", - converter: webidl.converters["GPUBindingResource"], - required: true, - }, - ]; - webidl.converters["GPUBindGroupEntry"] = webidl.createDictionaryConverter( - "GPUBindGroupEntry", - dictMembersGPUBindGroupEntry, - ); - - // DICTIONARY: GPUBindGroupDescriptor - const dictMembersGPUBindGroupDescriptor = [ - { - key: "layout", - converter: webidl.converters["GPUBindGroupLayout"], - required: true, - }, - { - key: "entries", - converter: webidl.createSequenceConverter( - webidl.converters["GPUBindGroupEntry"], - ), - required: true, - }, - ]; - webidl.converters["GPUBindGroupDescriptor"] = webidl - .createDictionaryConverter( - "GPUBindGroupDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUBindGroupDescriptor, - ); - - // INTERFACE: GPUPipelineLayout - webidl.converters.GPUPipelineLayout = webidl.createInterfaceConverter( - "GPUPipelineLayout", - GPUPipelineLayout.prototype, - ); - - // DICTIONARY: GPUPipelineLayoutDescriptor - const dictMembersGPUPipelineLayoutDescriptor = [ - { - key: "bindGroupLayouts", - converter: webidl.createSequenceConverter( - webidl.converters["GPUBindGroupLayout"], - ), - required: true, - }, - ]; - webidl.converters["GPUPipelineLayoutDescriptor"] = webidl - .createDictionaryConverter( - "GPUPipelineLayoutDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUPipelineLayoutDescriptor, - ); - - // INTERFACE: GPUShaderModule - webidl.converters.GPUShaderModule = webidl.createInterfaceConverter( - "GPUShaderModule", - GPUShaderModule.prototype, - ); - - // DICTIONARY: GPUShaderModuleDescriptor - const dictMembersGPUShaderModuleDescriptor = [ - { - key: "code", - converter: webidl.converters["DOMString"], - required: true, - }, - { key: "sourceMap", converter: webidl.converters["object"] }, - ]; - webidl.converters["GPUShaderModuleDescriptor"] = webidl - .createDictionaryConverter( - "GPUShaderModuleDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUShaderModuleDescriptor, - ); - - // // ENUM: GPUCompilationMessageType - // webidl.converters["GPUCompilationMessageType"] = webidl.createEnumConverter( - // "GPUCompilationMessageType", - // [ - // "error", - // "warning", - // "info", - // ], - // ); - - // // INTERFACE: GPUCompilationMessage - // webidl.converters.GPUCompilationMessage = webidl.createInterfaceConverter( - // "GPUCompilationMessage", - // GPUCompilationMessage.prototype, - // ); - - // // INTERFACE: GPUCompilationInfo - // webidl.converters.GPUCompilationInfo = webidl.createInterfaceConverter( - // "GPUCompilationInfo", - // GPUCompilationInfo.prototype, - // ); - - // DICTIONARY: GPUPipelineDescriptorBase - const dictMembersGPUPipelineDescriptorBase = [ - { key: "layout", converter: webidl.converters["GPUPipelineLayout"] }, - ]; - webidl.converters["GPUPipelineDescriptorBase"] = webidl - .createDictionaryConverter( - "GPUPipelineDescriptorBase", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUPipelineDescriptorBase, - ); - - // TYPEDEF: GPUPipelineConstantValue - webidl.converters.GPUPipelineConstantValue = webidl.converters.double; - - webidl.converters["record"] = webidl - .createRecordConverter( - webidl.converters.USVString, - webidl.converters.GPUPipelineConstantValue, - ); - - // DICTIONARY: GPUProgrammableStage - const dictMembersGPUProgrammableStage = [ - { - key: "module", - converter: webidl.converters["GPUShaderModule"], - required: true, - }, - { - key: "entryPoint", - converter: webidl.converters["USVString"], - required: true, - }, - { - key: "constants", - converter: - webidl.converters["record"], - }, - ]; - webidl.converters["GPUProgrammableStage"] = webidl.createDictionaryConverter( - "GPUProgrammableStage", - dictMembersGPUProgrammableStage, - ); - - // INTERFACE: GPUComputePipeline - webidl.converters.GPUComputePipeline = webidl.createInterfaceConverter( - "GPUComputePipeline", - GPUComputePipeline.prototype, - ); - - // DICTIONARY: GPUComputePipelineDescriptor - const dictMembersGPUComputePipelineDescriptor = [ - { - key: "compute", - converter: webidl.converters["GPUProgrammableStage"], - required: true, - }, - ]; - webidl.converters["GPUComputePipelineDescriptor"] = webidl - .createDictionaryConverter( - "GPUComputePipelineDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUPipelineDescriptorBase, - dictMembersGPUComputePipelineDescriptor, - ); - - // INTERFACE: GPURenderPipeline - webidl.converters.GPURenderPipeline = webidl.createInterfaceConverter( - "GPURenderPipeline", - GPURenderPipeline.prototype, - ); - - // ENUM: GPUVertexStepMode - webidl.converters["GPUVertexStepMode"] = webidl.createEnumConverter( - "GPUVertexStepMode", - [ - "vertex", - "instance", - ], - ); - - // ENUM: GPUVertexFormat - webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( - "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", - ], - ); - - // DICTIONARY: GPUVertexAttribute - const dictMembersGPUVertexAttribute = [ - { - key: "format", - converter: webidl.converters["GPUVertexFormat"], - required: true, - }, - { - key: "offset", - converter: webidl.converters["GPUSize64"], - required: true, - }, - { - key: "shaderLocation", - converter: webidl.converters["GPUIndex32"], - required: true, - }, - ]; - webidl.converters["GPUVertexAttribute"] = webidl.createDictionaryConverter( - "GPUVertexAttribute", - dictMembersGPUVertexAttribute, - ); - - // DICTIONARY: GPUVertexBufferLayout - const dictMembersGPUVertexBufferLayout = [ - { - key: "arrayStride", - converter: webidl.converters["GPUSize64"], - required: true, - }, - { - key: "stepMode", - converter: webidl.converters["GPUVertexStepMode"], - defaultValue: "vertex", - }, - { - key: "attributes", - converter: webidl.createSequenceConverter( - webidl.converters["GPUVertexAttribute"], - ), - required: true, - }, - ]; - webidl.converters["GPUVertexBufferLayout"] = webidl.createDictionaryConverter( - "GPUVertexBufferLayout", - dictMembersGPUVertexBufferLayout, - ); - - // DICTIONARY: GPUVertexState - const dictMembersGPUVertexState = [ - { - key: "buffers", - converter: webidl.createSequenceConverter( - webidl.createNullableConverter( - webidl.converters["GPUVertexBufferLayout"], - ), - ), - get defaultValue() { - return []; - }, - }, - ]; - webidl.converters["GPUVertexState"] = webidl.createDictionaryConverter( - "GPUVertexState", - dictMembersGPUProgrammableStage, - dictMembersGPUVertexState, - ); - - // ENUM: GPUPrimitiveTopology - webidl.converters["GPUPrimitiveTopology"] = webidl.createEnumConverter( - "GPUPrimitiveTopology", - [ - "point-list", - "line-list", - "line-strip", - "triangle-list", - "triangle-strip", - ], - ); - - // ENUM: GPUIndexFormat - webidl.converters["GPUIndexFormat"] = webidl.createEnumConverter( - "GPUIndexFormat", - [ - "uint16", - "uint32", - ], - ); - - // ENUM: GPUFrontFace - webidl.converters["GPUFrontFace"] = webidl.createEnumConverter( - "GPUFrontFace", - [ - "ccw", - "cw", - ], - ); - - // ENUM: GPUCullMode - webidl.converters["GPUCullMode"] = webidl.createEnumConverter("GPUCullMode", [ - "none", - "front", - "back", - ]); - - // DICTIONARY: GPUPrimitiveState - const dictMembersGPUPrimitiveState = [ - { - key: "topology", - converter: webidl.converters["GPUPrimitiveTopology"], - defaultValue: "triangle-list", - }, - { key: "stripIndexFormat", converter: webidl.converters["GPUIndexFormat"] }, - { - key: "frontFace", - converter: webidl.converters["GPUFrontFace"], - defaultValue: "ccw", - }, - { - key: "cullMode", - converter: webidl.converters["GPUCullMode"], - defaultValue: "none", - }, - { - key: "unclippedDepth", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - webidl.converters["GPUPrimitiveState"] = webidl.createDictionaryConverter( - "GPUPrimitiveState", - dictMembersGPUPrimitiveState, - ); - - // ENUM: GPUStencilOperation - webidl.converters["GPUStencilOperation"] = webidl.createEnumConverter( - "GPUStencilOperation", - [ - "keep", - "zero", - "replace", - "invert", - "increment-clamp", - "decrement-clamp", - "increment-wrap", - "decrement-wrap", - ], - ); - - // DICTIONARY: GPUStencilFaceState - const dictMembersGPUStencilFaceState = [ - { - key: "compare", - converter: webidl.converters["GPUCompareFunction"], - defaultValue: "always", - }, - { - key: "failOp", - converter: webidl.converters["GPUStencilOperation"], - defaultValue: "keep", - }, - { - key: "depthFailOp", - converter: webidl.converters["GPUStencilOperation"], - defaultValue: "keep", - }, - { - key: "passOp", - converter: webidl.converters["GPUStencilOperation"], - defaultValue: "keep", - }, - ]; - webidl.converters["GPUStencilFaceState"] = webidl.createDictionaryConverter( - "GPUStencilFaceState", - dictMembersGPUStencilFaceState, - ); - - // TYPEDEF: GPUStencilValue - webidl.converters["GPUStencilValue"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // TYPEDEF: GPUDepthBias - webidl.converters["GPUDepthBias"] = (V, opts) => - webidl.converters["long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUDepthStencilState - const dictMembersGPUDepthStencilState = [ - { - key: "format", - converter: webidl.converters["GPUTextureFormat"], - required: true, - }, - { - key: "depthWriteEnabled", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - { - key: "depthCompare", - converter: webidl.converters["GPUCompareFunction"], - defaultValue: "always", - }, - { - key: "stencilFront", - converter: webidl.converters["GPUStencilFaceState"], - get defaultValue() { - return {}; - }, - }, - { - key: "stencilBack", - converter: webidl.converters["GPUStencilFaceState"], - get defaultValue() { - return {}; - }, - }, - { - key: "stencilReadMask", - converter: webidl.converters["GPUStencilValue"], - defaultValue: 0xFFFFFFFF, - }, - { - key: "stencilWriteMask", - converter: webidl.converters["GPUStencilValue"], - defaultValue: 0xFFFFFFFF, - }, - { - key: "depthBias", - converter: webidl.converters["GPUDepthBias"], - defaultValue: 0, - }, - { - key: "depthBiasSlopeScale", - converter: webidl.converters["float"], - defaultValue: 0, - }, - { - key: "depthBiasClamp", - converter: webidl.converters["float"], - defaultValue: 0, - }, - ]; - webidl.converters["GPUDepthStencilState"] = webidl.createDictionaryConverter( - "GPUDepthStencilState", - dictMembersGPUDepthStencilState, - ); - - // TYPEDEF: GPUSampleMask - webidl.converters["GPUSampleMask"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUMultisampleState - const dictMembersGPUMultisampleState = [ - { - key: "count", - converter: webidl.converters["GPUSize32"], - defaultValue: 1, - }, - { - key: "mask", - converter: webidl.converters["GPUSampleMask"], - defaultValue: 0xFFFFFFFF, - }, - { - key: "alphaToCoverageEnabled", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - webidl.converters["GPUMultisampleState"] = webidl.createDictionaryConverter( - "GPUMultisampleState", - dictMembersGPUMultisampleState, - ); - - // ENUM: GPUBlendFactor - webidl.converters["GPUBlendFactor"] = webidl.createEnumConverter( - "GPUBlendFactor", - [ - "zero", - "one", - "src", - "one-minus-src", - "src-alpha", - "one-minus-src-alpha", - "dst", - "one-minus-dst", - "dst-alpha", - "one-minus-dst-alpha", - "src-alpha-saturated", - "constant", - "one-minus-constant", - ], - ); - - // ENUM: GPUBlendOperation - webidl.converters["GPUBlendOperation"] = webidl.createEnumConverter( - "GPUBlendOperation", - [ - "add", - "subtract", - "reverse-subtract", - "min", - "max", - ], - ); - - // DICTIONARY: GPUBlendComponent - const dictMembersGPUBlendComponent = [ - { - key: "srcFactor", - converter: webidl.converters["GPUBlendFactor"], - defaultValue: "one", - }, - { - key: "dstFactor", - converter: webidl.converters["GPUBlendFactor"], - defaultValue: "zero", - }, - { - key: "operation", - converter: webidl.converters["GPUBlendOperation"], - defaultValue: "add", - }, - ]; - webidl.converters["GPUBlendComponent"] = webidl.createDictionaryConverter( - "GPUBlendComponent", - dictMembersGPUBlendComponent, - ); - - // DICTIONARY: GPUBlendState - const dictMembersGPUBlendState = [ - { - key: "color", - converter: webidl.converters["GPUBlendComponent"], - required: true, - }, - { - key: "alpha", - converter: webidl.converters["GPUBlendComponent"], - required: true, - }, - ]; - webidl.converters["GPUBlendState"] = webidl.createDictionaryConverter( - "GPUBlendState", - dictMembersGPUBlendState, - ); - - // TYPEDEF: GPUColorWriteFlags - webidl.converters["GPUColorWriteFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // DICTIONARY: GPUColorTargetState - const dictMembersGPUColorTargetState = [ - { - key: "format", - converter: webidl.converters["GPUTextureFormat"], - required: true, - }, - { key: "blend", converter: webidl.converters["GPUBlendState"] }, - { - key: "writeMask", - converter: webidl.converters["GPUColorWriteFlags"], - defaultValue: 0xF, - }, - ]; - webidl.converters["GPUColorTargetState"] = webidl.createDictionaryConverter( - "GPUColorTargetState", - dictMembersGPUColorTargetState, - ); - - // DICTIONARY: GPUFragmentState - const dictMembersGPUFragmentState = [ - { - key: "targets", - converter: webidl.createSequenceConverter( - webidl.converters["GPUColorTargetState"], - ), - required: true, - }, - ]; - webidl.converters["GPUFragmentState"] = webidl.createDictionaryConverter( - "GPUFragmentState", - dictMembersGPUProgrammableStage, - dictMembersGPUFragmentState, - ); - - // DICTIONARY: GPURenderPipelineDescriptor - const dictMembersGPURenderPipelineDescriptor = [ - { - key: "vertex", - converter: webidl.converters["GPUVertexState"], - required: true, - }, - { - key: "primitive", - converter: webidl.converters["GPUPrimitiveState"], - get defaultValue() { - return {}; - }, - }, - { - key: "depthStencil", - converter: webidl.converters["GPUDepthStencilState"], - }, - { - key: "multisample", - converter: webidl.converters["GPUMultisampleState"], - get defaultValue() { - return {}; - }, - }, - { key: "fragment", converter: webidl.converters["GPUFragmentState"] }, - ]; - webidl.converters["GPURenderPipelineDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderPipelineDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUPipelineDescriptorBase, - dictMembersGPURenderPipelineDescriptor, - ); - - // INTERFACE: GPUColorWrite - webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( - "GPUColorWrite", - GPUColorWrite.prototype, - ); - - // INTERFACE: GPUCommandBuffer - webidl.converters.GPUCommandBuffer = webidl.createInterfaceConverter( - "GPUCommandBuffer", - GPUCommandBuffer.prototype, - ); - webidl.converters["sequence"] = webidl - .createSequenceConverter(webidl.converters["GPUCommandBuffer"]); - - // DICTIONARY: GPUCommandBufferDescriptor - const dictMembersGPUCommandBufferDescriptor = []; - webidl.converters["GPUCommandBufferDescriptor"] = webidl - .createDictionaryConverter( - "GPUCommandBufferDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUCommandBufferDescriptor, - ); - - // INTERFACE: GPUCommandEncoder - webidl.converters.GPUCommandEncoder = webidl.createInterfaceConverter( - "GPUCommandEncoder", - GPUCommandEncoder.prototype, - ); - - // DICTIONARY: GPUCommandEncoderDescriptor - const dictMembersGPUCommandEncoderDescriptor = []; - webidl.converters["GPUCommandEncoderDescriptor"] = webidl - .createDictionaryConverter( - "GPUCommandEncoderDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUCommandEncoderDescriptor, - ); - - // DICTIONARY: GPUImageDataLayout - const dictMembersGPUImageDataLayout = [ - { - key: "offset", - converter: webidl.converters["GPUSize64"], - defaultValue: 0, - }, - { key: "bytesPerRow", converter: webidl.converters["GPUSize32"] }, - { key: "rowsPerImage", converter: webidl.converters["GPUSize32"] }, - ]; - webidl.converters["GPUImageDataLayout"] = webidl.createDictionaryConverter( - "GPUImageDataLayout", - dictMembersGPUImageDataLayout, - ); - - // DICTIONARY: GPUImageCopyBuffer - const dictMembersGPUImageCopyBuffer = [ - { - key: "buffer", - converter: webidl.converters["GPUBuffer"], - required: true, - }, - ]; - webidl.converters["GPUImageCopyBuffer"] = webidl.createDictionaryConverter( - "GPUImageCopyBuffer", - dictMembersGPUImageDataLayout, - dictMembersGPUImageCopyBuffer, - ); - - // DICTIONARY: GPUOrigin3DDict - const dictMembersGPUOrigin3DDict = [ - { - key: "x", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "z", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - ]; - webidl.converters["GPUOrigin3DDict"] = webidl.createDictionaryConverter( - "GPUOrigin3DDict", - dictMembersGPUOrigin3DDict, - ); - - // TYPEDEF: GPUOrigin3D - webidl.converters["GPUOrigin3D"] = (V, opts) => { - // Union for (sequence or GPUOrigin3DDict) - if (V === null || V === undefined) { - return webidl.converters["GPUOrigin3DDict"](V, opts); - } - if (typeof V === "object") { - const method = V[SymbolIterator]; - if (method !== undefined) { - return webidl.converters["sequence"](V, opts); - } - return webidl.converters["GPUOrigin3DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence or GPUOrigin3DDict.", - opts, - ); - }; - - // DICTIONARY: GPUImageCopyTexture - const dictMembersGPUImageCopyTexture = [ - { - key: "texture", - converter: webidl.converters["GPUTexture"], - required: true, - }, - { - key: "mipLevel", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "origin", - converter: webidl.converters["GPUOrigin3D"], - get defaultValue() { - return {}; - }, - }, - { - key: "aspect", - converter: webidl.converters["GPUTextureAspect"], - defaultValue: "all", - }, - ]; - webidl.converters["GPUImageCopyTexture"] = webidl.createDictionaryConverter( - "GPUImageCopyTexture", - dictMembersGPUImageCopyTexture, - ); - - // DICTIONARY: GPUOrigin2DDict - const dictMembersGPUOrigin2DDict = [ - { - key: "x", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["GPUIntegerCoordinate"], - defaultValue: 0, - }, - ]; - webidl.converters["GPUOrigin2DDict"] = webidl.createDictionaryConverter( - "GPUOrigin2DDict", - dictMembersGPUOrigin2DDict, - ); - - // TYPEDEF: GPUOrigin2D - webidl.converters["GPUOrigin2D"] = (V, opts) => { - // Union for (sequence or GPUOrigin2DDict) - if (V === null || V === undefined) { - return webidl.converters["GPUOrigin2DDict"](V, opts); - } - if (typeof V === "object") { - const method = V[SymbolIterator]; - if (method !== undefined) { - return webidl.converters["sequence"](V, opts); - } - return webidl.converters["GPUOrigin2DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence or GPUOrigin2DDict.", - opts, - ); - }; - - // INTERFACE: GPUComputePassEncoder - webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter( - "GPUComputePassEncoder", - GPUComputePassEncoder.prototype, - ); - - // DICTIONARY: GPUComputePassDescriptor - const dictMembersGPUComputePassDescriptor = []; - webidl.converters["GPUComputePassDescriptor"] = webidl - .createDictionaryConverter( - "GPUComputePassDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUComputePassDescriptor, - ); - - // INTERFACE: GPURenderPassEncoder - webidl.converters.GPURenderPassEncoder = webidl.createInterfaceConverter( - "GPURenderPassEncoder", - GPURenderPassEncoder.prototype, - ); - - // ENUM: GPULoadOp - webidl.converters["GPULoadOp"] = webidl.createEnumConverter("GPULoadOp", [ - "load", - ]); - - // DICTIONARY: GPUColorDict - const dictMembersGPUColorDict = [ - { key: "r", converter: webidl.converters["double"], required: true }, - { key: "g", converter: webidl.converters["double"], required: true }, - { key: "b", converter: webidl.converters["double"], required: true }, - { key: "a", converter: webidl.converters["double"], required: true }, - ]; - webidl.converters["GPUColorDict"] = webidl.createDictionaryConverter( - "GPUColorDict", - dictMembersGPUColorDict, - ); - - // TYPEDEF: GPUColor - webidl.converters["GPUColor"] = (V, opts) => { - // Union for (sequence or GPUColorDict) - if (V === null || V === undefined) { - return webidl.converters["GPUColorDict"](V, opts); - } - if (typeof V === "object") { - const method = V[SymbolIterator]; - if (method !== undefined) { - return webidl.converters["sequence"](V, opts); - } - return webidl.converters["GPUColorDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence or GPUColorDict.", - opts, - ); - }; - - // ENUM: GPUStoreOp - webidl.converters["GPUStoreOp"] = webidl.createEnumConverter("GPUStoreOp", [ - "store", - "discard", - ]); - - // DICTIONARY: GPURenderPassColorAttachment - const dictMembersGPURenderPassColorAttachment = [ - { - key: "view", - converter: webidl.converters["GPUTextureView"], - required: true, - }, - { key: "resolveTarget", converter: webidl.converters["GPUTextureView"] }, - { - key: "loadValue", - converter: webidl.converters.any, /** put union here! **/ - required: true, - }, - { - key: "storeOp", - converter: webidl.converters["GPUStoreOp"], - required: true, - }, - ]; - webidl.converters["GPURenderPassColorAttachment"] = webidl - .createDictionaryConverter( - "GPURenderPassColorAttachment", - dictMembersGPURenderPassColorAttachment, - ); - - // DICTIONARY: GPURenderPassDepthStencilAttachment - const dictMembersGPURenderPassDepthStencilAttachment = [ - { - key: "view", - converter: webidl.converters["GPUTextureView"], - required: true, - }, - { - key: "depthLoadValue", - converter: webidl.converters.any, /** put union here! **/ - required: true, - }, - { - key: "depthStoreOp", - converter: webidl.converters["GPUStoreOp"], - required: true, - }, - { - key: "depthReadOnly", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - { - key: "stencilLoadValue", - converter: webidl.converters.any, /** put union here! **/ - required: true, - }, - { - key: "stencilStoreOp", - converter: webidl.converters["GPUStoreOp"], - required: true, - }, - { - key: "stencilReadOnly", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - webidl.converters["GPURenderPassDepthStencilAttachment"] = webidl - .createDictionaryConverter( - "GPURenderPassDepthStencilAttachment", - dictMembersGPURenderPassDepthStencilAttachment, - ); - - // INTERFACE: GPUQuerySet - webidl.converters.GPUQuerySet = webidl.createInterfaceConverter( - "GPUQuerySet", - GPUQuerySet.prototype, - ); - - // DICTIONARY: GPURenderPassDescriptor - const dictMembersGPURenderPassDescriptor = [ - { - key: "colorAttachments", - converter: webidl.createSequenceConverter( - webidl.converters["GPURenderPassColorAttachment"], - ), - required: true, - }, - { - key: "depthStencilAttachment", - converter: webidl.converters["GPURenderPassDepthStencilAttachment"], - }, - { key: "occlusionQuerySet", converter: webidl.converters["GPUQuerySet"] }, - ]; - webidl.converters["GPURenderPassDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderPassDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPURenderPassDescriptor, - ); - - // INTERFACE: GPURenderBundle - webidl.converters.GPURenderBundle = webidl.createInterfaceConverter( - "GPURenderBundle", - GPURenderBundle.prototype, - ); - webidl.converters["sequence"] = webidl - .createSequenceConverter(webidl.converters["GPURenderBundle"]); - - // DICTIONARY: GPURenderBundleDescriptor - const dictMembersGPURenderBundleDescriptor = []; - webidl.converters["GPURenderBundleDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderBundleDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPURenderBundleDescriptor, - ); - - // INTERFACE: GPURenderBundleEncoder - webidl.converters.GPURenderBundleEncoder = webidl.createInterfaceConverter( - "GPURenderBundleEncoder", - GPURenderBundleEncoder.prototype, - ); - - // DICTIONARY: GPURenderPassLayout - const dictMembersGPURenderPassLayout = [ - { - key: "colorFormats", - converter: webidl.createSequenceConverter( - webidl.converters["GPUTextureFormat"], - ), - required: true, - }, - { - key: "depthStencilFormat", - converter: webidl.converters["GPUTextureFormat"], - }, - { - key: "sampleCount", - converter: webidl.converters["GPUSize32"], - defaultValue: 1, - }, - ]; - webidl.converters["GPURenderPassLayout"] = webidl - .createDictionaryConverter( - "GPURenderPassLayout", - dictMembersGPUObjectDescriptorBase, - dictMembersGPURenderPassLayout, - ); - - // DICTIONARY: GPURenderBundleEncoderDescriptor - const dictMembersGPURenderBundleEncoderDescriptor = [ - { - key: "depthReadOnly", - converter: webidl.converters.boolean, - defaultValue: false, - }, - { - key: "stencilReadOnly", - converter: webidl.converters.boolean, - defaultValue: false, - }, - ]; - webidl.converters["GPURenderBundleEncoderDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderBundleEncoderDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPURenderPassLayout, - dictMembersGPURenderBundleEncoderDescriptor, - ); - - // INTERFACE: GPUQueue - webidl.converters.GPUQueue = webidl.createInterfaceConverter( - "GPUQueue", - GPUQueue.prototype, - ); - - // ENUM: GPUQueryType - webidl.converters["GPUQueryType"] = webidl.createEnumConverter( - "GPUQueryType", - [ - "occlusion", - "pipeline-statistics", - "timestamp", - ], - ); - - // ENUM: GPUPipelineStatisticName - webidl.converters["GPUPipelineStatisticName"] = webidl.createEnumConverter( - "GPUPipelineStatisticName", - [ - "vertex-shader-invocations", - "clipper-invocations", - "clipper-primitives-out", - "fragment-shader-invocations", - "compute-shader-invocations", - ], - ); - - // DICTIONARY: GPUQuerySetDescriptor - const dictMembersGPUQuerySetDescriptor = [ - { - key: "type", - converter: webidl.converters["GPUQueryType"], - required: true, - }, - { key: "count", converter: webidl.converters["GPUSize32"], required: true }, - { - key: "pipelineStatistics", - converter: webidl.createSequenceConverter( - webidl.converters["GPUPipelineStatisticName"], - ), - get defaultValue() { - return []; - }, - }, - ]; - webidl.converters["GPUQuerySetDescriptor"] = webidl.createDictionaryConverter( - "GPUQuerySetDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUQuerySetDescriptor, - ); - - // ENUM: GPUDeviceLostReason - webidl.converters["GPUDeviceLostReason"] = webidl.createEnumConverter( - "GPUDeviceLostReason", - [ - "destroyed", - ], - ); - - // // INTERFACE: GPUDeviceLostInfo - // webidl.converters.GPUDeviceLostInfo = webidl.createInterfaceConverter( - // "GPUDeviceLostInfo", - // GPUDeviceLostInfo.prototype, - // ); - - // ENUM: GPUErrorFilter - webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter( - "GPUErrorFilter", - [ - "out-of-memory", - "validation", - ], - ); - - // INTERFACE: GPUOutOfMemoryError - webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( - "GPUOutOfMemoryError", - GPUOutOfMemoryError.prototype, - ); - - // INTERFACE: GPUValidationError - webidl.converters.GPUValidationError = webidl.createInterfaceConverter( - "GPUValidationError", - GPUValidationError.prototype, - ); - - // TYPEDEF: GPUError - webidl.converters["GPUError"] = webidl.converters.any /** put union here! **/; - - // // INTERFACE: GPUUncapturedErrorEvent - // webidl.converters.GPUUncapturedErrorEvent = webidl.createInterfaceConverter( - // "GPUUncapturedErrorEvent", - // GPUUncapturedErrorEvent.prototype, - // ); - - // DICTIONARY: GPUUncapturedErrorEventInit - const dictMembersGPUUncapturedErrorEventInit = [ - { key: "error", converter: webidl.converters["GPUError"], required: true }, - ]; - webidl.converters["GPUUncapturedErrorEventInit"] = webidl - .createDictionaryConverter( - "GPUUncapturedErrorEventInit", - // dictMembersEventInit, - dictMembersGPUUncapturedErrorEventInit, - ); - - // TYPEDEF: GPUBufferDynamicOffset - webidl.converters["GPUBufferDynamicOffset"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // TYPEDEF: GPUSignedOffset32 - webidl.converters["GPUSignedOffset32"] = (V, opts) => - webidl.converters["long"](V, { ...opts, enforceRange: true }); - - // TYPEDEF: GPUFlagsConstant - webidl.converters["GPUFlagsConstant"] = webidl.converters["unsigned long"]; -})(this); diff --git a/ext/webgpu/src/01_webgpu.js b/ext/webgpu/src/01_webgpu.js new file mode 100644 index 000000000..be880d81d --- /dev/null +++ b/ext/webgpu/src/01_webgpu.js @@ -0,0 +1,5200 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// +/// +/// +/// + +"use strict"; + +((window) => { + const core = window.Deno.core; + const webidl = window.__bootstrap.webidl; + const eventTarget = window.__bootstrap.eventTarget; + const { DOMException } = window.__bootstrap.domException; + const { + ArrayBuffer, + ArrayBufferIsView, + ArrayIsArray, + ArrayPrototypeFilter, + ArrayPrototypeMap, + ArrayPrototypePop, + ArrayPrototypePush, + Error, + MathMax, + ObjectDefineProperty, + ObjectFreeze, + ObjectPrototypeIsPrototypeOf, + Promise, + PromiseAll, + PromisePrototypeCatch, + PromisePrototypeThen, + PromiseReject, + PromiseResolve, + SafeArrayIterator, + Set, + SetPrototypeEntries, + SetPrototypeForEach, + SetPrototypeHas, + SetPrototypeKeys, + SetPrototypeValues, + Symbol, + SymbolFor, + SymbolIterator, + TypeError, + Uint32Array, + Uint32ArrayPrototype, + Uint8Array, + } = window.__bootstrap.primordials; + + /** + * @param {any} self + * @param {{prefix: string, context: string}} opts + * @returns {InnerGPUDevice & {rid: number}} + */ + function assertDevice(self, { prefix, context }) { + const device = self[_device]; + const deviceRid = device?.rid; + if (deviceRid === undefined) { + throw new DOMException( + `${prefix}: ${context} references an invalid or destroyed device.`, + "OperationError", + ); + } + return device; + } + + /** + * @param {InnerGPUDevice} self + * @param {any} resource + * @param {{prefix: string, resourceContext: string, selfContext: string}} opts + * @returns {InnerGPUDevice & {rid: number}} + */ + function assertDeviceMatch( + self, + resource, + { prefix, resourceContext, selfContext }, + ) { + const resourceDevice = assertDevice(resource, { + prefix, + context: resourceContext, + }); + if (resourceDevice.rid !== self.rid) { + throw new DOMException( + `${prefix}: ${resourceContext} belongs to a diffent device than ${selfContext}.`, + "OperationError", + ); + } + return { ...resourceDevice, rid: resourceDevice.rid }; + } + + /** + * @param {any} self + * @param {{prefix: string, context: string}} opts + * @returns {number} + */ + function assertResource(self, { prefix, context }) { + const rid = self[_rid]; + if (rid === undefined) { + throw new DOMException( + `${prefix}: ${context} an invalid or destroyed resource.`, + "OperationError", + ); + } + return rid; + } + + /** + * @param {number[] | GPUExtent3DDict} data + * @returns {GPUExtent3DDict} + */ + function normalizeGPUExtent3D(data) { + if (ArrayIsArray(data)) { + return { + width: data[0], + height: data[1], + depthOrArrayLayers: data[2], + }; + } else { + return data; + } + } + + /** + * @param {number[] | GPUOrigin3DDict} data + * @returns {GPUOrigin3DDict} + */ + function normalizeGPUOrigin3D(data) { + if (ArrayIsArray(data)) { + return { + x: data[0], + y: data[1], + z: data[2], + }; + } else { + return data; + } + } + + /** + * @param {number[] | GPUColor} data + * @returns {GPUColor} + */ + function normalizeGPUColor(data) { + if (ArrayIsArray(data)) { + return { + r: data[0], + g: data[1], + b: data[2], + a: data[3], + }; + } else { + return data; + } + } + + class GPUOutOfMemoryError extends Error { + name = "GPUOutOfMemoryError"; + constructor() { + super("device out of memory"); + } + } + const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError.prototype; + + class GPUValidationError extends Error { + name = "GPUValidationError"; + /** @param {string} message */ + constructor(message) { + const prefix = "Failed to construct 'GPUValidationError'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + message = webidl.converters.DOMString(message, { + prefix, + context: "Argument 1", + }); + super(message); + } + } + const GPUValidationErrorPrototype = GPUValidationError.prototype; + + class GPU { + [webidl.brand] = webidl.brand; + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPURequestAdapterOptions} options + */ + async requestAdapter(options = {}) { + webidl.assertBranded(this, GPUPrototype); + options = webidl.converters.GPURequestAdapterOptions(options, { + prefix: "Failed to execute 'requestAdapter' on 'GPU'", + context: "Argument 1", + }); + + const { err, ...data } = await core.opAsync( + "op_webgpu_request_adapter", + { ...options }, + ); + + if (err) { + return null; + } else { + return createGPUAdapter(data.name, data); + } + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${inspect({})}`; + } + } + const GPUPrototype = GPU.prototype; + + const _name = Symbol("[[name]]"); + const _adapter = Symbol("[[adapter]]"); + const _cleanup = Symbol("[[cleanup]]"); + + /** + * @typedef InnerGPUAdapter + * @property {number} rid + * @property {GPUSupportedFeatures} features + * @property {GPUSupportedLimits} limits + * @property {boolean} isFallbackAdapter + */ + + /** + * @param {string} name + * @param {InnerGPUAdapter} inner + * @returns {GPUAdapter} + */ + function createGPUAdapter(name, inner) { + /** @type {GPUAdapter} */ + const adapter = webidl.createBranded(GPUAdapter); + adapter[_name] = name; + adapter[_adapter] = { + ...inner, + features: createGPUSupportedFeatures(inner.features), + limits: createGPUSupportedLimits(inner.limits), + }; + return adapter; + } + + class GPUAdapter { + /** @type {string} */ + [_name]; + /** @type {InnerGPUAdapter} */ + [_adapter]; + + /** @returns {string} */ + get name() { + webidl.assertBranded(this, GPUAdapterPrototype); + return this[_name]; + } + /** @returns {GPUSupportedFeatures} */ + get features() { + webidl.assertBranded(this, GPUAdapterPrototype); + return this[_adapter].features; + } + /** @returns {GPUSupportedLimits} */ + get limits() { + webidl.assertBranded(this, GPUAdapterPrototype); + return this[_adapter].limits; + } + /** @returns {boolean} */ + get isFallbackAdapter() { + return this[_adapter].isFallbackAdapter; + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPUDeviceDescriptor} descriptor + * @returns {Promise} + */ + async requestDevice(descriptor = {}) { + webidl.assertBranded(this, GPUAdapterPrototype); + const prefix = "Failed to execute 'requestDevice' on 'GPUAdapter'"; + descriptor = webidl.converters.GPUDeviceDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const requiredFeatures = descriptor.requiredFeatures ?? []; + for (const feature of requiredFeatures) { + if (!SetPrototypeHas(this[_adapter].features[_features], feature)) { + throw new TypeError( + `${prefix}: nonGuaranteedFeatures must be a subset of the adapter features.`, + ); + } + } + const requiredLimits = descriptor.requiredLimits; + // TODO(lucacasonato): validate requiredLimits + + const { rid, features, limits } = await core.opAsync( + "op_webgpu_request_device", + { + adapterRid: this[_adapter].rid, + labe: descriptor.label, + requiredFeatures, + requiredLimits, + }, + ); + + const inner = new InnerGPUDevice({ + rid, + adapter: this, + features: ObjectFreeze(features), + limits: ObjectFreeze(limits), + }); + return createGPUDevice( + descriptor.label ?? null, + inner, + createGPUQueue(descriptor.label ?? null, inner), + ); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + name: this.name, + features: this.features, + limits: this.limits, + }) + }`; + } + } + const GPUAdapterPrototype = GPUAdapter.prototype; + + const _limits = Symbol("[[limits]]"); + + function createGPUSupportedLimits(features) { + /** @type {GPUSupportedLimits} */ + const adapterFeatures = webidl.createBranded(GPUSupportedLimits); + adapterFeatures[_limits] = features; + return adapterFeatures; + } + + /** + * @typedef InnerAdapterLimits + * @property {number} maxTextureDimension1D + * @property {number} maxTextureDimension2D + * @property {number} maxTextureDimension3D + * @property {number} maxTextureArrayLayers + * @property {number} maxBindGroups + * @property {number} maxDynamicUniformBuffersPerPipelineLayout + * @property {number} maxDynamicStorageBuffersPerPipelineLayout + * @property {number} maxSampledTexturesPerShaderStage + * @property {number} maxSamplersPerShaderStage + * @property {number} maxStorageBuffersPerShaderStage + * @property {number} maxStorageTexturesPerShaderStage + * @property {number} maxUniformBuffersPerShaderStage + * @property {number} maxUniformBufferBindingSize + * @property {number} maxStorageBufferBindingSize + * @property {number} minUniformBufferOffsetAlignment + * @property {number} minStorageBufferOffsetAlignment + * @property {number} maxVertexBuffers + * @property {number} maxVertexAttributes + * @property {number} maxVertexBufferArrayStride + * @property {number} maxInterStageShaderComponents + * @property {number} maxComputeWorkgroupStorageSize + * @property {number} maxComputeInvocationsPerWorkgroup + * @property {number} maxComputeWorkgroupSizeX + * @property {number} maxComputeWorkgroupSizeY + * @property {number} maxComputeWorkgroupSizeZ + * @property {number} maxComputeWorkgroupsPerDimension + */ + + class GPUSupportedLimits { + /** @type {InnerAdapterLimits} */ + [_limits]; + constructor() { + webidl.illegalConstructor(); + } + + get maxTextureDimension1D() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxTextureDimension1D; + } + get maxTextureDimension2D() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxTextureDimension2D; + } + get maxTextureDimension3D() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxTextureDimension3D; + } + get maxTextureArrayLayers() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxTextureArrayLayers; + } + get maxBindGroups() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxBindGroups; + } + get maxDynamicUniformBuffersPerPipelineLayout() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxDynamicUniformBuffersPerPipelineLayout; + } + get maxDynamicStorageBuffersPerPipelineLayout() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxDynamicStorageBuffersPerPipelineLayout; + } + get maxSampledTexturesPerShaderStage() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxSampledTexturesPerShaderStage; + } + get maxSamplersPerShaderStage() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxSamplersPerShaderStage; + } + get maxStorageBuffersPerShaderStage() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxStorageBuffersPerShaderStage; + } + get maxStorageTexturesPerShaderStage() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxStorageTexturesPerShaderStage; + } + get maxUniformBuffersPerShaderStage() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxUniformBuffersPerShaderStage; + } + get maxUniformBufferBindingSize() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxUniformBufferBindingSize; + } + get maxStorageBufferBindingSize() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxStorageBufferBindingSize; + } + get minUniformBufferOffsetAlignment() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].minUniformBufferOffsetAlignment; + } + get minStorageBufferOffsetAlignment() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].minStorageBufferOffsetAlignment; + } + get maxVertexBuffers() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxVertexBuffers; + } + get maxVertexAttributes() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxVertexAttributes; + } + get maxVertexBufferArrayStride() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxVertexBufferArrayStride; + } + get maxInterStageShaderComponents() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxInterStageShaderComponents; + } + get maxComputeWorkgroupStorageSize() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeWorkgroupStorageSize; + } + get maxComputeInvocationsPerWorkgroup() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeInvocationsPerWorkgroup; + } + get maxComputeWorkgroupSizeX() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeWorkgroupSizeX; + } + get maxComputeWorkgroupSizeY() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeWorkgroupSizeY; + } + get maxComputeWorkgroupSizeZ() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeWorkgroupSizeZ; + } + get maxComputeWorkgroupsPerDimension() { + webidl.assertBranded(this, GPUSupportedLimitsPrototype); + return this[_limits].maxComputeWorkgroupsPerDimension; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${inspect(this[_limits])}`; + } + } + const GPUSupportedLimitsPrototype = GPUSupportedLimits.prototype; + + const _features = Symbol("[[features]]"); + + function createGPUSupportedFeatures(features) { + /** @type {GPUSupportedFeatures} */ + const adapterFeatures = webidl.createBranded(GPUSupportedFeatures); + adapterFeatures[_features] = new Set(features); + return adapterFeatures; + } + + class GPUSupportedFeatures { + /** @type {Set} */ + [_features]; + + constructor() { + webidl.illegalConstructor(); + } + + /** @return {IterableIterator<[string, string]>} */ + entries() { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return SetPrototypeEntries(this[_features]); + } + + /** @return {void} */ + forEach(callbackfn, thisArg) { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + SetPrototypeForEach(this[_features], callbackfn, thisArg); + } + + /** @return {boolean} */ + has(value) { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return SetPrototypeHas(this[_features], value); + } + + /** @return {IterableIterator} */ + keys() { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return SetPrototypeKeys(this[_features]); + } + + /** @return {IterableIterator} */ + values() { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return SetPrototypeValues(this[_features]); + } + + /** @return {number} */ + get size() { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return this[_features].size; + } + + [SymbolIterator]() { + webidl.assertBranded(this, GPUSupportedFeaturesPrototype); + return this[_features][SymbolIterator](); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect([...new SafeArrayIterator(this.values())]) + }`; + } + } + + const GPUSupportedFeaturesPrototype = GPUSupportedFeatures.prototype; + + const _reason = Symbol("[[reason]]"); + const _message = Symbol("[[message]]"); + + /** + * @param {string | undefined} reason + * @param {string} message + * @returns {GPUDeviceLostInfo} + */ + function createGPUDeviceLostInfo(reason, message) { + /** @type {GPUDeviceLostInfo} */ + const deviceLostInfo = webidl.createBranded(GPUDeviceLostInfo); + deviceLostInfo[_reason] = reason; + deviceLostInfo[_message] = message; + return deviceLostInfo; + } + + class GPUDeviceLostInfo { + /** @type {string | undefined} */ + [_reason]; + /** @type {string} */ + [_message]; + + constructor() { + webidl.illegalConstructor(); + } + + get reason() { + webidl.assertBranded(this, GPUDeviceLostInfoPrototype); + return this[_reason]; + } + get message() { + webidl.assertBranded(this, GPUDeviceLostInfoPrototype); + return this[_message]; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ reason: this[_reason], message: this[_message] }) + }`; + } + } + + const GPUDeviceLostInfoPrototype = GPUDeviceLostInfo.prototype; + + const _label = Symbol("[[label]]"); + + /** + * @param {string} name + * @param {any} type + */ + function GPUObjectBaseMixin(name, type) { + type.prototype[_label] = null; + ObjectDefineProperty(type.prototype, "label", { + /** + * @return {string | null} + */ + get() { + webidl.assertBranded(this, type.prototype); + return this[_label]; + }, + /** + * @param {string | null} label + */ + set(label) { + webidl.assertBranded(this, type.prototype); + label = webidl.converters["UVString?"](label, { + prefix: `Failed to set 'label' on '${name}'`, + context: "Argument 1", + }); + this[_label] = label; + }, + }); + } + + const _device = Symbol("[[device]]"); + const _queue = Symbol("[[queue]]"); + + /** + * @typedef ErrorScope + * @property {string} filter + * @property {Promise[]} operations + */ + + /** + * @typedef InnerGPUDeviceOptions + * @property {GPUAdapter} adapter + * @property {number | undefined} rid + * @property {GPUFeatureName[]} features + * @property {object} limits + */ + + class InnerGPUDevice { + /** @type {GPUAdapter} */ + adapter; + /** @type {number | undefined} */ + rid; + /** @type {GPUFeatureName[]} */ + features; + /** @type {object} */ + limits; + /** @type {WeakRef[]} */ + resources; + /** @type {boolean} */ + isLost; + /** @type {Promise} */ + lost; + /** @type {(info: GPUDeviceLostInfo) => void} */ + resolveLost; + /** @type {ErrorScope[]} */ + errorScopeStack; + + /** + * @param {InnerGPUDeviceOptions} options + */ + constructor(options) { + this.adapter = options.adapter; + this.rid = options.rid; + this.features = options.features; + this.limits = options.limits; + this.resources = []; + this.isLost = false; + this.resolveLost = () => {}; + this.lost = new Promise((resolve) => { + this.resolveLost = resolve; + }); + this.errorScopeStack = []; + } + + /** @param {any} resource */ + trackResource(resource) { + ArrayPrototypePush(this.resources, new WeakRef(resource)); + } + + /** @param {{ type: string, value: string | null } | undefined} err */ + pushError(err) { + this.pushErrorPromise(PromiseResolve(err)); + } + + /** @param {Promise<{ type: string, value: string | null } | undefined>} promise */ + pushErrorPromise(promise) { + const operation = PromisePrototypeThen(promise, (err) => { + if (err) { + switch (err.type) { + case "lost": + this.isLost = true; + this.resolveLost( + createGPUDeviceLostInfo(undefined, "device was lost"), + ); + break; + case "validation": + return PromiseReject( + new GPUValidationError(err.value ?? "validation error"), + ); + case "out-of-memory": + return PromiseReject(new GPUOutOfMemoryError()); + } + } + }); + + 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); + } + 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( + this.errorScopeStack, + ({ filter }) => filter == "out-of-memory", + ); + 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); + } else { + PromisePrototypeCatch(oomFilteredPromise, () => { + // TODO(lucacasonato): emit an UncapturedErrorEvent + }); + } + // prevent uncaptured promise rejections + PromisePrototypeCatch(oomFilteredPromise, (_err) => {}); + } + } + + /** + * @param {string | null} label + * @param {InnerGPUDevice} inner + * @param {GPUQueue} queue + * @returns {GPUDevice} + */ + function createGPUDevice(label, inner, queue) { + /** @type {GPUDevice} */ + const device = webidl.createBranded(GPUDevice); + device[_label] = label; + device[_device] = inner; + device[_queue] = queue; + return device; + } + + // TODO(@crowlKats): https://gpuweb.github.io/gpuweb/#errors-and-debugging + class GPUDevice extends eventTarget.EventTarget { + /** @type {InnerGPUDevice} */ + [_device]; + + /** @type {GPUQueue} */ + [_queue]; + + [_cleanup]() { + const device = this[_device]; + const resources = device.resources; + while (resources.length > 0) { + const resource = ArrayPrototypePop(resources)?.deref(); + if (resource) { + resource[_cleanup](); + } + } + const rid = device.rid; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + device.rid = undefined; + } + } + + get features() { + webidl.assertBranded(this, GPUDevicePrototype); + return this[_device].features; + } + get limits() { + webidl.assertBranded(this, GPUDevicePrototype); + return this[_device].limits; + } + get queue() { + webidl.assertBranded(this, GPUDevicePrototype); + return this[_queue]; + } + + constructor() { + webidl.illegalConstructor(); + super(); + } + + destroy() { + webidl.assertBranded(this, GPUDevicePrototype); + this[_cleanup](); + } + + /** + * @param {GPUBufferDescriptor} descriptor + * @returns {GPUBuffer} + */ + createBuffer(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createBuffer' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUBufferDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_buffer", { + deviceRid: device.rid, + ...descriptor, + }); + device.pushError(err); + /** @type {CreateGPUBufferOptions} */ + let options; + if (descriptor.mappedAtCreation) { + options = { + mapping: new ArrayBuffer(descriptor.size), + mappingRange: [0, descriptor.size], + mappedRanges: [], + state: "mapped at creation", + }; + } else { + options = { + mapping: null, + mappedRanges: null, + mappingRange: null, + state: "unmapped", + }; + } + const buffer = createGPUBuffer( + descriptor.label ?? null, + device, + rid, + descriptor.size, + descriptor.usage, + options, + ); + device.trackResource(buffer); + return buffer; + } + + /** + * @param {GPUTextureDescriptor} descriptor + * @returns {GPUTexture} + */ + createTexture(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createTexture' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUTextureDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_texture", { + deviceRid: device.rid, + ...descriptor, + size: normalizeGPUExtent3D(descriptor.size), + }); + device.pushError(err); + + const texture = createGPUTexture( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(texture); + return texture; + } + + /** + * @param {GPUSamplerDescriptor} descriptor + * @returns {GPUSampler} + */ + createSampler(descriptor = {}) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createSampler' on 'GPUDevice'"; + descriptor = webidl.converters.GPUSamplerDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_sampler", { + deviceRid: device.rid, + ...descriptor, + }); + device.pushError(err); + + const sampler = createGPUSampler( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(sampler); + return sampler; + } + + /** + * @param {GPUBindGroupLayoutDescriptor} descriptor + * @returns {GPUBindGroupLayout} + */ + createBindGroupLayout(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createBindGroupLayout' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUBindGroupLayoutDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + for (const entry of descriptor.entries) { + let i = 0; + if (entry.buffer) i++; + if (entry.sampler) i++; + if (entry.texture) i++; + if (entry.storageTexture) i++; + + if (i !== 1) { + throw new Error(); // TODO(@crowlKats): correct error + } + } + + const { rid, err } = core.opSync( + "op_webgpu_create_bind_group_layout", + { + deviceRid: device.rid, + ...descriptor, + }, + ); + device.pushError(err); + + const bindGroupLayout = createGPUBindGroupLayout( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(bindGroupLayout); + return bindGroupLayout; + } + + /** + * @param {GPUPipelineLayoutDescriptor} descriptor + * @returns {GPUPipelineLayout} + */ + createPipelineLayout(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createPipelineLayout' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUPipelineLayoutDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const bindGroupLayouts = ArrayPrototypeMap( + descriptor.bindGroupLayouts, + (layout, i) => { + const context = `bind group layout ${i + 1}`; + const rid = assertResource(layout, { prefix, context }); + assertDeviceMatch(device, layout, { + prefix, + selfContext: "this", + resourceContext: context, + }); + return rid; + }, + ); + const { rid, err } = core.opSync("op_webgpu_create_pipeline_layout", { + deviceRid: device.rid, + label: descriptor.label, + bindGroupLayouts, + }); + device.pushError(err); + + const pipelineLayout = createGPUPipelineLayout( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(pipelineLayout); + return pipelineLayout; + } + + /** + * @param {GPUBindGroupDescriptor} descriptor + * @returns {GPUBindGroup} + */ + createBindGroup(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createBindGroup' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUBindGroupDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const layout = assertResource(descriptor.layout, { + prefix, + context: "layout", + }); + assertDeviceMatch(device, descriptor.layout, { + prefix, + resourceContext: "layout", + selfContext: "this", + }); + const entries = ArrayPrototypeMap(descriptor.entries, (entry, i) => { + const context = `entry ${i + 1}`; + 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", + resource: rid, + }; + } else if ( + ObjectPrototypeIsPrototypeOf(GPUTextureViewPrototype, resource) + ) { + 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", + resource: rid, + }; + } else { + const rid = assertResource(resource.buffer, { prefix, context }); + assertDeviceMatch(device, resource.buffer, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return { + binding: entry.binding, + kind: "GPUBufferBinding", + resource: rid, + offset: entry.resource.offset, + size: entry.resource.size, + }; + } + }); + + const { rid, err } = core.opSync("op_webgpu_create_bind_group", { + deviceRid: device.rid, + label: descriptor.label, + layout, + entries, + }); + device.pushError(err); + + const bindGroup = createGPUBindGroup( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(bindGroup); + return bindGroup; + } + + /** + * @param {GPUShaderModuleDescriptor} descriptor + */ + createShaderModule(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createShaderModule' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUShaderModuleDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync( + "op_webgpu_create_shader_module", + { + deviceRid: device.rid, + label: descriptor.label, + code: descriptor.code, + sourceMap: descriptor.sourceMap, + }, + ); + device.pushError(err); + + const shaderModule = createGPUShaderModule( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(shaderModule); + return shaderModule; + } + + /** + * @param {GPUComputePipelineDescriptor} descriptor + * @returns {GPUComputePipeline} + */ + createComputePipeline(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createComputePipeline' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUComputePipelineDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + let layout = undefined; + if (descriptor.layout) { + 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, + context: "compute shader module", + }); + assertDeviceMatch(device, descriptor.compute.module, { + prefix, + resourceContext: "compute shader module", + selfContext: "this", + }); + + const { rid, err } = core.opSync( + "op_webgpu_create_compute_pipeline", + { + deviceRid: device.rid, + label: descriptor.label, + layout, + compute: { + module, + entryPoint: descriptor.compute.entryPoint, + constants: descriptor.compute.constants, + }, + }, + ); + device.pushError(err); + + const computePipeline = createGPUComputePipeline( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(computePipeline); + return computePipeline; + } + + /** + * @param {GPURenderPipelineDescriptor} descriptor + * @returns {GPURenderPipeline} + */ + createRenderPipeline(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createRenderPipeline' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderPipelineDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + let layout = undefined; + if (descriptor.layout) { + 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, + context: "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, + context: "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 } = core.opSync("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); + + const renderPipeline = createGPURenderPipeline( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(renderPipeline); + return renderPipeline; + } + + createComputePipelineAsync(descriptor) { + // TODO(lucacasonato): this should be real async + return PromiseResolve(this.createComputePipeline(descriptor)); + } + + createRenderPipelineAsync(descriptor) { + // TODO(lucacasonato): this should be real async + return PromiseResolve(this.createRenderPipeline(descriptor)); + } + + /** + * @param {GPUCommandEncoderDescriptor} descriptor + * @returns {GPUCommandEncoder} + */ + createCommandEncoder(descriptor = {}) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createCommandEncoder' on 'GPUDevice'"; + descriptor = webidl.converters.GPUCommandEncoderDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_command_encoder", { + deviceRid: device.rid, + ...descriptor, + }); + device.pushError(err); + + const commandEncoder = createGPUCommandEncoder( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(commandEncoder); + return commandEncoder; + } + + /** + * @param {GPURenderBundleEncoderDescriptor} descriptor + * @returns {GPURenderBundleEncoder} + */ + createRenderBundleEncoder(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = + "Failed to execute 'createRenderBundleEncoder' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderBundleEncoderDescriptor( + descriptor, + { + prefix, + context: "Argument 1", + }, + ); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync( + "op_webgpu_create_render_bundle_encoder", + { + deviceRid: device.rid, + ...descriptor, + }, + ); + device.pushError(err); + + const renderBundleEncoder = createGPURenderBundleEncoder( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(renderBundleEncoder); + return renderBundleEncoder; + } + + /** + * @param {GPUQuerySetDescriptor} descriptor + * @returns {GPUQuerySet} + */ + createQuerySet(descriptor) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'createQuerySet' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPUQuerySetDescriptor( + descriptor, + { + prefix, + context: "Argument 1", + }, + ); + const device = assertDevice(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_query_set", { + deviceRid: device.rid, + ...descriptor, + }); + device.pushError(err); + + const querySet = createGPUQuerySet( + descriptor.label ?? null, + device, + rid, + descriptor, + ); + device.trackResource(querySet); + return querySet; + } + + get lost() { + webidl.assertBranded(this, GPUDevicePrototype); + const device = this[_device]; + if (!device) { + return PromiseResolve(true); + } + if (device.rid === undefined) { + return PromiseResolve(true); + } + return device.lost; + } + + /** + * @param {GPUErrorFilter} filter + */ + pushErrorScope(filter) { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'pushErrorScope' on 'GPUDevice'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + filter = webidl.converters.GPUErrorFilter(filter, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + ArrayPrototypePush(device.errorScopeStack, { filter, operations: [] }); + } + + /** + * @returns {Promise} + */ + // deno-lint-ignore require-await + async popErrorScope() { + webidl.assertBranded(this, GPUDevicePrototype); + const prefix = "Failed to execute 'popErrorScope' on 'GPUDevice'"; + const device = assertDevice(this, { prefix, context: "this" }); + if (device.isLost) { + throw new DOMException("Device has been lost.", "OperationError"); + } + const scope = ArrayPrototypePop(device.errorScopeStack); + if (!scope) { + throw new DOMException( + "There are no error scopes on the error scope stack.", + "OperationError", + ); + } + const operations = PromiseAll(scope.operations); + return PromisePrototypeThen( + operations, + () => PromiseResolve(null), + (err) => PromiseResolve(err), + ); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + features: this.features, + label: this.label, + limits: this.limits, + queue: this.queue, + }) + }`; + } + } + GPUObjectBaseMixin("GPUDevice", GPUDevice); + const GPUDevicePrototype = GPUDevice.prototype; + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @returns {GPUQueue} + */ + function createGPUQueue(label, device) { + /** @type {GPUQueue} */ + const queue = webidl.createBranded(GPUQueue); + queue[_label] = label; + queue[_device] = device; + return queue; + } + + class GPUQueue { + /** @type {InnerGPUDevice} */ + [_device]; + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPUCommandBuffer[]} commandBuffers + */ + submit(commandBuffers) { + webidl.assertBranded(this, GPUQueue.prototype); + const prefix = "Failed to execute 'submit' on 'GPUQueue'"; + webidl.requiredArguments(arguments.length, 1, { + prefix, + }); + commandBuffers = webidl.converters["sequence"]( + commandBuffers, + { prefix, context: "Argument 1" }, + ); + const device = assertDevice(this, { prefix, context: "this" }); + const commandBufferRids = ArrayPrototypeMap( + commandBuffers, + (buffer, i) => { + const context = `command buffer ${i + 1}`; + const rid = assertResource(buffer, { prefix, context }); + assertDeviceMatch(device, buffer, { + prefix, + selfContext: "this", + resourceContext: context, + }); + return rid; + }, + ); + const { err } = core.opSync("op_webgpu_queue_submit", { + queueRid: device.rid, + commandBuffers: commandBufferRids, + }); + device.pushError(err); + } + + onSubmittedWorkDone() { + webidl.assertBranded(this, GPUQueue.prototype); + return PromiseResolve(); + } + + /** + * @param {GPUBuffer} buffer + * @param {number} bufferOffset + * @param {BufferSource} data + * @param {number} [dataOffset] + * @param {number} [size] + */ + writeBuffer(buffer, bufferOffset, data, dataOffset = 0, size) { + webidl.assertBranded(this, GPUQueue.prototype); + const prefix = "Failed to execute 'writeBuffer' on 'GPUQueue'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + buffer = webidl.converters["GPUBuffer"](buffer, { + prefix, + context: "Argument 1", + }); + bufferOffset = webidl.converters["GPUSize64"](bufferOffset, { + prefix, + context: "Argument 2", + }); + data = webidl.converters.BufferSource(data, { + prefix, + context: "Argument 3", + }); + dataOffset = webidl.converters["GPUSize64"](dataOffset, { + prefix, + context: "Argument 4", + }); + size = size === undefined + ? undefined + : webidl.converters["GPUSize64"](size, { + prefix, + context: "Argument 5", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + selfContext: "this", + resourceContext: "Argument 1", + }); + const { err } = core.opSync( + "op_webgpu_write_buffer", + { + queueRid: device.rid, + buffer: bufferRid, + bufferOffset, + dataOffset, + size, + }, + new Uint8Array(ArrayBufferIsView(data) ? data.buffer : data), + ); + device.pushError(err); + } + + /** + * @param {GPUImageCopyTexture} destination + * @param {BufferSource} data + * @param {GPUImageDataLayout} dataLayout + * @param {GPUExtent3D} size + */ + writeTexture(destination, data, dataLayout, size) { + webidl.assertBranded(this, GPUQueue.prototype); + const prefix = "Failed to execute 'writeTexture' on 'GPUQueue'"; + webidl.requiredArguments(arguments.length, 4, { prefix }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 1", + }); + data = webidl.converters.BufferSource(data, { + prefix, + context: "Argument 2", + }); + dataLayout = webidl.converters.GPUImageDataLayout(dataLayout, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUExtent3D(size, { + prefix, + context: "Argument 4", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const textureRid = assertResource(destination.texture, { + prefix, + context: "texture", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + selfContext: "this", + resourceContext: "texture", + }); + const { err } = core.opSync( + "op_webgpu_write_texture", + { + queueRid: device.rid, + destination: { + texture: textureRid, + mipLevel: destination.mipLevel, + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, + aspect: destination.aspect, + }, + dataLayout, + size: normalizeGPUExtent3D(size), + }, + new Uint8Array(ArrayBufferIsView(data) ? data.buffer : data), + ); + device.pushError(err); + } + + copyImageBitmapToTexture(_source, _destination, _copySize) { + throw new Error("Not yet implemented"); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUQueue", GPUQueue); + + const _rid = Symbol("[[rid]]"); + + const _size = Symbol("[[size]]"); + const _usage = Symbol("[[usage]]"); + const _state = Symbol("[[state]]"); + const _mappingRange = Symbol("[[mapping_range]]"); + const _mappedRanges = Symbol("[[mapped_ranges]]"); + const _mapMode = Symbol("[[map_mode]]"); + + /** + * @typedef CreateGPUBufferOptions + * @property {ArrayBuffer | null} mapping + * @property {number[] | null} mappingRange + * @property {[ArrayBuffer, number, number][] | null} mappedRanges + * @property {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy" } state + */ + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @param {number} size + * @param {number} usage + * @param {CreateGPUBufferOptions} options + * @returns {GPUBuffer} + */ + function createGPUBuffer(label, device, rid, size, usage, options) { + /** @type {GPUBuffer} */ + const buffer = webidl.createBranded(GPUBuffer); + buffer[_label] = label; + buffer[_device] = device; + buffer[_rid] = rid; + buffer[_size] = size; + buffer[_usage] = usage; + buffer[_mappingRange] = options.mappingRange; + buffer[_mappedRanges] = options.mappedRanges; + buffer[_state] = options.state; + return buffer; + } + + class GPUBuffer { + /** @type {InnerGPUDevice} */ + [_device]; + + /** @type {number} */ + [_rid]; + + /** @type {number} */ + [_size]; + + /** @type {number} */ + [_usage]; + + /** @type {"mapped" | "mapped at creation" | "mapped pending" | "unmapped" | "destroy"} */ + [_state]; + + /** @type {[number, number] | null} */ + [_mappingRange]; + + /** @type {[ArrayBuffer, number, number][] | null} */ + [_mappedRanges]; + + /** @type {number} */ + [_mapMode]; + + [_cleanup]() { + const mappedRanges = this[_mappedRanges]; + if (mappedRanges) { + while (mappedRanges.length > 0) { + const mappedRange = ArrayPrototypePop(mappedRanges); + if (mappedRange !== undefined) { + core.close(mappedRange[1]); + } + } + } + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + this[_state] = "destroy"; + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {number} mode + * @param {number} offset + * @param {number} [size] + */ + async mapAsync(mode, offset = 0, size) { + webidl.assertBranded(this, GPUBuffer.prototype); + const prefix = "Failed to execute 'mapAsync' on 'GPUBuffer'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + mode = webidl.converters.GPUMapModeFlags(mode, { + prefix, + context: "Argument 1", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 2", + }); + size = size === undefined + ? undefined + : webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); + /** @type {number} */ + let rangeSize; + if (size === undefined) { + rangeSize = MathMax(0, this[_size] - offset); + } else { + rangeSize = this[_size]; + } + if ((offset % 8) !== 0) { + throw new DOMException( + `${prefix}: offset must be a multiple of 8.`, + "OperationError", + ); + } + if ((rangeSize % 4) !== 0) { + throw new DOMException( + `${prefix}: rangeSize must be a multiple of 4.`, + "OperationError", + ); + } + if ((offset + rangeSize) > this[_size]) { + throw new DOMException( + `${prefix}: offset + rangeSize must be less than or equal to buffer size.`, + "OperationError", + ); + } + if (this[_state] !== "unmapped") { + throw new DOMException( + `${prefix}: GPUBuffer is not currently unmapped.`, + "OperationError", + ); + } + const readMode = (mode & 0x0001) === 0x0001; + const writeMode = (mode & 0x0002) === 0x0002; + if ((readMode && writeMode) || (!readMode && !writeMode)) { + throw new DOMException( + `${prefix}: exactly one of READ or WRITE map mode must be set.`, + "OperationError", + ); + } + if (readMode && !((this[_usage] && 0x0001) === 0x0001)) { + throw new DOMException( + `${prefix}: READ map mode not valid because buffer does not have MAP_READ usage.`, + "OperationError", + ); + } + if (writeMode && !((this[_usage] && 0x0002) === 0x0002)) { + throw new DOMException( + `${prefix}: WRITE map mode not valid because buffer does not have MAP_WRITE usage.`, + "OperationError", + ); + } + + this[_mapMode] = mode; + this[_state] = "mapping pending"; + const promise = PromisePrototypeThen( + core.opAsync( + "op_webgpu_buffer_get_map_async", + { + bufferRid, + deviceRid: device.rid, + mode, + offset, + size: rangeSize, + }, + ), + ({ err }) => err, + ); + device.pushErrorPromise(promise); + const err = await promise; + if (err) { + throw new DOMException("validation error occured", "OperationError"); + } + this[_state] = "mapped"; + this[_mappingRange] = [offset, offset + rangeSize]; + /** @type {[ArrayBuffer, number, number][] | null} */ + this[_mappedRanges] = []; + } + + /** + * @param {number} offset + * @param {number} size + */ + getMappedRange(offset = 0, size) { + webidl.assertBranded(this, GPUBuffer.prototype); + const prefix = "Failed to execute 'getMappedRange' on 'GPUBuffer'"; + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 1", + }); + if (size !== undefined) { + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 2", + }); + } + assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); + /** @type {number} */ + let rangeSize; + if (size === undefined) { + rangeSize = MathMax(0, this[_size] - offset); + } else { + rangeSize = size; + } + + const mappedRanges = this[_mappedRanges]; + if (!mappedRanges) { + throw new DOMException(`${prefix}: invalid state.`, "OperationError"); + } + for (const [buffer, _rid, start] of mappedRanges) { + // TODO(lucacasonato): is this logic correct? + const end = start + buffer.byteLength; + if ( + (start >= offset && start < (offset + rangeSize)) || + (end >= offset && end < (offset + rangeSize)) + ) { + throw new DOMException( + `${prefix}: requested buffer overlaps with another mapped range.`, + "OperationError", + ); + } + } + + const buffer = new ArrayBuffer(rangeSize); + const { rid } = core.opSync( + "op_webgpu_buffer_get_mapped_range", + { + bufferRid, + offset, + size, + }, + new Uint8Array(buffer), + ); + + ArrayPrototypePush(mappedRanges, [buffer, rid, offset]); + + return buffer; + } + + unmap() { + webidl.assertBranded(this, GPUBuffer.prototype); + const prefix = "Failed to execute 'unmap' on 'GPUBuffer'"; + const device = assertDevice(this, { prefix, context: "this" }); + const bufferRid = assertResource(this, { prefix, context: "this" }); + if (this[_state] === "unmapped" || this[_state] === "destroyed") { + throw new DOMException( + `${prefix}: buffer is not ready to be unmapped.`, + "OperationError", + ); + } + if (this[_state] === "mapping pending") { + // TODO(lucacasonato): this is not spec compliant. + throw new DOMException( + `${prefix}: can not unmap while mapping. This is a Deno limitation.`, + "OperationError", + ); + } else if ( + this[_state] === "mapped" || this[_state] === "mapped at creation" + ) { + /** @type {boolean} */ + let write = false; + if (this[_state] === "mapped at creation") { + write = true; + } else if (this[_state] === "mapped") { + const mapMode = this[_mapMode]; + if (mapMode === undefined) { + throw new DOMException( + `${prefix}: invalid state.`, + "OperationError", + ); + } + if ((mapMode & 0x0002) === 0x0002) { + write = true; + } + } + + const mappedRanges = this[_mappedRanges]; + if (!mappedRanges) { + throw new DOMException(`${prefix}: invalid state.`, "OperationError"); + } + for (const [buffer, mappedRid] of mappedRanges) { + const { err } = core.opSync("op_webgpu_buffer_unmap", { + bufferRid, + mappedRid, + }, ...new SafeArrayIterator(write ? [new Uint8Array(buffer)] : [])); + device.pushError(err); + if (err) return; + } + this[_mappingRange] = null; + this[_mappedRanges] = null; + } + + this[_state] = "unmapped"; + } + + destroy() { + webidl.assertBranded(this, GPUBuffer.prototype); + this[_cleanup](); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUBuffer", GPUBuffer); + + class GPUBufferUsage { + constructor() { + webidl.illegalConstructor(); + } + + static get MAP_READ() { + return 0x0001; + } + static get MAP_WRITE() { + return 0x0002; + } + static get COPY_SRC() { + return 0x0004; + } + static get COPY_DST() { + return 0x0008; + } + static get INDEX() { + return 0x0010; + } + static get VERTEX() { + return 0x0020; + } + static get UNIFORM() { + return 0x0040; + } + static get STORAGE() { + return 0x0080; + } + static get INDIRECT() { + return 0x0100; + } + static get QUERY_RESOLVE() { + return 0x0200; + } + } + + class GPUMapMode { + constructor() { + webidl.illegalConstructor(); + } + + static get READ() { + return 0x0001; + } + static get WRITE() { + return 0x0002; + } + } + + const _views = Symbol("[[views]]"); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUTexture} + */ + function createGPUTexture(label, device, rid) { + /** @type {GPUTexture} */ + const texture = webidl.createBranded(GPUTexture); + texture[_label] = label; + texture[_device] = device; + texture[_rid] = rid; + texture[_views] = []; + return texture; + } + + class GPUTexture { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + /** @type {WeakRef[]} */ + [_views]; + + [_cleanup]() { + const views = this[_views]; + while (views.length > 0) { + const view = ArrayPrototypePop(views)?.deref(); + if (view) { + view[_cleanup](); + } + } + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPUTextureViewDescriptor} descriptor + */ + createView(descriptor = {}) { + webidl.assertBranded(this, GPUTexture.prototype); + const prefix = "Failed to execute 'createView' on 'GPUTexture'"; + webidl.requiredArguments(arguments.length, 0, { prefix }); + descriptor = webidl.converters.GPUTextureViewDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const textureRid = assertResource(this, { prefix, context: "this" }); + const { rid, err } = core.opSync("op_webgpu_create_texture_view", { + textureRid, + ...descriptor, + }); + device.pushError(err); + + const textureView = createGPUTextureView( + descriptor.label ?? null, + this, + rid, + ); + ArrayPrototypePush(this[_views], new WeakRef(textureView)); + return textureView; + } + + destroy() { + webidl.assertBranded(this, GPUTexture.prototype); + this[_cleanup](); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUTexture", GPUTexture); + + class GPUTextureUsage { + constructor() { + webidl.illegalConstructor(); + } + + static get COPY_SRC() { + return 0x01; + } + static get COPY_DST() { + return 0x02; + } + static get TEXTURE_BINDING() { + return 0x04; + } + static get STORAGE_BINDING() { + return 0x08; + } + static get RENDER_ATTACHMENT() { + return 0x10; + } + } + + const _texture = Symbol("[[texture]]"); + + /** + * @param {string | null} label + * @param {GPUTexture} texture + * @param {number} rid + * @returns {GPUTextureView} + */ + function createGPUTextureView(label, texture, rid) { + /** @type {GPUTextureView} */ + const textureView = webidl.createBranded(GPUTextureView); + textureView[_label] = label; + textureView[_texture] = texture; + textureView[_rid] = rid; + return textureView; + } + class GPUTextureView { + /** @type {GPUTexture} */ + [_texture]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUTextureView", GPUTextureView); + const GPUTextureViewPrototype = GPUTextureView.prototype; + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUSampler} + */ + function createGPUSampler(label, device, rid) { + /** @type {GPUSampler} */ + const sampler = webidl.createBranded(GPUSampler); + sampler[_label] = label; + sampler[_device] = device; + sampler[_rid] = rid; + return sampler; + } + class GPUSampler { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUSampler", GPUSampler); + const GPUSamplerPrototype = GPUSampler.prototype; + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUBindGroupLayout} + */ + function createGPUBindGroupLayout(label, device, rid) { + /** @type {GPUBindGroupLayout} */ + const bindGroupLayout = webidl.createBranded(GPUBindGroupLayout); + bindGroupLayout[_label] = label; + bindGroupLayout[_device] = device; + bindGroupLayout[_rid] = rid; + return bindGroupLayout; + } + class GPUBindGroupLayout { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUBindGroupLayout", GPUBindGroupLayout); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUPipelineLayout} + */ + function createGPUPipelineLayout(label, device, rid) { + /** @type {GPUPipelineLayout} */ + const pipelineLayout = webidl.createBranded(GPUPipelineLayout); + pipelineLayout[_label] = label; + pipelineLayout[_device] = device; + pipelineLayout[_rid] = rid; + return pipelineLayout; + } + class GPUPipelineLayout { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUPipelineLayout", GPUPipelineLayout); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUBindGroup} + */ + function createGPUBindGroup(label, device, rid) { + /** @type {GPUBindGroup} */ + const bindGroup = webidl.createBranded(GPUBindGroup); + bindGroup[_label] = label; + bindGroup[_device] = device; + bindGroup[_rid] = rid; + return bindGroup; + } + class GPUBindGroup { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUBindGroup", GPUBindGroup); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUShaderModule} + */ + function createGPUShaderModule(label, device, rid) { + /** @type {GPUShaderModule} */ + const bindGroup = webidl.createBranded(GPUShaderModule); + bindGroup[_label] = label; + bindGroup[_device] = device; + bindGroup[_rid] = rid; + return bindGroup; + } + class GPUShaderModule { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + compilationInfo() { + throw new Error("Not yet implemented"); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUShaderModule", GPUShaderModule); + + class GPUShaderStage { + constructor() { + webidl.illegalConstructor(); + } + + static get VERTEX() { + return 0x1; + } + + static get FRAGMENT() { + return 0x2; + } + + static get COMPUTE() { + return 0x4; + } + } + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUComputePipeline} + */ + function createGPUComputePipeline(label, device, rid) { + /** @type {GPUComputePipeline} */ + const pipeline = webidl.createBranded(GPUComputePipeline); + pipeline[_label] = label; + pipeline[_device] = device; + pipeline[_rid] = rid; + return pipeline; + } + class GPUComputePipeline { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {number} index + * @returns {GPUBindGroupLayout} + */ + getBindGroupLayout(index) { + webidl.assertBranded(this, GPUComputePipelinePrototype); + const prefix = + "Failed to execute 'getBindGroupLayout' on 'GPUComputePipeline'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + index = webidl.converters["unsigned long"](index, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const computePipelineRid = assertResource(this, { + prefix, + context: "this", + }); + const { rid, label, err } = core.opSync( + "op_webgpu_compute_pipeline_get_bind_group_layout", + { computePipelineRid, index }, + ); + device.pushError(err); + + const bindGroupLayout = createGPUBindGroupLayout( + label, + device, + rid, + ); + device.trackResource(bindGroupLayout); + return bindGroupLayout; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUComputePipeline", GPUComputePipeline); + const GPUComputePipelinePrototype = GPUComputePipeline.prototype; + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPURenderPipeline} + */ + function createGPURenderPipeline(label, device, rid) { + /** @type {GPURenderPipeline} */ + const pipeline = webidl.createBranded(GPURenderPipeline); + pipeline[_label] = label; + pipeline[_device] = device; + pipeline[_rid] = rid; + return pipeline; + } + class GPURenderPipeline { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {number} index + */ + getBindGroupLayout(index) { + webidl.assertBranded(this, GPURenderPipelinePrototype); + const prefix = + "Failed to execute 'getBindGroupLayout' on 'GPURenderPipeline'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + index = webidl.converters["unsigned long"](index, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderPipelineRid = assertResource(this, { + prefix, + context: "this", + }); + const { rid, label, err } = core.opSync( + "op_webgpu_render_pipeline_get_bind_group_layout", + { renderPipelineRid, index }, + ); + device.pushError(err); + + const bindGroupLayout = createGPUBindGroupLayout( + label, + device, + rid, + ); + device.trackResource(bindGroupLayout); + return bindGroupLayout; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPURenderPipeline", GPURenderPipeline); + const GPURenderPipelinePrototype = GPURenderPipeline.prototype; + + class GPUColorWrite { + constructor() { + webidl.illegalConstructor(); + } + + static get RED() { + return 0x1; + } + static get GREEN() { + return 0x2; + } + static get BLUE() { + return 0x4; + } + static get ALPHA() { + return 0x8; + } + static get ALL() { + return 0xF; + } + } + + const _encoders = Symbol("[[encoders]]"); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUCommandEncoder} + */ + function createGPUCommandEncoder(label, device, rid) { + /** @type {GPUCommandEncoder} */ + const encoder = webidl.createBranded(GPUCommandEncoder); + encoder[_label] = label; + encoder[_device] = device; + encoder[_rid] = rid; + encoder[_encoders] = []; + return encoder; + } + class GPUCommandEncoder { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + /** @type {WeakRef[]} */ + [_encoders]; + + [_cleanup]() { + const encoders = this[_encoders]; + while (encoders.length > 0) { + const encoder = ArrayPrototypePop(encoders)?.deref(); + if (encoder) { + encoder[_cleanup](); + } + } + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPURenderPassDescriptor} descriptor + * @return {GPURenderPassEncoder} + */ + beginRenderPass(descriptor) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + descriptor = webidl.converters.GPURenderPassDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + + if (this[_rid] === undefined) { + throw new DOMException( + "Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': already consumed", + "OperationError", + ); + } + + let depthStencilAttachment; + if (descriptor.depthStencilAttachment) { + const view = assertResource(descriptor.depthStencilAttachment.view, { + prefix, + context: "texture view for depth stencil attachment", + }); + assertDeviceMatch( + device, + descriptor.depthStencilAttachment.view[_texture], + { + prefix, + resourceContext: "texture view for depth stencil attachment", + selfContext: "this", + }, + ); + + depthStencilAttachment = { + ...descriptor.depthStencilAttachment, + view, + }; + + if ( + typeof descriptor.depthStencilAttachment.depthLoadValue === "string" + ) { + depthStencilAttachment.depthLoadOp = + descriptor.depthStencilAttachment.depthLoadValue; + } else { + depthStencilAttachment.depthLoadOp = { + clear: descriptor.depthStencilAttachment.depthLoadValue, + }; + } + + if ( + typeof descriptor.depthStencilAttachment.stencilLoadValue === "string" + ) { + depthStencilAttachment.stencilLoadOp = + descriptor.depthStencilAttachment.stencilLoadValue; + } else { + depthStencilAttachment.stencilLoadOp = { + clear: descriptor.depthStencilAttachment.stencilLoadValue, + }; + } + } + const colorAttachments = ArrayPrototypeMap( + descriptor.colorAttachments, + (colorAttachment, i) => { + const context = `color attachment ${i + 1}`; + const view = assertResource(colorAttachment.view, { + prefix, + context: `texture view for ${context}`, + }); + assertResource(colorAttachment.view[_texture], { + prefix, + context: `texture backing texture view for ${context}`, + }); + assertDeviceMatch( + device, + colorAttachment.view[_texture], + { + prefix, + resourceContext: `texture view for ${context}`, + selfContext: "this", + }, + ); + let resolveTarget; + if (colorAttachment.resolveTarget) { + resolveTarget = assertResource( + colorAttachment.resolveTarget, + { + prefix, + context: `resolve target texture view for ${context}`, + }, + ); + assertResource(colorAttachment.resolveTarget[_texture], { + prefix, + context: + `texture backing resolve target texture view for ${context}`, + }); + assertDeviceMatch( + device, + colorAttachment.resolveTarget[_texture], + { + prefix, + resourceContext: `resolve target texture view for ${context}`, + selfContext: "this", + }, + ); + } + const attachment = { + view: view, + resolveTarget, + storeOp: colorAttachment.storeOp, + }; + + if (typeof colorAttachment.loadValue === "string") { + attachment.loadOp = colorAttachment.loadValue; + } else { + attachment.loadOp = { + clear: normalizeGPUColor(colorAttachment.loadValue), + }; + } + + return attachment; + }, + ); + + const { rid } = core.opSync( + "op_webgpu_command_encoder_begin_render_pass", + { + commandEncoderRid, + ...descriptor, + colorAttachments, + depthStencilAttachment, + }, + ); + + const renderPassEncoder = createGPURenderPassEncoder( + descriptor.label ?? null, + this, + rid, + ); + ArrayPrototypePush(this[_encoders], new WeakRef(renderPassEncoder)); + return renderPassEncoder; + } + + /** + * @param {GPUComputePassDescriptor} descriptor + */ + beginComputePass(descriptor = {}) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; + descriptor = webidl.converters.GPUComputePassDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + + assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + + const { rid } = core.opSync( + "op_webgpu_command_encoder_begin_compute_pass", + { + commandEncoderRid, + ...descriptor, + }, + ); + + const computePassEncoder = createGPUComputePassEncoder( + descriptor.label ?? null, + this, + rid, + ); + ArrayPrototypePush(this[_encoders], new WeakRef(computePassEncoder)); + return computePassEncoder; + } + + /** + * @param {GPUBuffer} source + * @param {number} sourceOffset + * @param {GPUBuffer} destination + * @param {number} destinationOffset + * @param {number} size + */ + copyBufferToBuffer( + source, + sourceOffset, + destination, + destinationOffset, + size, + ) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'copyBufferToBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 5, { prefix }); + source = webidl.converters.GPUBuffer(source, { + prefix, + context: "Argument 1", + }); + sourceOffset = webidl.converters.GPUSize64(sourceOffset, { + prefix, + context: "Argument 2", + }); + destination = webidl.converters.GPUBuffer(destination, { + prefix, + context: "Argument 3", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 4", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 5", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceRid = assertResource(source, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, source, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + const destinationRid = assertResource(destination, { + prefix, + context: "Argument 3", + }); + assertDeviceMatch(device, destination, { + prefix, + resourceContext: "Argument 3", + selfContext: "this", + }); + + const { err } = core.opSync( + "op_webgpu_command_encoder_copy_buffer_to_buffer", + { + commandEncoderRid, + source: sourceRid, + sourceOffset, + destination: destinationRid, + destinationOffset, + size, + }, + ); + device.pushError(err); + } + + /** + * @param {GPUImageCopyBuffer} source + * @param {GPUImageCopyTexture} destination + * @param {GPUExtent3D} copySize + */ + copyBufferToTexture(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'copyBufferToTexture' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyBuffer(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceBufferRid = assertResource(source.buffer, { + prefix, + context: "source in Argument 1", + }); + assertDeviceMatch(device, source.buffer, { + prefix, + resourceContext: "source in Argument 1", + selfContext: "this", + }); + const destinationTextureRid = assertResource(destination.texture, { + prefix, + context: "texture in Argument 2", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + resourceContext: "texture in Argument 2", + selfContext: "this", + }); + + const { err } = core.opSync( + "op_webgpu_command_encoder_copy_buffer_to_texture", + { + commandEncoderRid, + source: { + ...source, + buffer: sourceBufferRid, + }, + destination: { + texture: destinationTextureRid, + mipLevel: destination.mipLevel, + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, + aspect: destination.aspect, + }, + copySize: normalizeGPUExtent3D(copySize), + }, + ); + device.pushError(err); + } + + /** + * @param {GPUImageCopyTexture} source + * @param {GPUImageCopyBuffer} destination + * @param {GPUExtent3D} copySize + */ + copyTextureToBuffer(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'copyTextureToBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyTexture(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyBuffer(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceTextureRid = assertResource(source.texture, { + prefix, + context: "texture in Argument 1", + }); + assertDeviceMatch(device, source.texture, { + prefix, + resourceContext: "texture in Argument 1", + selfContext: "this", + }); + const destinationBufferRid = assertResource(destination.buffer, { + prefix, + context: "buffer in Argument 2", + }); + assertDeviceMatch(device, destination.buffer, { + prefix, + resourceContext: "buffer in Argument 2", + selfContext: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_copy_texture_to_buffer", + { + commandEncoderRid, + source: { + texture: sourceTextureRid, + mipLevel: source.mipLevel, + origin: source.origin + ? normalizeGPUOrigin3D(source.origin) + : undefined, + aspect: source.aspect, + }, + destination: { + ...destination, + buffer: destinationBufferRid, + }, + copySize: normalizeGPUExtent3D(copySize), + }, + ); + device.pushError(err); + } + + /** + * @param {GPUImageCopyTexture} source + * @param {GPUImageCopyTexture} destination + * @param {GPUExtent3D} copySize + */ + copyTextureToTexture(source, destination, copySize) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'copyTextureToTexture' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + source = webidl.converters.GPUImageCopyTexture(source, { + prefix, + context: "Argument 1", + }); + destination = webidl.converters.GPUImageCopyTexture(destination, { + prefix, + context: "Argument 2", + }); + copySize = webidl.converters.GPUExtent3D(copySize, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const sourceTextureRid = assertResource(source.texture, { + prefix, + context: "texture in Argument 1", + }); + assertDeviceMatch(device, source.texture, { + prefix, + resourceContext: "texture in Argument 1", + selfContext: "this", + }); + const destinationTextureRid = assertResource(destination.texture, { + prefix, + context: "texture in Argument 2", + }); + assertDeviceMatch(device, destination.texture, { + prefix, + resourceContext: "texture in Argument 2", + selfContext: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_copy_texture_to_texture", + { + commandEncoderRid, + source: { + texture: sourceTextureRid, + mipLevel: source.mipLevel, + origin: source.origin + ? normalizeGPUOrigin3D(source.origin) + : undefined, + aspect: source.aspect, + }, + destination: { + texture: destinationTextureRid, + mipLevel: destination.mipLevel, + origin: destination.origin + ? normalizeGPUOrigin3D(destination.origin) + : undefined, + aspect: source.aspect, + }, + copySize: normalizeGPUExtent3D(copySize), + }, + ); + device.pushError(err); + } + + /** + * @param {GPUBuffer} destination + * @param {GPUSize64} destinationOffset + * @param {GPUSize64} size + */ + clearBuffer(destination, destinationOffset, size) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = "Failed to execute 'clearBuffer' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 3, { prefix }); + destination = webidl.converters.GPUBuffer(destination, { + prefix, + context: "Argument 1", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 2", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 3", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const destinationRid = assertResource(destination, { + prefix, + context: "Argument 1", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_clear_buffer", + { + commandEncoderRid, + destinationRid, + destinationOffset, + size, + }, + ); + device.pushError(err); + } + + /** + * @param {string} groupLabel + */ + pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_push_debug_group", + { + commandEncoderRid, + groupLabel, + }, + ); + device.pushError(err); + } + + popDebugGroup() { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = "Failed to execute 'popDebugGroup' on 'GPUCommandEncoder'"; + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_pop_debug_group", + { + commandEncoderRid, + }, + ); + device.pushError(err); + } + + /** + * @param {string} markerLabel + */ + insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_insert_debug_marker", + { + commandEncoderRid, + markerLabel, + }, + ); + device.pushError(err); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ + writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_write_timestamp", + { + commandEncoderRid, + querySet: querySetRid, + queryIndex, + }, + ); + device.pushError(err); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} firstQuery + * @param {number} queryCount + * @param {GPUBuffer} destination + * @param {number} destinationOffset + */ + resolveQuerySet( + querySet, + firstQuery, + queryCount, + destination, + destinationOffset, + ) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = + "Failed to execute 'resolveQuerySet' on 'GPUCommandEncoder'"; + webidl.requiredArguments(arguments.length, 5, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + firstQuery = webidl.converters.GPUSize32(firstQuery, { + prefix, + context: "Argument 2", + }); + queryCount = webidl.converters.GPUSize32(queryCount, { + prefix, + context: "Argument 3", + }); + destination = webidl.converters.GPUBuffer(destination, { + prefix, + context: "Argument 4", + }); + destinationOffset = webidl.converters.GPUSize64(destinationOffset, { + prefix, + context: "Argument 5", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + const destinationRid = assertResource(destination, { + prefix, + context: "Argument 3", + }); + assertDeviceMatch(device, destination, { + prefix, + resourceContext: "Argument 3", + selfContext: "this", + }); + const { err } = core.opSync( + "op_webgpu_command_encoder_resolve_query_set", + { + commandEncoderRid, + querySet: querySetRid, + firstQuery, + queryCount, + destination: destinationRid, + destinationOffset, + }, + ); + device.pushError(err); + } + + /** + * @param {GPUCommandBufferDescriptor} descriptor + * @returns {GPUCommandBuffer} + */ + finish(descriptor = {}) { + webidl.assertBranded(this, GPUCommandEncoderPrototype); + const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; + descriptor = webidl.converters.GPUCommandBufferDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const commandEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { rid, err } = core.opSync("op_webgpu_command_encoder_finish", { + commandEncoderRid, + ...descriptor, + }); + device.pushError(err); + /** @type {number | undefined} */ + this[_rid] = undefined; + + const commandBuffer = createGPUCommandBuffer( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(commandBuffer); + return commandBuffer; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUCommandEncoder", GPUCommandEncoder); + const GPUCommandEncoderPrototype = GPUCommandEncoder.prototype; + + const _encoder = Symbol("[[encoder]]"); + + /** + * @param {string | null} label + * @param {GPUCommandEncoder} encoder + * @param {number} rid + * @returns {GPURenderPassEncoder} + */ + function createGPURenderPassEncoder(label, encoder, rid) { + /** @type {GPURenderPassEncoder} */ + const passEncoder = webidl.createBranded(GPURenderPassEncoder); + passEncoder[_label] = label; + passEncoder[_encoder] = encoder; + passEncoder[_rid] = rid; + return passEncoder; + } + + class GPURenderPassEncoder { + /** @type {GPUCommandEncoder} */ + [_encoder]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {number} minDepth + * @param {number} maxDepth + */ + setViewport(x, y, width, height, minDepth, maxDepth) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setViewport' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 6, { prefix }); + x = webidl.converters.float(x, { prefix, context: "Argument 1" }); + y = webidl.converters.float(y, { prefix, context: "Argument 2" }); + width = webidl.converters.float(width, { prefix, context: "Argument 3" }); + height = webidl.converters.float(height, { + prefix, + context: "Argument 4", + }); + minDepth = webidl.converters.float(minDepth, { + prefix, + context: "Argument 5", + }); + maxDepth = webidl.converters.float(maxDepth, { + prefix, + context: "Argument 6", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_set_viewport", { + renderPassRid, + x, + y, + width, + height, + minDepth, + maxDepth, + }); + } + + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + setScissorRect(x, y, width, height) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setScissorRect' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 4, { prefix }); + x = webidl.converters.GPUIntegerCoordinate(x, { + prefix, + context: "Argument 1", + }); + y = webidl.converters.GPUIntegerCoordinate(y, { + prefix, + context: "Argument 2", + }); + width = webidl.converters.GPUIntegerCoordinate(width, { + prefix, + context: "Argument 3", + }); + height = webidl.converters.GPUIntegerCoordinate(height, { + prefix, + context: "Argument 4", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_set_scissor_rect", { + renderPassRid, + x, + y, + width, + height, + }); + } + + /** + * @param {GPUColor} color + */ + setBlendConstant(color) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setBlendConstant' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + color = webidl.converters.GPUColor(color, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_set_blend_constant", { + renderPassRid, + color: normalizeGPUColor(color), + }); + } + + /** + * @param {number} reference + */ + setStencilReference(reference) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setStencilReference' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + reference = webidl.converters.GPUStencilValue(reference, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_set_stencil_reference", { + renderPassRid, + reference, + }); + } + + beginOcclusionQuery(_queryIndex) { + throw new Error("Not yet implemented"); + } + + endOcclusionQuery() { + throw new Error("Not yet implemented"); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ + beginPipelineStatisticsQuery(querySet, queryIndex) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_begin_pipeline_statistics_query", { + renderPassRid, + querySet: querySetRid, + queryIndex, + }); + } + + endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'endPipelineStatisticsQuery' on 'GPURenderPassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_end_pipeline_statistics_query", { + renderPassRid, + }); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ + writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_write_timestamp", { + renderPassRid, + querySet: querySetRid, + queryIndex, + }); + } + + /** + * @param {GPURenderBundle[]} bundles + */ + executeBundles(bundles) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + bundles = webidl.converters["sequence"](bundles, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bundleRids = ArrayPrototypeMap(bundles, (bundle, i) => { + const context = `bundle ${i + 1}`; + const rid = assertResource(bundle, { prefix, context }); + assertDeviceMatch(device, bundle, { + prefix, + resourceContext: context, + selfContext: "this", + }); + return rid; + }); + core.opSync("op_webgpu_render_pass_execute_bundles", { + renderPassRid, + bundles: bundleRids, + }); + } + + endPass() { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = "Failed to execute 'endPass' on 'GPURenderPassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const commandEncoderRid = assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const { err } = core.opSync("op_webgpu_render_pass_end_pass", { + commandEncoderRid, + renderPassRid, + }); + device.pushError(err); + this[_rid] = undefined; + } + + // TODO(lucacasonato): has an overload + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setBindGroup' on 'GPURenderPassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); + if ( + !(ObjectPrototypeIsPrototypeOf( + Uint32ArrayPrototype, + dynamicOffsetsData, + )) + ) { + dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); + dynamicOffsetsDataStart = 0; + dynamicOffsetsDataLength = dynamicOffsetsData.length; + } + core.opSync("op_webgpu_render_pass_set_bind_group", { + renderPassRid, + index, + bindGroup: bindGroupRid, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }); + } + + /** + * @param {string} groupLabel + */ + pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_push_debug_group", { + renderPassRid, + groupLabel, + }); + } + + popDebugGroup() { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'popDebugGroup' on 'GPURenderPassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_pop_debug_group", { + renderPassRid, + }); + } + + /** + * @param {string} markerLabel + */ + insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_insert_debug_marker", { + renderPassRid, + markerLabel, + }); + } + + /** + * @param {GPURenderPipeline} pipeline + */ + setPipeline(pipeline) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setPipeline' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPURenderPipeline(pipeline, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_set_pipeline", { + renderPassRid, + pipeline: pipelineRid, + }); + } + + /** + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size + */ + setIndexBuffer(buffer, indexFormat, offset = 0, size) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setIndexBuffer' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 1", + }); + indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + if (size !== undefined) { + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); + } + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_set_index_buffer", { + renderPassRid, + buffer: bufferRid, + indexFormat, + offset, + size, + }); + } + + /** + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size + */ + setVertexBuffer(slot, buffer, offset = 0, size) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'setVertexBuffer' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + slot = webidl.converters.GPUSize32(slot, { + prefix, + context: "Argument 2", + }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + if (size !== undefined) { + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); + } + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_set_vertex_buffer", { + renderPassRid, + slot, + buffer: bufferRid, + offset, + size, + }); + } + + /** + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance + */ + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = "Failed to execute 'draw' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + vertexCount = webidl.converters.GPUSize32(vertexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstVertex = webidl.converters.GPUSize32(firstVertex, { + prefix, + context: "Argument 3", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 4", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_draw", { + renderPassRid, + vertexCount, + instanceCount, + firstVertex, + firstInstance, + }); + } + + /** + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance + */ + drawIndexed( + indexCount, + instanceCount = 1, + firstIndex = 0, + baseVertex = 0, + firstInstance = 0, + ) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'drawIndexed' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + indexCount = webidl.converters.GPUSize32(indexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstIndex = webidl.converters.GPUSize32(firstIndex, { + prefix, + context: "Argument 3", + }); + baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { + prefix, + context: "Argument 4", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 5", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_render_pass_draw_indexed", { + renderPassRid, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance, + }); + } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ + drawIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_draw_indirect", { + renderPassRid, + indirectBuffer: indirectBufferRid, + indirectOffset, + }); + } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ + drawIndexedIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderPassEncoderPrototype); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderPassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const renderPassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_pass_draw_indexed_indirect", { + renderPassRid, + indirectBuffer: indirectBufferRid, + indirectOffset, + }); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPURenderPassEncoder", GPURenderPassEncoder); + const GPURenderPassEncoderPrototype = GPURenderPassEncoder.prototype; + + /** + * @param {string | null} label + * @param {GPUCommandEncoder} encoder + * @param {number} rid + * @returns {GPUComputePassEncoder} + */ + function createGPUComputePassEncoder(label, encoder, rid) { + /** @type {GPUComputePassEncoder} */ + const computePassEncoder = webidl.createBranded(GPUComputePassEncoder); + computePassEncoder[_label] = label; + computePassEncoder[_encoder] = encoder; + computePassEncoder[_rid] = rid; + return computePassEncoder; + } + + class GPUComputePassEncoder { + /** @type {GPUCommandEncoder} */ + [_encoder]; + + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPUComputePipeline} pipeline + */ + setPipeline(pipeline) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'setPipeline' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPUComputePipeline(pipeline, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_compute_pass_set_pipeline", { + computePassRid, + pipeline: pipelineRid, + }); + } + + /** + * @param {number} x + * @param {number} y + * @param {number} z + */ + dispatch(x, y = 1, z = 1) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = "Failed to execute 'dispatch' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + x = webidl.converters.GPUSize32(x, { prefix, context: "Argument 1" }); + y = webidl.converters.GPUSize32(y, { prefix, context: "Argument 2" }); + z = webidl.converters.GPUSize32(z, { prefix, context: "Argument 3" }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_compute_pass_dispatch", { + computePassRid, + x, + y, + z, + }); + } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ + dispatchIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'dispatchIndirect' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_compute_pass_dispatch_indirect", { + computePassRid: computePassRid, + indirectBuffer: indirectBufferRid, + indirectOffset, + }); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ + beginPipelineStatisticsQuery(querySet, queryIndex) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'beginPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync( + "op_webgpu_compute_pass_begin_pipeline_statistics_query", + { + computePassRid, + querySet: querySetRid, + queryIndex, + }, + ); + } + + endPipelineStatisticsQuery() { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'endPipelineStatisticsQuery' on 'GPUComputePassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_compute_pass_end_pipeline_statistics_query", { + computePassRid, + }); + } + + /** + * @param {GPUQuerySet} querySet + * @param {number} queryIndex + */ + writeTimestamp(querySet, queryIndex) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'writeTimestamp' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + querySet = webidl.converters.GPUQuerySet(querySet, { + prefix, + context: "Argument 1", + }); + queryIndex = webidl.converters.GPUSize32(queryIndex, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const querySetRid = assertResource(querySet, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, querySet, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_compute_pass_write_timestamp", { + computePassRid, + querySet: querySetRid, + queryIndex, + }); + } + + endPass() { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = "Failed to execute 'endPass' on 'GPUComputePassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const commandEncoderRid = assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const { err } = core.opSync("op_webgpu_compute_pass_end_pass", { + commandEncoderRid, + computePassRid, + }); + device.pushError(err); + this[_rid] = undefined; + } + + // TODO(lucacasonato): has an overload + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; + const device = assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); + if ( + !(ObjectPrototypeIsPrototypeOf( + Uint32ArrayPrototype, + dynamicOffsetsData, + )) + ) { + dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); + dynamicOffsetsDataStart = 0; + dynamicOffsetsDataLength = dynamicOffsetsData.length; + } + core.opSync("op_webgpu_compute_pass_set_bind_group", { + computePassRid, + index, + bindGroup: bindGroupRid, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }); + } + + /** + * @param {string} groupLabel + */ + pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_compute_pass_push_debug_group", { + computePassRid, + groupLabel, + }); + } + + popDebugGroup() { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'popDebugGroup' on 'GPUComputePassEncoder'"; + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_compute_pass_pop_debug_group", { + computePassRid, + }); + } + + /** + * @param {string} markerLabel + */ + insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPUComputePassEncoderPrototype); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPUComputePassEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + assertResource(this[_encoder], { + prefix, + context: "encoder referenced by this", + }); + const computePassRid = assertResource(this, { prefix, context: "this" }); + core.opSync("op_webgpu_compute_pass_insert_debug_marker", { + computePassRid, + markerLabel, + }); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUComputePassEncoder", GPUComputePassEncoder); + const GPUComputePassEncoderPrototype = GPUComputePassEncoder.prototype; + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUCommandBuffer} + */ + function createGPUCommandBuffer(label, device, rid) { + /** @type {GPUCommandBuffer} */ + const commandBuffer = webidl.createBranded(GPUCommandBuffer); + commandBuffer[_label] = label; + commandBuffer[_device] = device; + commandBuffer[_rid] = rid; + return commandBuffer; + } + + class GPUCommandBuffer { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUCommandBuffer", GPUCommandBuffer); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPURenderBundleEncoder} + */ + function createGPURenderBundleEncoder(label, device, rid) { + /** @type {GPURenderBundleEncoder} */ + const bundleEncoder = webidl.createBranded(GPURenderBundleEncoder); + bundleEncoder[_label] = label; + bundleEncoder[_device] = device; + bundleEncoder[_rid] = rid; + return bundleEncoder; + } + + class GPURenderBundleEncoder { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + /** + * @param {GPURenderBundleDescriptor} descriptor + */ + finish(descriptor = {}) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'"; + descriptor = webidl.converters.GPURenderBundleDescriptor(descriptor, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const { rid, err } = core.opSync( + "op_webgpu_render_bundle_encoder_finish", + { + renderBundleEncoderRid, + ...descriptor, + }, + ); + device.pushError(err); + this[_rid] = undefined; + + const renderBundle = createGPURenderBundle( + descriptor.label ?? null, + device, + rid, + ); + device.trackResource(renderBundle); + return renderBundle; + } + + // TODO(lucacasonato): has an overload + setBindGroup( + index, + bindGroup, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + ) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'setBindGroup' on 'GPURenderBundleEncoder'"; + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bindGroupRid = assertResource(bindGroup, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, bindGroup, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); + if ( + !(ObjectPrototypeIsPrototypeOf( + Uint32ArrayPrototype, + dynamicOffsetsData, + )) + ) { + dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); + dynamicOffsetsDataStart = 0; + dynamicOffsetsDataLength = dynamicOffsetsData.length; + } + core.opSync("op_webgpu_render_bundle_encoder_set_bind_group", { + renderBundleEncoderRid, + index, + bindGroup: bindGroupRid, + dynamicOffsetsData, + dynamicOffsetsDataStart, + dynamicOffsetsDataLength, + }); + } + + /** + * @param {string} groupLabel + */ + pushDebugGroup(groupLabel) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'pushDebugGroup' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + groupLabel = webidl.converters.USVString(groupLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_push_debug_group", { + renderBundleEncoderRid, + groupLabel, + }); + } + + popDebugGroup() { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'popDebugGroup' on 'GPURenderBundleEncoder'"; + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_pop_debug_group", { + renderBundleEncoderRid, + }); + } + + /** + * @param {string} markerLabel + */ + insertDebugMarker(markerLabel) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'insertDebugMarker' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + markerLabel = webidl.converters.USVString(markerLabel, { + prefix, + context: "Argument 1", + }); + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_push_debug_group", { + renderBundleEncoderRid, + markerLabel, + }); + } + + /** + * @param {GPURenderPipeline} pipeline + */ + setPipeline(pipeline) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'setPipeline' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + pipeline = webidl.converters.GPURenderPipeline(pipeline, { + prefix, + context: "Argument 1", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const pipelineRid = assertResource(pipeline, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, pipeline, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_set_pipeline", { + renderBundleEncoderRid, + pipeline: pipelineRid, + }); + } + + /** + * @param {GPUBuffer} buffer + * @param {GPUIndexFormat} indexFormat + * @param {number} offset + * @param {number} size + */ + setIndexBuffer(buffer, indexFormat, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'setIndexBuffer' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 1", + }); + indexFormat = webidl.converters.GPUIndexFormat(indexFormat, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_set_index_buffer", { + renderBundleEncoderRid, + buffer: bufferRid, + indexFormat, + offset, + size, + }); + } + + /** + * @param {number} slot + * @param {GPUBuffer} buffer + * @param {number} offset + * @param {number} size + */ + setVertexBuffer(slot, buffer, offset = 0, size = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'setVertexBuffer' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + slot = webidl.converters.GPUSize32(slot, { + prefix, + context: "Argument 2", + }); + buffer = webidl.converters.GPUBuffer(buffer, { + prefix, + context: "Argument 2", + }); + offset = webidl.converters.GPUSize64(offset, { + prefix, + context: "Argument 3", + }); + size = webidl.converters.GPUSize64(size, { + prefix, + context: "Argument 4", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const bufferRid = assertResource(buffer, { + prefix, + context: "Argument 2", + }); + assertDeviceMatch(device, buffer, { + prefix, + resourceContext: "Argument 2", + selfContext: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_set_vertex_buffer", { + renderBundleEncoderRid, + slot, + buffer: bufferRid, + offset, + size, + }); + } + + /** + * @param {number} vertexCount + * @param {number} instanceCount + * @param {number} firstVertex + * @param {number} firstInstance + */ + draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = "Failed to execute 'draw' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + vertexCount = webidl.converters.GPUSize32(vertexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstVertex = webidl.converters.GPUSize32(firstVertex, { + prefix, + context: "Argument 3", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 4", + }); + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_draw", { + renderBundleEncoderRid, + vertexCount, + instanceCount, + firstVertex, + firstInstance, + }); + } + + /** + * @param {number} indexCount + * @param {number} instanceCount + * @param {number} firstIndex + * @param {number} baseVertex + * @param {number} firstInstance + */ + drawIndexed( + indexCount, + instanceCount = 1, + firstIndex = 0, + baseVertex = 0, + firstInstance = 0, + ) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'drawIndexed' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + indexCount = webidl.converters.GPUSize32(indexCount, { + prefix, + context: "Argument 1", + }); + instanceCount = webidl.converters.GPUSize32(instanceCount, { + prefix, + context: "Argument 2", + }); + firstIndex = webidl.converters.GPUSize32(firstIndex, { + prefix, + context: "Argument 3", + }); + baseVertex = webidl.converters.GPUSignedOffset32(baseVertex, { + prefix, + context: "Argument 4", + }); + firstInstance = webidl.converters.GPUSize32(firstInstance, { + prefix, + context: "Argument 5", + }); + assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_draw_indexed", { + renderBundleEncoderRid, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance, + }); + } + + /** + * @param {GPUBuffer} indirectBuffer + * @param {number} indirectOffset + */ + drawIndirect(indirectBuffer, indirectOffset) { + webidl.assertBranded(this, GPURenderBundleEncoder.prototype); + const prefix = + "Failed to execute 'drawIndirect' on 'GPURenderBundleEncoder'"; + webidl.requiredArguments(arguments.length, 2, { prefix }); + indirectBuffer = webidl.converters.GPUBuffer(indirectBuffer, { + prefix, + context: "Argument 1", + }); + indirectOffset = webidl.converters.GPUSize64(indirectOffset, { + prefix, + context: "Argument 2", + }); + const device = assertDevice(this, { prefix, context: "this" }); + const renderBundleEncoderRid = assertResource(this, { + prefix, + context: "this", + }); + const indirectBufferRid = assertResource(indirectBuffer, { + prefix, + context: "Argument 1", + }); + assertDeviceMatch(device, indirectBuffer, { + prefix, + resourceContext: "Argument 1", + selfContext: "this", + }); + core.opSync("op_webgpu_render_bundle_encoder_draw_indirect", { + renderBundleEncoderRid, + indirectBuffer: indirectBufferRid, + indirectOffset, + }); + } + + drawIndexedIndirect(_indirectBuffer, _indirectOffset) { + throw new Error("Not yet implemented"); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPURenderBundleEncoder", GPURenderBundleEncoder); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPURenderBundle} + */ + function createGPURenderBundle(label, device, rid) { + /** @type {GPURenderBundle} */ + const bundle = webidl.createBranded(GPURenderBundle); + bundle[_label] = label; + bundle[_device] = device; + bundle[_rid] = rid; + return bundle; + } + + class GPURenderBundle { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPURenderBundle", GPURenderBundle); + + const _descriptor = Symbol("[[descriptor]]"); + + /** + * @param {string | null} label + * @param {InnerGPUDevice} device + * @param {number} rid + * @returns {GPUQuerySet} + */ + function createGPUQuerySet(label, device, rid, descriptor) { + /** @type {GPUQuerySet} */ + const queue = webidl.createBranded(GPUQuerySet); + queue[_label] = label; + queue[_device] = device; + queue[_rid] = rid; + queue[_descriptor] = descriptor; + return queue; + } + + class GPUQuerySet { + /** @type {InnerGPUDevice} */ + [_device]; + /** @type {number | undefined} */ + [_rid]; + /** @type {GPUQuerySetDescriptor} */ + [_descriptor]; + + [_cleanup]() { + const rid = this[_rid]; + if (rid !== undefined) { + core.close(rid); + /** @type {number | undefined} */ + this[_rid] = undefined; + } + } + + constructor() { + webidl.illegalConstructor(); + } + + destroy() { + webidl.assertBranded(this, GPUQuerySetPrototype); + this[_cleanup](); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ + label: this.label, + }) + }`; + } + } + GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); + const GPUQuerySetPrototype = GPUQuerySet.prototype; + + window.__bootstrap.webgpu = { + gpu: webidl.createBranded(GPU), + GPU, + GPUAdapter, + GPUSupportedLimits, + GPUSupportedFeatures, + GPUDevice, + GPUQueue, + GPUBuffer, + GPUBufferUsage, + GPUMapMode, + GPUTextureUsage, + GPUTexture, + GPUTextureView, + GPUSampler, + GPUBindGroupLayout, + GPUPipelineLayout, + GPUBindGroup, + GPUShaderModule, + GPUShaderStage, + GPUComputePipeline, + GPURenderPipeline, + GPUColorWrite, + GPUCommandEncoder, + GPURenderPassEncoder, + GPUComputePassEncoder, + GPUCommandBuffer, + GPURenderBundleEncoder, + GPURenderBundle, + GPUQuerySet, + GPUOutOfMemoryError, + GPUValidationError, + }; +})(this); diff --git a/ext/webgpu/src/02_idl_types.js b/ext/webgpu/src/02_idl_types.js new file mode 100644 index 000000000..0dd8c00f9 --- /dev/null +++ b/ext/webgpu/src/02_idl_types.js @@ -0,0 +1,2002 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// + +"use strict"; + +((window) => { + const webidl = window.__bootstrap.webidl; + const { + GPU, + GPUAdapter, + GPUSupportedLimits, + GPUSupportedFeatures, + GPUDevice, + GPUQueue, + GPUBuffer, + GPUBufferUsage, + GPUMapMode, + GPUTextureUsage, + GPUTexture, + GPUTextureView, + GPUSampler, + GPUBindGroupLayout, + GPUPipelineLayout, + GPUBindGroup, + GPUShaderModule, + GPUShaderStage, + GPUComputePipeline, + GPURenderPipeline, + GPUColorWrite, + GPUCommandEncoder, + GPURenderPassEncoder, + GPUComputePassEncoder, + GPUCommandBuffer, + GPURenderBundleEncoder, + GPURenderBundle, + GPUQuerySet, + GPUOutOfMemoryError, + GPUValidationError, + } = window.__bootstrap.webgpu; + const { SymbolIterator, TypeError } = window.__bootstrap.primordials; + + // This needs to be initialized after all of the base classes are implemented, + // otherwise their converters might not be available yet. + // DICTIONARY: GPUObjectDescriptorBase + const dictMembersGPUObjectDescriptorBase = [ + { key: "label", converter: webidl.converters["USVString"] }, + ]; + webidl.converters["GPUObjectDescriptorBase"] = webidl + .createDictionaryConverter( + "GPUObjectDescriptorBase", + dictMembersGPUObjectDescriptorBase, + ); + + // INTERFACE: GPUSupportedLimits + webidl.converters.GPUSupportedLimits = webidl.createInterfaceConverter( + "GPUSupportedLimits", + GPUSupportedLimits.prototype, + ); + + // INTERFACE: GPUSupportedFeatures + webidl.converters.GPUSupportedFeatures = webidl.createInterfaceConverter( + "GPUSupportedFeatures", + GPUSupportedFeatures.prototype, + ); + + // ENUM: GPUPredefinedColorSpace + webidl.converters.GPUPredefinedColorSpace = webidl.createEnumConverter( + "GPUPredefinedColorSpace", + ["srgb"], + ); + + // INTERFACE: GPU + webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU.prototype); + + // ENUM: GPUPowerPreference + webidl.converters["GPUPowerPreference"] = webidl.createEnumConverter( + "GPUPowerPreference", + [ + "low-power", + "high-performance", + ], + ); + + // DICTIONARY: GPURequestAdapterOptions + const dictMembersGPURequestAdapterOptions = [ + { + key: "powerPreference", + converter: webidl.converters["GPUPowerPreference"], + }, + { + key: "forceFallbackAdapter", + converter: webidl.converters.boolean, + defaultValue: false, + }, + ]; + webidl.converters["GPURequestAdapterOptions"] = webidl + .createDictionaryConverter( + "GPURequestAdapterOptions", + dictMembersGPURequestAdapterOptions, + ); + + // INTERFACE: GPUAdapter + webidl.converters.GPUAdapter = webidl.createInterfaceConverter( + "GPUAdapter", + GPUAdapter.prototype, + ); + + // ENUM: GPUFeatureName + webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( + "GPUFeatureName", + [ + "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", + "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", + "texture-adapter-specific-format-features", + "shader-float64", + "vertex-attribute-64bit", + "conservative-rasterization", + "vertex-writable-storage", + "clear-commands", + "spirv-shader-passthrough", + "shader-primitive-index", + ], + ); + + // TYPEDEF: GPUSize32 + webidl.converters["GPUSize32"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUDeviceDescriptor + const dictMembersGPUDeviceDescriptor = [ + { + key: "nonGuaranteedFeatures", + converter: webidl.createSequenceConverter( + webidl.converters["GPUFeatureName"], + ), + get defaultValue() { + return []; + }, + }, + { + key: "nonGuaranteedLimits", + converter: webidl.createRecordConverter( + webidl.converters["DOMString"], + webidl.converters["GPUSize32"], + ), + get defaultValue() { + return {}; + }, + }, + ]; + webidl.converters["GPUDeviceDescriptor"] = webidl.createDictionaryConverter( + "GPUDeviceDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUDeviceDescriptor, + ); + + // INTERFACE: GPUDevice + webidl.converters.GPUDevice = webidl.createInterfaceConverter( + "GPUDevice", + GPUDevice.prototype, + ); + + // INTERFACE: GPUBuffer + webidl.converters.GPUBuffer = webidl.createInterfaceConverter( + "GPUBuffer", + GPUBuffer.prototype, + ); + + // TYPEDEF: GPUSize64 + webidl.converters["GPUSize64"] = (V, opts) => + webidl.converters["unsigned long long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUBufferUsageFlags + webidl.converters["GPUBufferUsageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUBufferDescriptor + const dictMembersGPUBufferDescriptor = [ + { key: "size", converter: webidl.converters["GPUSize64"], required: true }, + { + key: "usage", + converter: webidl.converters["GPUBufferUsageFlags"], + required: true, + }, + { + key: "mappedAtCreation", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + ]; + webidl.converters["GPUBufferDescriptor"] = webidl.createDictionaryConverter( + "GPUBufferDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBufferDescriptor, + ); + + // INTERFACE: GPUBufferUsage + webidl.converters.GPUBufferUsage = webidl.createInterfaceConverter( + "GPUBufferUsage", + GPUBufferUsage.prototype, + ); + + // TYPEDEF: GPUMapModeFlags + webidl.converters["GPUMapModeFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // INTERFACE: GPUMapMode + webidl.converters.GPUMapMode = webidl.createInterfaceConverter( + "GPUMapMode", + GPUMapMode.prototype, + ); + + // INTERFACE: GPUTexture + webidl.converters.GPUTexture = webidl.createInterfaceConverter( + "GPUTexture", + GPUTexture.prototype, + ); + + // TYPEDEF: GPUIntegerCoordinate + webidl.converters["GPUIntegerCoordinate"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + webidl.converters["sequence"] = webidl + .createSequenceConverter(webidl.converters["GPUIntegerCoordinate"]); + + // DICTIONARY: GPUExtent3DDict + const dictMembersGPUExtent3DDict = [ + { + key: "width", + converter: webidl.converters["GPUIntegerCoordinate"], + required: true, + }, + { + key: "height", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, + { + key: "depthOrArrayLayers", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, + ]; + webidl.converters["GPUExtent3DDict"] = webidl.createDictionaryConverter( + "GPUExtent3DDict", + dictMembersGPUExtent3DDict, + ); + + // TYPEDEF: GPUExtent3D + webidl.converters["GPUExtent3D"] = (V, opts) => { + // Union for (sequence or GPUExtent3DDict) + if (V === null || V === undefined) { + return webidl.converters["GPUExtent3DDict"](V, opts); + } + if (typeof V === "object") { + const method = V[SymbolIterator]; + if (method !== undefined) { + return webidl.converters["sequence"](V, opts); + } + return webidl.converters["GPUExtent3DDict"](V, opts); + } + throw webidl.makeException( + TypeError, + "can not be converted to sequence or GPUExtent3DDict.", + opts, + ); + }; + + // ENUM: GPUTextureDimension + webidl.converters["GPUTextureDimension"] = webidl.createEnumConverter( + "GPUTextureDimension", + [ + "1d", + "2d", + "3d", + ], + ); + + // ENUM: GPUTextureFormat + webidl.converters["GPUTextureFormat"] = webidl.createEnumConverter( + "GPUTextureFormat", + [ + "r8unorm", + "r8snorm", + "r8uint", + "r8sint", + "r16uint", + "r16sint", + "r16float", + "rg8unorm", + "rg8snorm", + "rg8uint", + "rg8sint", + "r32uint", + "r32sint", + "r32float", + "rg16uint", + "rg16sint", + "rg16float", + "rgba8unorm", + "rgba8unorm-srgb", + "rgba8snorm", + "rgba8uint", + "rgba8sint", + "bgra8unorm", + "bgra8unorm-srgb", + "rgb9e5ufloat", + "rgb10a2unorm", + "rg11b10ufloat", + "rg32uint", + "rg32sint", + "rg32float", + "rgba16uint", + "rgba16sint", + "rgba16float", + "rgba32uint", + "rgba32sint", + "rgba32float", + "stencil8", + "depth16unorm", + "depth24plus", + "depth24plus-stencil8", + "depth32float", + "bc1-rgba-unorm", + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm", + "bc3-rgba-unorm-srgb", + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm", + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb", + "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", + ], + ); + + // TYPEDEF: GPUTextureUsageFlags + webidl.converters["GPUTextureUsageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUTextureDescriptor + const dictMembersGPUTextureDescriptor = [ + { + key: "size", + converter: webidl.converters["GPUExtent3D"], + required: true, + }, + { + key: "mipLevelCount", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 1, + }, + { + key: "sampleCount", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, + }, + { + key: "dimension", + converter: webidl.converters["GPUTextureDimension"], + defaultValue: "2d", + }, + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { + key: "usage", + converter: webidl.converters["GPUTextureUsageFlags"], + required: true, + }, + ]; + webidl.converters["GPUTextureDescriptor"] = webidl.createDictionaryConverter( + "GPUTextureDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUTextureDescriptor, + ); + + // INTERFACE: GPUTextureUsage + webidl.converters.GPUTextureUsage = webidl.createInterfaceConverter( + "GPUTextureUsage", + GPUTextureUsage.prototype, + ); + + // INTERFACE: GPUTextureView + webidl.converters.GPUTextureView = webidl.createInterfaceConverter( + "GPUTextureView", + GPUTextureView.prototype, + ); + + // ENUM: GPUTextureViewDimension + webidl.converters["GPUTextureViewDimension"] = webidl.createEnumConverter( + "GPUTextureViewDimension", + [ + "1d", + "2d", + "2d-array", + "cube", + "cube-array", + "3d", + ], + ); + + // ENUM: GPUTextureAspect + webidl.converters["GPUTextureAspect"] = webidl.createEnumConverter( + "GPUTextureAspect", + [ + "all", + "stencil-only", + "depth-only", + ], + ); + + // DICTIONARY: GPUTextureViewDescriptor + const dictMembersGPUTextureViewDescriptor = [ + { key: "format", converter: webidl.converters["GPUTextureFormat"] }, + { + key: "dimension", + converter: webidl.converters["GPUTextureViewDimension"], + }, + { + key: "aspect", + converter: webidl.converters["GPUTextureAspect"], + defaultValue: "all", + }, + { + key: "baseMipLevel", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "mipLevelCount", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + { + key: "baseArrayLayer", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "arrayLayerCount", + converter: webidl.converters["GPUIntegerCoordinate"], + }, + ]; + webidl.converters["GPUTextureViewDescriptor"] = webidl + .createDictionaryConverter( + "GPUTextureViewDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUTextureViewDescriptor, + ); + + // INTERFACE: GPUSampler + webidl.converters.GPUSampler = webidl.createInterfaceConverter( + "GPUSampler", + GPUSampler.prototype, + ); + + // ENUM: GPUAddressMode + webidl.converters["GPUAddressMode"] = webidl.createEnumConverter( + "GPUAddressMode", + [ + "clamp-to-edge", + "repeat", + "mirror-repeat", + ], + ); + + // ENUM: GPUFilterMode + webidl.converters["GPUFilterMode"] = webidl.createEnumConverter( + "GPUFilterMode", + [ + "nearest", + "linear", + ], + ); + + // ENUM: GPUCompareFunction + webidl.converters["GPUCompareFunction"] = webidl.createEnumConverter( + "GPUCompareFunction", + [ + "never", + "less", + "equal", + "less-equal", + "greater", + "not-equal", + "greater-equal", + "always", + ], + ); + + // DICTIONARY: GPUSamplerDescriptor + const dictMembersGPUSamplerDescriptor = [ + { + key: "addressModeU", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "addressModeV", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "addressModeW", + converter: webidl.converters["GPUAddressMode"], + defaultValue: "clamp-to-edge", + }, + { + key: "magFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "minFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "mipmapFilter", + converter: webidl.converters["GPUFilterMode"], + defaultValue: "nearest", + }, + { + key: "lodMinClamp", + converter: webidl.converters["float"], + defaultValue: 0, + }, + { + key: "lodMaxClamp", + converter: webidl.converters["float"], + defaultValue: 0xffffffff, + }, + { key: "compare", converter: webidl.converters["GPUCompareFunction"] }, + { + key: "maxAnisotropy", + converter: (V, opts) => + webidl.converters["unsigned short"](V, { ...opts, clamp: true }), + defaultValue: 1, + }, + ]; + webidl.converters["GPUSamplerDescriptor"] = webidl.createDictionaryConverter( + "GPUSamplerDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUSamplerDescriptor, + ); + + // INTERFACE: GPUBindGroupLayout + webidl.converters.GPUBindGroupLayout = webidl.createInterfaceConverter( + "GPUBindGroupLayout", + GPUBindGroupLayout.prototype, + ); + + // TYPEDEF: GPUIndex32 + webidl.converters["GPUIndex32"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUShaderStageFlags + webidl.converters["GPUShaderStageFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // ENUM: GPUBufferBindingType + webidl.converters["GPUBufferBindingType"] = webidl.createEnumConverter( + "GPUBufferBindingType", + [ + "uniform", + "storage", + "read-only-storage", + ], + ); + + // DICTIONARY: GPUBufferBindingLayout + const dictMembersGPUBufferBindingLayout = [ + { + key: "type", + converter: webidl.converters["GPUBufferBindingType"], + defaultValue: "uniform", + }, + { + key: "hasDynamicOffset", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + { + key: "minBindingSize", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, + ]; + webidl.converters["GPUBufferBindingLayout"] = webidl + .createDictionaryConverter( + "GPUBufferBindingLayout", + dictMembersGPUBufferBindingLayout, + ); + + // ENUM: GPUSamplerBindingType + webidl.converters["GPUSamplerBindingType"] = webidl.createEnumConverter( + "GPUSamplerBindingType", + [ + "filtering", + "non-filtering", + "comparison", + ], + ); + + // DICTIONARY: GPUSamplerBindingLayout + const dictMembersGPUSamplerBindingLayout = [ + { + key: "type", + converter: webidl.converters["GPUSamplerBindingType"], + defaultValue: "filtering", + }, + ]; + webidl.converters["GPUSamplerBindingLayout"] = webidl + .createDictionaryConverter( + "GPUSamplerBindingLayout", + dictMembersGPUSamplerBindingLayout, + ); + + // ENUM: GPUTextureSampleType + webidl.converters["GPUTextureSampleType"] = webidl.createEnumConverter( + "GPUTextureSampleType", + [ + "float", + "unfilterable-float", + "depth", + "sint", + "uint", + ], + ); + + // DICTIONARY: GPUTextureBindingLayout + const dictMembersGPUTextureBindingLayout = [ + { + key: "sampleType", + converter: webidl.converters["GPUTextureSampleType"], + defaultValue: "float", + }, + { + key: "viewDimension", + converter: webidl.converters["GPUTextureViewDimension"], + defaultValue: "2d", + }, + { + key: "multisampled", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + ]; + webidl.converters["GPUTextureBindingLayout"] = webidl + .createDictionaryConverter( + "GPUTextureBindingLayout", + dictMembersGPUTextureBindingLayout, + ); + + // ENUM: GPUStorageTextureAccess + webidl.converters["GPUStorageTextureAccess"] = webidl.createEnumConverter( + "GPUStorageTextureAccess", + [ + "write-only", + ], + ); + + // DICTIONARY: GPUStorageTextureBindingLayout + const dictMembersGPUStorageTextureBindingLayout = [ + { + key: "access", + converter: webidl.converters["GPUStorageTextureAccess"], + defaultValue: "write-only", + }, + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { + key: "viewDimension", + converter: webidl.converters["GPUTextureViewDimension"], + defaultValue: "2d", + }, + ]; + webidl.converters["GPUStorageTextureBindingLayout"] = webidl + .createDictionaryConverter( + "GPUStorageTextureBindingLayout", + dictMembersGPUStorageTextureBindingLayout, + ); + + // DICTIONARY: GPUBindGroupLayoutEntry + const dictMembersGPUBindGroupLayoutEntry = [ + { + key: "binding", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + { + key: "visibility", + converter: webidl.converters["GPUShaderStageFlags"], + required: true, + }, + { key: "buffer", converter: webidl.converters["GPUBufferBindingLayout"] }, + { key: "sampler", converter: webidl.converters["GPUSamplerBindingLayout"] }, + { key: "texture", converter: webidl.converters["GPUTextureBindingLayout"] }, + { + key: "storageTexture", + converter: webidl.converters["GPUStorageTextureBindingLayout"], + }, + ]; + webidl.converters["GPUBindGroupLayoutEntry"] = webidl + .createDictionaryConverter( + "GPUBindGroupLayoutEntry", + dictMembersGPUBindGroupLayoutEntry, + ); + + // DICTIONARY: GPUBindGroupLayoutDescriptor + const dictMembersGPUBindGroupLayoutDescriptor = [ + { + key: "entries", + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupLayoutEntry"], + ), + required: true, + }, + ]; + webidl.converters["GPUBindGroupLayoutDescriptor"] = webidl + .createDictionaryConverter( + "GPUBindGroupLayoutDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBindGroupLayoutDescriptor, + ); + + // INTERFACE: GPUShaderStage + webidl.converters.GPUShaderStage = webidl.createInterfaceConverter( + "GPUShaderStage", + GPUShaderStage.prototype, + ); + + // INTERFACE: GPUBindGroup + webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( + "GPUBindGroup", + GPUBindGroup.prototype, + ); + + // DICTIONARY: GPUBufferBinding + const dictMembersGPUBufferBinding = [ + { + key: "buffer", + converter: webidl.converters["GPUBuffer"], + required: true, + }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, + { key: "size", converter: webidl.converters["GPUSize64"] }, + ]; + webidl.converters["GPUBufferBinding"] = webidl.createDictionaryConverter( + "GPUBufferBinding", + dictMembersGPUBufferBinding, + ); + + // TYPEDEF: GPUBindingResource + webidl.converters["GPUBindingResource"] = + webidl.converters.any /** put union here! **/; + + // DICTIONARY: GPUBindGroupEntry + const dictMembersGPUBindGroupEntry = [ + { + key: "binding", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + { + key: "resource", + converter: webidl.converters["GPUBindingResource"], + required: true, + }, + ]; + webidl.converters["GPUBindGroupEntry"] = webidl.createDictionaryConverter( + "GPUBindGroupEntry", + dictMembersGPUBindGroupEntry, + ); + + // DICTIONARY: GPUBindGroupDescriptor + const dictMembersGPUBindGroupDescriptor = [ + { + key: "layout", + converter: webidl.converters["GPUBindGroupLayout"], + required: true, + }, + { + key: "entries", + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupEntry"], + ), + required: true, + }, + ]; + webidl.converters["GPUBindGroupDescriptor"] = webidl + .createDictionaryConverter( + "GPUBindGroupDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUBindGroupDescriptor, + ); + + // INTERFACE: GPUPipelineLayout + webidl.converters.GPUPipelineLayout = webidl.createInterfaceConverter( + "GPUPipelineLayout", + GPUPipelineLayout.prototype, + ); + + // DICTIONARY: GPUPipelineLayoutDescriptor + const dictMembersGPUPipelineLayoutDescriptor = [ + { + key: "bindGroupLayouts", + converter: webidl.createSequenceConverter( + webidl.converters["GPUBindGroupLayout"], + ), + required: true, + }, + ]; + webidl.converters["GPUPipelineLayoutDescriptor"] = webidl + .createDictionaryConverter( + "GPUPipelineLayoutDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineLayoutDescriptor, + ); + + // INTERFACE: GPUShaderModule + webidl.converters.GPUShaderModule = webidl.createInterfaceConverter( + "GPUShaderModule", + GPUShaderModule.prototype, + ); + + // DICTIONARY: GPUShaderModuleDescriptor + const dictMembersGPUShaderModuleDescriptor = [ + { + key: "code", + converter: webidl.converters["DOMString"], + required: true, + }, + { key: "sourceMap", converter: webidl.converters["object"] }, + ]; + webidl.converters["GPUShaderModuleDescriptor"] = webidl + .createDictionaryConverter( + "GPUShaderModuleDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUShaderModuleDescriptor, + ); + + // // ENUM: GPUCompilationMessageType + // webidl.converters["GPUCompilationMessageType"] = webidl.createEnumConverter( + // "GPUCompilationMessageType", + // [ + // "error", + // "warning", + // "info", + // ], + // ); + + // // INTERFACE: GPUCompilationMessage + // webidl.converters.GPUCompilationMessage = webidl.createInterfaceConverter( + // "GPUCompilationMessage", + // GPUCompilationMessage.prototype, + // ); + + // // INTERFACE: GPUCompilationInfo + // webidl.converters.GPUCompilationInfo = webidl.createInterfaceConverter( + // "GPUCompilationInfo", + // GPUCompilationInfo.prototype, + // ); + + // DICTIONARY: GPUPipelineDescriptorBase + const dictMembersGPUPipelineDescriptorBase = [ + { key: "layout", converter: webidl.converters["GPUPipelineLayout"] }, + ]; + webidl.converters["GPUPipelineDescriptorBase"] = webidl + .createDictionaryConverter( + "GPUPipelineDescriptorBase", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineDescriptorBase, + ); + + // TYPEDEF: GPUPipelineConstantValue + webidl.converters.GPUPipelineConstantValue = webidl.converters.double; + + webidl.converters["record"] = webidl + .createRecordConverter( + webidl.converters.USVString, + webidl.converters.GPUPipelineConstantValue, + ); + + // DICTIONARY: GPUProgrammableStage + const dictMembersGPUProgrammableStage = [ + { + key: "module", + converter: webidl.converters["GPUShaderModule"], + required: true, + }, + { + key: "entryPoint", + converter: webidl.converters["USVString"], + required: true, + }, + { + key: "constants", + converter: + webidl.converters["record"], + }, + ]; + webidl.converters["GPUProgrammableStage"] = webidl.createDictionaryConverter( + "GPUProgrammableStage", + dictMembersGPUProgrammableStage, + ); + + // INTERFACE: GPUComputePipeline + webidl.converters.GPUComputePipeline = webidl.createInterfaceConverter( + "GPUComputePipeline", + GPUComputePipeline.prototype, + ); + + // DICTIONARY: GPUComputePipelineDescriptor + const dictMembersGPUComputePipelineDescriptor = [ + { + key: "compute", + converter: webidl.converters["GPUProgrammableStage"], + required: true, + }, + ]; + webidl.converters["GPUComputePipelineDescriptor"] = webidl + .createDictionaryConverter( + "GPUComputePipelineDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineDescriptorBase, + dictMembersGPUComputePipelineDescriptor, + ); + + // INTERFACE: GPURenderPipeline + webidl.converters.GPURenderPipeline = webidl.createInterfaceConverter( + "GPURenderPipeline", + GPURenderPipeline.prototype, + ); + + // ENUM: GPUVertexStepMode + webidl.converters["GPUVertexStepMode"] = webidl.createEnumConverter( + "GPUVertexStepMode", + [ + "vertex", + "instance", + ], + ); + + // ENUM: GPUVertexFormat + webidl.converters["GPUVertexFormat"] = webidl.createEnumConverter( + "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", + ], + ); + + // DICTIONARY: GPUVertexAttribute + const dictMembersGPUVertexAttribute = [ + { + key: "format", + converter: webidl.converters["GPUVertexFormat"], + required: true, + }, + { + key: "offset", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { + key: "shaderLocation", + converter: webidl.converters["GPUIndex32"], + required: true, + }, + ]; + webidl.converters["GPUVertexAttribute"] = webidl.createDictionaryConverter( + "GPUVertexAttribute", + dictMembersGPUVertexAttribute, + ); + + // DICTIONARY: GPUVertexBufferLayout + const dictMembersGPUVertexBufferLayout = [ + { + key: "arrayStride", + converter: webidl.converters["GPUSize64"], + required: true, + }, + { + key: "stepMode", + converter: webidl.converters["GPUVertexStepMode"], + defaultValue: "vertex", + }, + { + key: "attributes", + converter: webidl.createSequenceConverter( + webidl.converters["GPUVertexAttribute"], + ), + required: true, + }, + ]; + webidl.converters["GPUVertexBufferLayout"] = webidl.createDictionaryConverter( + "GPUVertexBufferLayout", + dictMembersGPUVertexBufferLayout, + ); + + // DICTIONARY: GPUVertexState + const dictMembersGPUVertexState = [ + { + key: "buffers", + converter: webidl.createSequenceConverter( + webidl.createNullableConverter( + webidl.converters["GPUVertexBufferLayout"], + ), + ), + get defaultValue() { + return []; + }, + }, + ]; + webidl.converters["GPUVertexState"] = webidl.createDictionaryConverter( + "GPUVertexState", + dictMembersGPUProgrammableStage, + dictMembersGPUVertexState, + ); + + // ENUM: GPUPrimitiveTopology + webidl.converters["GPUPrimitiveTopology"] = webidl.createEnumConverter( + "GPUPrimitiveTopology", + [ + "point-list", + "line-list", + "line-strip", + "triangle-list", + "triangle-strip", + ], + ); + + // ENUM: GPUIndexFormat + webidl.converters["GPUIndexFormat"] = webidl.createEnumConverter( + "GPUIndexFormat", + [ + "uint16", + "uint32", + ], + ); + + // ENUM: GPUFrontFace + webidl.converters["GPUFrontFace"] = webidl.createEnumConverter( + "GPUFrontFace", + [ + "ccw", + "cw", + ], + ); + + // ENUM: GPUCullMode + webidl.converters["GPUCullMode"] = webidl.createEnumConverter("GPUCullMode", [ + "none", + "front", + "back", + ]); + + // DICTIONARY: GPUPrimitiveState + const dictMembersGPUPrimitiveState = [ + { + key: "topology", + converter: webidl.converters["GPUPrimitiveTopology"], + defaultValue: "triangle-list", + }, + { key: "stripIndexFormat", converter: webidl.converters["GPUIndexFormat"] }, + { + key: "frontFace", + converter: webidl.converters["GPUFrontFace"], + defaultValue: "ccw", + }, + { + key: "cullMode", + converter: webidl.converters["GPUCullMode"], + defaultValue: "none", + }, + { + key: "unclippedDepth", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + ]; + webidl.converters["GPUPrimitiveState"] = webidl.createDictionaryConverter( + "GPUPrimitiveState", + dictMembersGPUPrimitiveState, + ); + + // ENUM: GPUStencilOperation + webidl.converters["GPUStencilOperation"] = webidl.createEnumConverter( + "GPUStencilOperation", + [ + "keep", + "zero", + "replace", + "invert", + "increment-clamp", + "decrement-clamp", + "increment-wrap", + "decrement-wrap", + ], + ); + + // DICTIONARY: GPUStencilFaceState + const dictMembersGPUStencilFaceState = [ + { + key: "compare", + converter: webidl.converters["GPUCompareFunction"], + defaultValue: "always", + }, + { + key: "failOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, + { + key: "depthFailOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, + { + key: "passOp", + converter: webidl.converters["GPUStencilOperation"], + defaultValue: "keep", + }, + ]; + webidl.converters["GPUStencilFaceState"] = webidl.createDictionaryConverter( + "GPUStencilFaceState", + dictMembersGPUStencilFaceState, + ); + + // TYPEDEF: GPUStencilValue + webidl.converters["GPUStencilValue"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUDepthBias + webidl.converters["GPUDepthBias"] = (V, opts) => + webidl.converters["long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUDepthStencilState + const dictMembersGPUDepthStencilState = [ + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { + key: "depthWriteEnabled", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + { + key: "depthCompare", + converter: webidl.converters["GPUCompareFunction"], + defaultValue: "always", + }, + { + key: "stencilFront", + converter: webidl.converters["GPUStencilFaceState"], + get defaultValue() { + return {}; + }, + }, + { + key: "stencilBack", + converter: webidl.converters["GPUStencilFaceState"], + get defaultValue() { + return {}; + }, + }, + { + key: "stencilReadMask", + converter: webidl.converters["GPUStencilValue"], + defaultValue: 0xFFFFFFFF, + }, + { + key: "stencilWriteMask", + converter: webidl.converters["GPUStencilValue"], + defaultValue: 0xFFFFFFFF, + }, + { + key: "depthBias", + converter: webidl.converters["GPUDepthBias"], + defaultValue: 0, + }, + { + key: "depthBiasSlopeScale", + converter: webidl.converters["float"], + defaultValue: 0, + }, + { + key: "depthBiasClamp", + converter: webidl.converters["float"], + defaultValue: 0, + }, + ]; + webidl.converters["GPUDepthStencilState"] = webidl.createDictionaryConverter( + "GPUDepthStencilState", + dictMembersGPUDepthStencilState, + ); + + // TYPEDEF: GPUSampleMask + webidl.converters["GPUSampleMask"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUMultisampleState + const dictMembersGPUMultisampleState = [ + { + key: "count", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, + }, + { + key: "mask", + converter: webidl.converters["GPUSampleMask"], + defaultValue: 0xFFFFFFFF, + }, + { + key: "alphaToCoverageEnabled", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + ]; + webidl.converters["GPUMultisampleState"] = webidl.createDictionaryConverter( + "GPUMultisampleState", + dictMembersGPUMultisampleState, + ); + + // ENUM: GPUBlendFactor + webidl.converters["GPUBlendFactor"] = webidl.createEnumConverter( + "GPUBlendFactor", + [ + "zero", + "one", + "src", + "one-minus-src", + "src-alpha", + "one-minus-src-alpha", + "dst", + "one-minus-dst", + "dst-alpha", + "one-minus-dst-alpha", + "src-alpha-saturated", + "constant", + "one-minus-constant", + ], + ); + + // ENUM: GPUBlendOperation + webidl.converters["GPUBlendOperation"] = webidl.createEnumConverter( + "GPUBlendOperation", + [ + "add", + "subtract", + "reverse-subtract", + "min", + "max", + ], + ); + + // DICTIONARY: GPUBlendComponent + const dictMembersGPUBlendComponent = [ + { + key: "srcFactor", + converter: webidl.converters["GPUBlendFactor"], + defaultValue: "one", + }, + { + key: "dstFactor", + converter: webidl.converters["GPUBlendFactor"], + defaultValue: "zero", + }, + { + key: "operation", + converter: webidl.converters["GPUBlendOperation"], + defaultValue: "add", + }, + ]; + webidl.converters["GPUBlendComponent"] = webidl.createDictionaryConverter( + "GPUBlendComponent", + dictMembersGPUBlendComponent, + ); + + // DICTIONARY: GPUBlendState + const dictMembersGPUBlendState = [ + { + key: "color", + converter: webidl.converters["GPUBlendComponent"], + required: true, + }, + { + key: "alpha", + converter: webidl.converters["GPUBlendComponent"], + required: true, + }, + ]; + webidl.converters["GPUBlendState"] = webidl.createDictionaryConverter( + "GPUBlendState", + dictMembersGPUBlendState, + ); + + // TYPEDEF: GPUColorWriteFlags + webidl.converters["GPUColorWriteFlags"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // DICTIONARY: GPUColorTargetState + const dictMembersGPUColorTargetState = [ + { + key: "format", + converter: webidl.converters["GPUTextureFormat"], + required: true, + }, + { key: "blend", converter: webidl.converters["GPUBlendState"] }, + { + key: "writeMask", + converter: webidl.converters["GPUColorWriteFlags"], + defaultValue: 0xF, + }, + ]; + webidl.converters["GPUColorTargetState"] = webidl.createDictionaryConverter( + "GPUColorTargetState", + dictMembersGPUColorTargetState, + ); + + // DICTIONARY: GPUFragmentState + const dictMembersGPUFragmentState = [ + { + key: "targets", + converter: webidl.createSequenceConverter( + webidl.converters["GPUColorTargetState"], + ), + required: true, + }, + ]; + webidl.converters["GPUFragmentState"] = webidl.createDictionaryConverter( + "GPUFragmentState", + dictMembersGPUProgrammableStage, + dictMembersGPUFragmentState, + ); + + // DICTIONARY: GPURenderPipelineDescriptor + const dictMembersGPURenderPipelineDescriptor = [ + { + key: "vertex", + converter: webidl.converters["GPUVertexState"], + required: true, + }, + { + key: "primitive", + converter: webidl.converters["GPUPrimitiveState"], + get defaultValue() { + return {}; + }, + }, + { + key: "depthStencil", + converter: webidl.converters["GPUDepthStencilState"], + }, + { + key: "multisample", + converter: webidl.converters["GPUMultisampleState"], + get defaultValue() { + return {}; + }, + }, + { key: "fragment", converter: webidl.converters["GPUFragmentState"] }, + ]; + webidl.converters["GPURenderPipelineDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderPipelineDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUPipelineDescriptorBase, + dictMembersGPURenderPipelineDescriptor, + ); + + // INTERFACE: GPUColorWrite + webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( + "GPUColorWrite", + GPUColorWrite.prototype, + ); + + // INTERFACE: GPUCommandBuffer + webidl.converters.GPUCommandBuffer = webidl.createInterfaceConverter( + "GPUCommandBuffer", + GPUCommandBuffer.prototype, + ); + webidl.converters["sequence"] = webidl + .createSequenceConverter(webidl.converters["GPUCommandBuffer"]); + + // DICTIONARY: GPUCommandBufferDescriptor + const dictMembersGPUCommandBufferDescriptor = []; + webidl.converters["GPUCommandBufferDescriptor"] = webidl + .createDictionaryConverter( + "GPUCommandBufferDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUCommandBufferDescriptor, + ); + + // INTERFACE: GPUCommandEncoder + webidl.converters.GPUCommandEncoder = webidl.createInterfaceConverter( + "GPUCommandEncoder", + GPUCommandEncoder.prototype, + ); + + // DICTIONARY: GPUCommandEncoderDescriptor + const dictMembersGPUCommandEncoderDescriptor = []; + webidl.converters["GPUCommandEncoderDescriptor"] = webidl + .createDictionaryConverter( + "GPUCommandEncoderDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUCommandEncoderDescriptor, + ); + + // DICTIONARY: GPUImageDataLayout + const dictMembersGPUImageDataLayout = [ + { + key: "offset", + converter: webidl.converters["GPUSize64"], + defaultValue: 0, + }, + { key: "bytesPerRow", converter: webidl.converters["GPUSize32"] }, + { key: "rowsPerImage", converter: webidl.converters["GPUSize32"] }, + ]; + webidl.converters["GPUImageDataLayout"] = webidl.createDictionaryConverter( + "GPUImageDataLayout", + dictMembersGPUImageDataLayout, + ); + + // DICTIONARY: GPUImageCopyBuffer + const dictMembersGPUImageCopyBuffer = [ + { + key: "buffer", + converter: webidl.converters["GPUBuffer"], + required: true, + }, + ]; + webidl.converters["GPUImageCopyBuffer"] = webidl.createDictionaryConverter( + "GPUImageCopyBuffer", + dictMembersGPUImageDataLayout, + dictMembersGPUImageCopyBuffer, + ); + + // DICTIONARY: GPUOrigin3DDict + const dictMembersGPUOrigin3DDict = [ + { + key: "x", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "z", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + ]; + webidl.converters["GPUOrigin3DDict"] = webidl.createDictionaryConverter( + "GPUOrigin3DDict", + dictMembersGPUOrigin3DDict, + ); + + // TYPEDEF: GPUOrigin3D + webidl.converters["GPUOrigin3D"] = (V, opts) => { + // Union for (sequence or GPUOrigin3DDict) + if (V === null || V === undefined) { + return webidl.converters["GPUOrigin3DDict"](V, opts); + } + if (typeof V === "object") { + const method = V[SymbolIterator]; + if (method !== undefined) { + return webidl.converters["sequence"](V, opts); + } + return webidl.converters["GPUOrigin3DDict"](V, opts); + } + throw webidl.makeException( + TypeError, + "can not be converted to sequence or GPUOrigin3DDict.", + opts, + ); + }; + + // DICTIONARY: GPUImageCopyTexture + const dictMembersGPUImageCopyTexture = [ + { + key: "texture", + converter: webidl.converters["GPUTexture"], + required: true, + }, + { + key: "mipLevel", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "origin", + converter: webidl.converters["GPUOrigin3D"], + get defaultValue() { + return {}; + }, + }, + { + key: "aspect", + converter: webidl.converters["GPUTextureAspect"], + defaultValue: "all", + }, + ]; + webidl.converters["GPUImageCopyTexture"] = webidl.createDictionaryConverter( + "GPUImageCopyTexture", + dictMembersGPUImageCopyTexture, + ); + + // DICTIONARY: GPUOrigin2DDict + const dictMembersGPUOrigin2DDict = [ + { + key: "x", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["GPUIntegerCoordinate"], + defaultValue: 0, + }, + ]; + webidl.converters["GPUOrigin2DDict"] = webidl.createDictionaryConverter( + "GPUOrigin2DDict", + dictMembersGPUOrigin2DDict, + ); + + // TYPEDEF: GPUOrigin2D + webidl.converters["GPUOrigin2D"] = (V, opts) => { + // Union for (sequence or GPUOrigin2DDict) + if (V === null || V === undefined) { + return webidl.converters["GPUOrigin2DDict"](V, opts); + } + if (typeof V === "object") { + const method = V[SymbolIterator]; + if (method !== undefined) { + return webidl.converters["sequence"](V, opts); + } + return webidl.converters["GPUOrigin2DDict"](V, opts); + } + throw webidl.makeException( + TypeError, + "can not be converted to sequence or GPUOrigin2DDict.", + opts, + ); + }; + + // INTERFACE: GPUComputePassEncoder + webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter( + "GPUComputePassEncoder", + GPUComputePassEncoder.prototype, + ); + + // DICTIONARY: GPUComputePassDescriptor + const dictMembersGPUComputePassDescriptor = []; + webidl.converters["GPUComputePassDescriptor"] = webidl + .createDictionaryConverter( + "GPUComputePassDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUComputePassDescriptor, + ); + + // INTERFACE: GPURenderPassEncoder + webidl.converters.GPURenderPassEncoder = webidl.createInterfaceConverter( + "GPURenderPassEncoder", + GPURenderPassEncoder.prototype, + ); + + // ENUM: GPULoadOp + webidl.converters["GPULoadOp"] = webidl.createEnumConverter("GPULoadOp", [ + "load", + ]); + + // DICTIONARY: GPUColorDict + const dictMembersGPUColorDict = [ + { key: "r", converter: webidl.converters["double"], required: true }, + { key: "g", converter: webidl.converters["double"], required: true }, + { key: "b", converter: webidl.converters["double"], required: true }, + { key: "a", converter: webidl.converters["double"], required: true }, + ]; + webidl.converters["GPUColorDict"] = webidl.createDictionaryConverter( + "GPUColorDict", + dictMembersGPUColorDict, + ); + + // TYPEDEF: GPUColor + webidl.converters["GPUColor"] = (V, opts) => { + // Union for (sequence or GPUColorDict) + if (V === null || V === undefined) { + return webidl.converters["GPUColorDict"](V, opts); + } + if (typeof V === "object") { + const method = V[SymbolIterator]; + if (method !== undefined) { + return webidl.converters["sequence"](V, opts); + } + return webidl.converters["GPUColorDict"](V, opts); + } + throw webidl.makeException( + TypeError, + "can not be converted to sequence or GPUColorDict.", + opts, + ); + }; + + // ENUM: GPUStoreOp + webidl.converters["GPUStoreOp"] = webidl.createEnumConverter("GPUStoreOp", [ + "store", + "discard", + ]); + + // DICTIONARY: GPURenderPassColorAttachment + const dictMembersGPURenderPassColorAttachment = [ + { + key: "view", + converter: webidl.converters["GPUTextureView"], + required: true, + }, + { key: "resolveTarget", converter: webidl.converters["GPUTextureView"] }, + { + key: "loadValue", + converter: webidl.converters.any, /** put union here! **/ + required: true, + }, + { + key: "storeOp", + converter: webidl.converters["GPUStoreOp"], + required: true, + }, + ]; + webidl.converters["GPURenderPassColorAttachment"] = webidl + .createDictionaryConverter( + "GPURenderPassColorAttachment", + dictMembersGPURenderPassColorAttachment, + ); + + // DICTIONARY: GPURenderPassDepthStencilAttachment + const dictMembersGPURenderPassDepthStencilAttachment = [ + { + key: "view", + converter: webidl.converters["GPUTextureView"], + required: true, + }, + { + key: "depthLoadValue", + converter: webidl.converters.any, /** put union here! **/ + required: true, + }, + { + key: "depthStoreOp", + converter: webidl.converters["GPUStoreOp"], + required: true, + }, + { + key: "depthReadOnly", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + { + key: "stencilLoadValue", + converter: webidl.converters.any, /** put union here! **/ + required: true, + }, + { + key: "stencilStoreOp", + converter: webidl.converters["GPUStoreOp"], + required: true, + }, + { + key: "stencilReadOnly", + converter: webidl.converters["boolean"], + defaultValue: false, + }, + ]; + webidl.converters["GPURenderPassDepthStencilAttachment"] = webidl + .createDictionaryConverter( + "GPURenderPassDepthStencilAttachment", + dictMembersGPURenderPassDepthStencilAttachment, + ); + + // INTERFACE: GPUQuerySet + webidl.converters.GPUQuerySet = webidl.createInterfaceConverter( + "GPUQuerySet", + GPUQuerySet.prototype, + ); + + // DICTIONARY: GPURenderPassDescriptor + const dictMembersGPURenderPassDescriptor = [ + { + key: "colorAttachments", + converter: webidl.createSequenceConverter( + webidl.converters["GPURenderPassColorAttachment"], + ), + required: true, + }, + { + key: "depthStencilAttachment", + converter: webidl.converters["GPURenderPassDepthStencilAttachment"], + }, + { key: "occlusionQuerySet", converter: webidl.converters["GPUQuerySet"] }, + ]; + webidl.converters["GPURenderPassDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderPassDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderPassDescriptor, + ); + + // INTERFACE: GPURenderBundle + webidl.converters.GPURenderBundle = webidl.createInterfaceConverter( + "GPURenderBundle", + GPURenderBundle.prototype, + ); + webidl.converters["sequence"] = webidl + .createSequenceConverter(webidl.converters["GPURenderBundle"]); + + // DICTIONARY: GPURenderBundleDescriptor + const dictMembersGPURenderBundleDescriptor = []; + webidl.converters["GPURenderBundleDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderBundleDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderBundleDescriptor, + ); + + // INTERFACE: GPURenderBundleEncoder + webidl.converters.GPURenderBundleEncoder = webidl.createInterfaceConverter( + "GPURenderBundleEncoder", + GPURenderBundleEncoder.prototype, + ); + + // DICTIONARY: GPURenderPassLayout + const dictMembersGPURenderPassLayout = [ + { + key: "colorFormats", + converter: webidl.createSequenceConverter( + webidl.converters["GPUTextureFormat"], + ), + required: true, + }, + { + key: "depthStencilFormat", + converter: webidl.converters["GPUTextureFormat"], + }, + { + key: "sampleCount", + converter: webidl.converters["GPUSize32"], + defaultValue: 1, + }, + ]; + webidl.converters["GPURenderPassLayout"] = webidl + .createDictionaryConverter( + "GPURenderPassLayout", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderPassLayout, + ); + + // DICTIONARY: GPURenderBundleEncoderDescriptor + const dictMembersGPURenderBundleEncoderDescriptor = [ + { + key: "depthReadOnly", + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: "stencilReadOnly", + converter: webidl.converters.boolean, + defaultValue: false, + }, + ]; + webidl.converters["GPURenderBundleEncoderDescriptor"] = webidl + .createDictionaryConverter( + "GPURenderBundleEncoderDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPURenderPassLayout, + dictMembersGPURenderBundleEncoderDescriptor, + ); + + // INTERFACE: GPUQueue + webidl.converters.GPUQueue = webidl.createInterfaceConverter( + "GPUQueue", + GPUQueue.prototype, + ); + + // ENUM: GPUQueryType + webidl.converters["GPUQueryType"] = webidl.createEnumConverter( + "GPUQueryType", + [ + "occlusion", + "pipeline-statistics", + "timestamp", + ], + ); + + // ENUM: GPUPipelineStatisticName + webidl.converters["GPUPipelineStatisticName"] = webidl.createEnumConverter( + "GPUPipelineStatisticName", + [ + "vertex-shader-invocations", + "clipper-invocations", + "clipper-primitives-out", + "fragment-shader-invocations", + "compute-shader-invocations", + ], + ); + + // DICTIONARY: GPUQuerySetDescriptor + const dictMembersGPUQuerySetDescriptor = [ + { + key: "type", + converter: webidl.converters["GPUQueryType"], + required: true, + }, + { key: "count", converter: webidl.converters["GPUSize32"], required: true }, + { + key: "pipelineStatistics", + converter: webidl.createSequenceConverter( + webidl.converters["GPUPipelineStatisticName"], + ), + get defaultValue() { + return []; + }, + }, + ]; + webidl.converters["GPUQuerySetDescriptor"] = webidl.createDictionaryConverter( + "GPUQuerySetDescriptor", + dictMembersGPUObjectDescriptorBase, + dictMembersGPUQuerySetDescriptor, + ); + + // ENUM: GPUDeviceLostReason + webidl.converters["GPUDeviceLostReason"] = webidl.createEnumConverter( + "GPUDeviceLostReason", + [ + "destroyed", + ], + ); + + // // INTERFACE: GPUDeviceLostInfo + // webidl.converters.GPUDeviceLostInfo = webidl.createInterfaceConverter( + // "GPUDeviceLostInfo", + // GPUDeviceLostInfo.prototype, + // ); + + // ENUM: GPUErrorFilter + webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter( + "GPUErrorFilter", + [ + "out-of-memory", + "validation", + ], + ); + + // INTERFACE: GPUOutOfMemoryError + webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( + "GPUOutOfMemoryError", + GPUOutOfMemoryError.prototype, + ); + + // INTERFACE: GPUValidationError + webidl.converters.GPUValidationError = webidl.createInterfaceConverter( + "GPUValidationError", + GPUValidationError.prototype, + ); + + // TYPEDEF: GPUError + webidl.converters["GPUError"] = webidl.converters.any /** put union here! **/; + + // // INTERFACE: GPUUncapturedErrorEvent + // webidl.converters.GPUUncapturedErrorEvent = webidl.createInterfaceConverter( + // "GPUUncapturedErrorEvent", + // GPUUncapturedErrorEvent.prototype, + // ); + + // DICTIONARY: GPUUncapturedErrorEventInit + const dictMembersGPUUncapturedErrorEventInit = [ + { key: "error", converter: webidl.converters["GPUError"], required: true }, + ]; + webidl.converters["GPUUncapturedErrorEventInit"] = webidl + .createDictionaryConverter( + "GPUUncapturedErrorEventInit", + // dictMembersEventInit, + dictMembersGPUUncapturedErrorEventInit, + ); + + // TYPEDEF: GPUBufferDynamicOffset + webidl.converters["GPUBufferDynamicOffset"] = (V, opts) => + webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUSignedOffset32 + webidl.converters["GPUSignedOffset32"] = (V, opts) => + webidl.converters["long"](V, { ...opts, enforceRange: true }); + + // TYPEDEF: GPUFlagsConstant + webidl.converters["GPUFlagsConstant"] = webidl.converters["unsigned long"]; +})(this); -- cgit v1.2.3