diff options
Diffstat (limited to 'extensions/webgpu')
-rw-r--r-- | extensions/webgpu/01_webgpu.js | 5140 | ||||
-rw-r--r-- | extensions/webgpu/02_idl_types.js | 1957 | ||||
-rw-r--r-- | extensions/webgpu/Cargo.toml | 21 | ||||
-rw-r--r-- | extensions/webgpu/README.md | 35 | ||||
-rw-r--r-- | extensions/webgpu/binding.rs | 335 | ||||
-rw-r--r-- | extensions/webgpu/buffer.rs | 241 | ||||
-rw-r--r-- | extensions/webgpu/bundle.rs | 454 | ||||
-rw-r--r-- | extensions/webgpu/command_encoder.rs | 692 | ||||
-rw-r--r-- | extensions/webgpu/compute_pass.rs | 356 | ||||
-rw-r--r-- | extensions/webgpu/error.rs | 294 | ||||
-rw-r--r-- | extensions/webgpu/lib.deno_webgpu.d.ts | 1131 | ||||
-rw-r--r-- | extensions/webgpu/lib.rs | 928 | ||||
-rw-r--r-- | extensions/webgpu/pipeline.rs | 686 | ||||
-rw-r--r-- | extensions/webgpu/queue.rs | 160 | ||||
-rw-r--r-- | extensions/webgpu/render_pass.rs | 688 | ||||
-rw-r--r-- | extensions/webgpu/sampler.rs | 120 | ||||
-rw-r--r-- | extensions/webgpu/shader.rs | 70 | ||||
-rw-r--r-- | extensions/webgpu/texture.rs | 244 | ||||
-rw-r--r-- | extensions/webgpu/webgpu.idl | 1057 |
19 files changed, 0 insertions, 14609 deletions
diff --git a/extensions/webgpu/01_webgpu.js b/extensions/webgpu/01_webgpu.js deleted file mode 100644 index 50d4d6eba..000000000 --- a/extensions/webgpu/01_webgpu.js +++ /dev/null @@ -1,5140 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -// @ts-check -/// <reference path="../../core/lib.deno_core.d.ts" /> -/// <reference path="../web/internal.d.ts" /> -/// <reference path="../web/lib.deno_web.d.ts" /> -/// <reference path="./lib.deno_webgpu.d.ts" /> - -"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, - Promise, - PromiseAll, - PromisePrototypeCatch, - PromisePrototypeThen, - PromiseReject, - PromiseResolve, - Set, - SetPrototypeEntries, - SetPrototypeForEach, - SetPrototypeHas, - SetPrototypeKeys, - SetPrototypeValues, - Symbol, - SymbolFor, - SymbolIterator, - TypeError, - Uint32Array, - 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"); - } - } - - 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); - } - } - - class GPU { - [webidl.brand] = webidl.brand; - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPURequestAdapterOptions} options - */ - async requestAdapter(options = {}) { - webidl.assertBranded(this, GPU); - 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 _name = Symbol("[[name]]"); - const _adapter = Symbol("[[adapter]]"); - const _cleanup = Symbol("[[cleanup]]"); - - /** - * @typedef InnerGPUAdapter - * @property {number} rid - * @property {GPUSupportedFeatures} features - * @property {GPUSupportedLimits} limits - * @property {boolean} isSoftware - */ - - /** - * @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, GPUAdapter); - return this[_name]; - } - /** @returns {GPUSupportedFeatures} */ - get features() { - webidl.assertBranded(this, GPUAdapter); - return this[_adapter].features; - } - /** @returns {GPUSupportedLimits} */ - get limits() { - webidl.assertBranded(this, GPUAdapter); - return this[_adapter].limits; - } - /** @returns {boolean} */ - get isSoftware() { - return this[_adapter].isSoftware; - } - - constructor() { - webidl.illegalConstructor(); - } - - /** - * @param {GPUDeviceDescriptor} descriptor - * @returns {Promise<GPUDevice>} - */ - async requestDevice(descriptor = {}) { - webidl.assertBranded(this, GPUAdapter); - 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 _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} maxComputeWorkgroupInvocations - * @property {number} maxComputePerDimensionDispatchSize - */ - - class GPUSupportedLimits { - /** @type {InnerAdapterLimits} */ - [_limits]; - constructor() { - webidl.illegalConstructor(); - } - - get maxTextureDimension1D() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxTextureDimension1D; - } - get maxTextureDimension2D() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxTextureDimension2D; - } - get maxTextureDimension3D() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxTextureDimension3D; - } - get maxTextureArrayLayers() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxTextureArrayLayers; - } - get maxBindGroups() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxBindGroups; - } - get maxDynamicUniformBuffersPerPipelineLayout() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxDynamicUniformBuffersPerPipelineLayout; - } - get maxDynamicStorageBuffersPerPipelineLayout() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxDynamicStorageBuffersPerPipelineLayout; - } - get maxSampledTexturesPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxSampledTexturesPerShaderStage; - } - get maxSamplersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxSamplersPerShaderStage; - } - get maxStorageBuffersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxStorageBuffersPerShaderStage; - } - get maxStorageTexturesPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxStorageTexturesPerShaderStage; - } - get maxUniformBuffersPerShaderStage() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxUniformBuffersPerShaderStage; - } - get maxUniformBufferBindingSize() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxUniformBufferBindingSize; - } - get maxStorageBufferBindingSize() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxStorageBufferBindingSize; - } - get minUniformBufferOffsetAlignment() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].minUniformBufferOffsetAlignment; - } - get minStorageBufferOffsetAlignment() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].minStorageBufferOffsetAlignment; - } - get maxVertexBuffers() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxVertexBuffers; - } - get maxVertexAttributes() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxVertexAttributes; - } - get maxVertexBufferArrayStride() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxVertexBufferArrayStride; - } - get maxInterStageShaderComponents() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxInterStageShaderComponents; - } - get maxComputeWorkgroupStorageSize() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxComputeWorkgroupStorageSize; - } - get maxComputeWorkgroupInvocations() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxComputeWorkgroupInvocations; - } - get maxComputePerDimensionDispatchSize() { - webidl.assertBranded(this, GPUSupportedLimits); - return this[_limits].maxComputePerDimensionDispatchSize; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect(this[_limits])}`; - } - } - - 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<string>} */ - [_features]; - - constructor() { - webidl.illegalConstructor(); - } - - /** @return {IterableIterator<[string, string]>} */ - entries() { - webidl.assertBranded(this, GPUSupportedFeatures); - return SetPrototypeEntries(this[_features]); - } - - /** @return {void} */ - forEach(callbackfn, thisArg) { - webidl.assertBranded(this, GPUSupportedFeatures); - SetPrototypeForEach(this[_features], callbackfn, thisArg); - } - - /** @return {boolean} */ - has(value) { - webidl.assertBranded(this, GPUSupportedFeatures); - return SetPrototypeHas(this[_features], value); - } - - /** @return {IterableIterator<string>} */ - keys() { - webidl.assertBranded(this, GPUSupportedFeatures); - return SetPrototypeKeys(this[_features]); - } - - /** @return {IterableIterator<string>} */ - values() { - webidl.assertBranded(this, GPUSupportedFeatures); - return SetPrototypeValues(this[_features]); - } - - /** @return {number} */ - get size() { - webidl.assertBranded(this, GPUSupportedFeatures); - return this[_features].size; - } - - [SymbolIterator]() { - webidl.assertBranded(this, GPUSupportedFeatures); - return this[_features][SymbolIterator](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect([...this.values()])}`; - } - } - - 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, GPUDeviceLostInfo); - return this[_reason]; - } - get message() { - webidl.assertBranded(this, GPUDeviceLostInfo); - return this[_message]; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ reason: this[_reason], message: this[_message] }) - }`; - } - } - - 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); - return this[_label]; - }, - /** - * @param {string | null} label - */ - set(label) { - webidl.assertBranded(this, type); - 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<void>[]} 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<any>[]} */ - resources; - /** @type {boolean} */ - isLost; - /** @type {Promise<GPUDeviceLostInfo>} */ - 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 (err instanceof GPUValidationError) 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 (err instanceof GPUOutOfMemoryError) 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, GPUDevice); - return this[_device].features; - } - get limits() { - webidl.assertBranded(this, GPUDevice); - return this[_device].limits; - } - get queue() { - webidl.assertBranded(this, GPUDevice); - return this[_queue]; - } - - constructor() { - webidl.illegalConstructor(); - super(); - } - - destroy() { - webidl.assertBranded(this, GPUDevice); - this[_cleanup](); - } - - /** - * @param {GPUBufferDescriptor} descriptor - * @returns {GPUBuffer} - */ - createBuffer(descriptor) { - webidl.assertBranded(this, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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 (resource instanceof GPUSampler) { - const rid = assertResource(resource, { - prefix, - context, - }); - assertDeviceMatch(device, resource, { - prefix, - resourceContext: context, - selfContext: "this", - }); - return { - binding: entry.binding, - kind: "GPUSampler", - resource: rid, - }; - } else if (resource instanceof GPUTextureView) { - 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, GPUDevice); - 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: (typeof descriptor.code === "string") - ? descriptor.code - : undefined, - sourceMap: descriptor.sourceMap, - }, - ...(descriptor.code instanceof Uint32Array - ? [new Uint8Array(descriptor.code.buffer)] - : []), - ); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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, GPUDevice); - 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<GPUError | null>} - */ - // deno-lint-ignore require-await - async popErrorScope() { - webidl.assertBranded(this, GPUDevice); - 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); - - /** - * @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); - const prefix = "Failed to execute 'submit' on 'GPUQueue'"; - webidl.requiredArguments(arguments.length, 1, { - prefix, - }); - commandBuffers = webidl.converters["sequence<GPUCommandBuffer>"]( - 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); - 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); - 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); - 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, - }, - 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); - 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); - 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); - 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, - }, ...(write ? [new Uint8Array(buffer)] : [])); - device.pushError(err); - if (err) return; - } - this[_mappingRange] = null; - this[_mappedRanges] = null; - } - - this[_state] = "unmapped"; - } - - destroy() { - webidl.assertBranded(this, GPUBuffer); - 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<GPUTextureView>[]} */ - [_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); - 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); - 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 SAMPLED() { - return 0x04; - } - static get STORAGE() { - 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); - - /** - * @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); - - /** - * @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, GPUComputePipeline); - 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); - - /** - * @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, GPURenderPipeline); - 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); - - 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<GPURenderPassEncoder | GPUComputePassEncoder>[]} */ - [_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, GPUCommandEncoder); - 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"; - depthStencilAttachment.depthLoadValue = - descriptor.depthStencilAttachment.depthLoadValue; - } - - if ( - typeof descriptor.depthStencilAttachment.stencilLoadValue === "string" - ) { - depthStencilAttachment.stencilLoadOp = - descriptor.depthStencilAttachment.stencilLoadValue; - depthStencilAttachment.stencilLoadValue = undefined; - } else { - depthStencilAttachment.stencilLoadOp = "clear"; - depthStencilAttachment.stencilLoadValue = - 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"; - attachment.loadValue = 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, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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, - }, - copySize: normalizeGPUExtent3D(copySize), - }, - ); - device.pushError(err); - } - - /** - * @param {GPUImageCopyTexture} source - * @param {GPUImageCopyBuffer} destination - * @param {GPUExtent3D} copySize - */ - copyTextureToBuffer(source, destination, copySize) { - webidl.assertBranded(this, GPUCommandEncoder); - 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, - }, - 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, GPUCommandEncoder); - 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, - }, - destination: { - texture: destinationTextureRid, - mipLevel: destination.mipLevel, - origin: destination.origin - ? normalizeGPUOrigin3D(destination.origin) - : undefined, - }, - copySize: normalizeGPUExtent3D(copySize), - }, - ); - device.pushError(err); - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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, GPUCommandEncoder); - 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.GPUQuerySet(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, GPUCommandEncoder); - 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 _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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - const prefix = - "Failed to execute 'executeBundles' on 'GPURenderPassEncoder'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - bundles = webidl.converters["sequence<GPURenderBundle>"](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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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 (dynamicOffsetsData instanceof Uint32Array) { - core.opSync( - "op_webgpu_render_pass_set_bind_group", - { - renderPassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }, - dynamicOffsetsData, - ); - } else { - dynamicOffsetsData ??= []; - core.opSync("op_webgpu_render_pass_set_bind_group", { - renderPassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart: 0, - dynamicOffsetsDataLength: dynamicOffsetsData.length, - }); - } - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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, GPURenderPassEncoder); - 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); - - /** - * @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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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 (dynamicOffsetsData instanceof Uint32Array) { - core.opSync( - "op_webgpu_compute_pass_set_bind_group", - { - computePassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }, - dynamicOffsetsData, - ); - } else { - dynamicOffsetsData ??= []; - core.opSync("op_webgpu_compute_pass_set_bind_group", { - computePassRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart: 0, - dynamicOffsetsDataLength: dynamicOffsetsData.length, - }); - } - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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, GPUComputePassEncoder); - 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); - - /** - * @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(); - } - - get executionTime() { - throw new Error("Not yet implemented"); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - // TODO(crowlKats): executionTime - }) - }`; - } - } - 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); - 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); - 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 (dynamicOffsetsData instanceof Uint32Array) { - core.opSync( - "op_webgpu_render_bundle_encoder_set_bind_group", - { - renderBundleEncoderRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsDataStart, - dynamicOffsetsDataLength, - }, - dynamicOffsetsData, - ); - } else { - dynamicOffsetsData ??= []; - core.opSync("op_webgpu_render_bundle_encoder_set_bind_group", { - renderBundleEncoderRid, - index, - bindGroup: bindGroupRid, - dynamicOffsetsData, - dynamicOffsetsDataStart: 0, - dynamicOffsetsDataLength: dynamicOffsetsData.length, - }); - } - } - - /** - * @param {string} groupLabel - */ - pushDebugGroup(groupLabel) { - webidl.assertBranded(this, GPURenderBundleEncoder); - 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); - 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); - 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); - 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); - 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); - 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); - 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); - 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); - 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, GPUQuerySet); - this[_cleanup](); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; - } - } - GPUObjectBaseMixin("GPUQuerySet", GPUQuerySet); - - 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/extensions/webgpu/02_idl_types.js b/extensions/webgpu/02_idl_types.js deleted file mode 100644 index 9102b8d7a..000000000 --- a/extensions/webgpu/02_idl_types.js +++ /dev/null @@ -1,1957 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -// @ts-check -/// <reference path="../web/internal.d.ts" /> - -"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, - Uint32Array, - } = window.__bootstrap.primordials; - - // This needs to be initalized after all of the base classes are implmented, - // 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, - ); - - // INTERFACE: GPUSupportedFeatures - webidl.converters.GPUSupportedFeatures = webidl.createInterfaceConverter( - "GPUSupportedFeatures", - GPUSupportedFeatures, - ); - - // ENUM: GPUPredefinedColorSpace - webidl.converters.GPUPredefinedColorSpace = webidl.createEnumConverter( - "GPUPredefinedColorSpace", - ["srgb"], - ); - - // INTERFACE: GPU - webidl.converters.GPU = webidl.createInterfaceConverter("GPU", GPU); - - // ENUM: GPUPowerPreference - webidl.converters["GPUPowerPreference"] = webidl.createEnumConverter( - "GPUPowerPreference", - [ - "low-power", - "high-performance", - ], - ); - - // DICTIONARY: GPURequestAdapterOptions - const dictMembersGPURequestAdapterOptions = [ - { - key: "powerPreference", - converter: webidl.converters["GPUPowerPreference"], - }, - { - key: "forceSoftware", - converter: webidl.converters.boolean, - defaultValue: false, - }, - ]; - webidl.converters["GPURequestAdapterOptions"] = webidl - .createDictionaryConverter( - "GPURequestAdapterOptions", - dictMembersGPURequestAdapterOptions, - ); - - // INTERFACE: GPUAdapter - webidl.converters.GPUAdapter = webidl.createInterfaceConverter( - "GPUAdapter", - GPUAdapter, - ); - - // ENUM: GPUFeatureName - webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( - "GPUFeatureName", - [ - "depth-clamping", - "depth24unorm-stencil8", - "depth32float-stencil8", - "pipeline-statistics-query", - "texture-compression-bc", - "timestamp-query", - // extended from spec - "mappable-primary-buffers", - "sampled-texture-binding-array", - "sampled-texture-array-dynamic-indexing", - "sampled-texture-array-non-uniform-indexing", - "unsized-binding-array", - "multi-draw-indirect", - "multi-draw-indirect-count", - "push-constants", - "address-mode-clamp-to-border", - "non-fill-polygon-mode", - "texture-compression-etc2", - "texture-compression-astc-ldr", - "texture-adapter-specific-format-features", - "shader-float64", - "vertex-attribute-64bit", - ], - ); - - // 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, - ); - - // INTERFACE: GPUBuffer - webidl.converters.GPUBuffer = webidl.createInterfaceConverter( - "GPUBuffer", - GPUBuffer, - ); - - // 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, - ); - - // TYPEDEF: GPUMapModeFlags - webidl.converters["GPUMapModeFlags"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - - // INTERFACE: GPUMapMode - webidl.converters.GPUMapMode = webidl.createInterfaceConverter( - "GPUMapMode", - GPUMapMode, - ); - - // INTERFACE: GPUTexture - webidl.converters.GPUTexture = webidl.createInterfaceConverter( - "GPUTexture", - GPUTexture, - ); - - // TYPEDEF: GPUIntegerCoordinate - webidl.converters["GPUIntegerCoordinate"] = (V, opts) => - webidl.converters["unsigned long"](V, { ...opts, enforceRange: true }); - webidl.converters["sequence<GPUIntegerCoordinate>"] = 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<GPUIntegerCoordinate> 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<GPUIntegerCoordinate>"](V, opts); - } - return webidl.converters["GPUExtent3DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence<GPUIntegerCoordinate> 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", - "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, - ); - - // INTERFACE: GPUTextureView - webidl.converters.GPUTextureView = webidl.createInterfaceConverter( - "GPUTextureView", - GPUTextureView, - ); - - // 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, - ); - - // 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, - ); - - // 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", - [ - "read-only", - "write-only", - ], - ); - - // DICTIONARY: GPUStorageTextureBindingLayout - const dictMembersGPUStorageTextureBindingLayout = [ - { - key: "access", - converter: webidl.converters["GPUStorageTextureAccess"], - required: true, - }, - { - 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, - ); - - // INTERFACE: GPUBindGroup - webidl.converters.GPUBindGroup = webidl.createInterfaceConverter( - "GPUBindGroup", - GPUBindGroup, - ); - - // 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, - ); - - // 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, - ); - - // DICTIONARY: GPUShaderModuleDescriptor - const dictMembersGPUShaderModuleDescriptor = [ - { - key: "code", - converter: (V, opts) => { - if (V instanceof Uint32Array) { - return webidl.converters["Uint32Array"](V, opts); - } - if (typeof V === "string") { - return webidl.converters["DOMString"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to Uint32Array or DOMString.", - opts, - ); - }, - 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, - // ); - - // // INTERFACE: GPUCompilationInfo - // webidl.converters.GPUCompilationInfo = webidl.createInterfaceConverter( - // "GPUCompilationInfo", - // GPUCompilationInfo, - // ); - - // 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<USVString, GPUPipelineConstantValue>"] = 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<USVString, GPUPipelineConstantValue>"], - }, - ]; - webidl.converters["GPUProgrammableStage"] = webidl.createDictionaryConverter( - "GPUProgrammableStage", - dictMembersGPUProgrammableStage, - ); - - // INTERFACE: GPUComputePipeline - webidl.converters.GPUComputePipeline = webidl.createInterfaceConverter( - "GPUComputePipeline", - GPUComputePipeline, - ); - - // DICTIONARY: GPUComputePipelineDescriptor - const dictMembersGPUComputePipelineDescriptor = [ - { - key: "compute", - converter: webidl.converters["GPUProgrammableStage"], - required: true, - }, - ]; - webidl.converters["GPUComputePipelineDescriptor"] = webidl - .createDictionaryConverter( - "GPUComputePipelineDescriptor", - dictMembersGPUPipelineDescriptorBase, - dictMembersGPUComputePipelineDescriptor, - ); - - // INTERFACE: GPURenderPipeline - webidl.converters.GPURenderPipeline = webidl.createInterfaceConverter( - "GPURenderPipeline", - GPURenderPipeline, - ); - - // ENUM: GPUInputStepMode - webidl.converters["GPUInputStepMode"] = webidl.createEnumConverter( - "GPUInputStepMode", - [ - "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["GPUInputStepMode"], - 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: "clampDepth", - 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", - dictMembersGPUPipelineDescriptorBase, - dictMembersGPURenderPipelineDescriptor, - ); - - // INTERFACE: GPUColorWrite - webidl.converters.GPUColorWrite = webidl.createInterfaceConverter( - "GPUColorWrite", - GPUColorWrite, - ); - - // INTERFACE: GPUCommandBuffer - webidl.converters.GPUCommandBuffer = webidl.createInterfaceConverter( - "GPUCommandBuffer", - GPUCommandBuffer, - ); - webidl.converters["sequence<GPUCommandBuffer>"] = 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, - ); - - // DICTIONARY: GPUCommandEncoderDescriptor - const dictMembersGPUCommandEncoderDescriptor = [ - { - key: "measureExecutionTime", - converter: webidl.converters["boolean"], - defaultValue: false, - }, - ]; - 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<GPUIntegerCoordinate> 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<GPUIntegerCoordinate>"](V, opts); - } - return webidl.converters["GPUOrigin3DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence<GPUIntegerCoordinate> 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<GPUIntegerCoordinate> 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<GPUIntegerCoordinate>"](V, opts); - } - return webidl.converters["GPUOrigin2DDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence<GPUIntegerCoordinate> or GPUOrigin2DDict.", - opts, - ); - }; - - // INTERFACE: GPUComputePassEncoder - webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter( - "GPUComputePassEncoder", - GPUComputePassEncoder, - ); - - // DICTIONARY: GPUComputePassDescriptor - const dictMembersGPUComputePassDescriptor = []; - webidl.converters["GPUComputePassDescriptor"] = webidl - .createDictionaryConverter( - "GPUComputePassDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPUComputePassDescriptor, - ); - - // INTERFACE: GPURenderPassEncoder - webidl.converters.GPURenderPassEncoder = webidl.createInterfaceConverter( - "GPURenderPassEncoder", - GPURenderPassEncoder, - ); - - // 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<double> 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<double>"](V, opts); - } - return webidl.converters["GPUColorDict"](V, opts); - } - throw webidl.makeException( - TypeError, - "can not be converted to sequence<double> 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, - ); - - // 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, - ); - webidl.converters["sequence<GPURenderBundle>"] = 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, - ); - - // DICTIONARY: GPURenderBundleEncoderDescriptor - const dictMembersGPURenderBundleEncoderDescriptor = [ - { - 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["GPURenderBundleEncoderDescriptor"] = webidl - .createDictionaryConverter( - "GPURenderBundleEncoderDescriptor", - dictMembersGPUObjectDescriptorBase, - dictMembersGPURenderBundleEncoderDescriptor, - ); - - // INTERFACE: GPUQueue - webidl.converters.GPUQueue = webidl.createInterfaceConverter( - "GPUQueue", - GPUQueue, - ); - - // 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, - // ); - - // ENUM: GPUErrorFilter - webidl.converters["GPUErrorFilter"] = webidl.createEnumConverter( - "GPUErrorFilter", - [ - "out-of-memory", - "validation", - ], - ); - - // INTERFACE: GPUOutOfMemoryError - webidl.converters.GPUOutOfMemoryError = webidl.createInterfaceConverter( - "GPUOutOfMemoryError", - GPUOutOfMemoryError, - ); - - // INTERFACE: GPUValidationError - webidl.converters.GPUValidationError = webidl.createInterfaceConverter( - "GPUValidationError", - GPUValidationError, - ); - - // TYPEDEF: GPUError - webidl.converters["GPUError"] = webidl.converters.any /** put union here! **/; - - // // INTERFACE: GPUUncapturedErrorEvent - // webidl.converters.GPUUncapturedErrorEvent = webidl.createInterfaceConverter( - // "GPUUncapturedErrorEvent", - // GPUUncapturedErrorEvent, - // ); - - // 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/extensions/webgpu/Cargo.toml b/extensions/webgpu/Cargo.toml deleted file mode 100644 index 1e1b36a41..000000000 --- a/extensions/webgpu/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -[package] -name = "deno_webgpu" -version = "0.15.0" -authors = ["the Deno authors"] -edition = "2018" -license = "MIT" -readme = "README.md" -repository = "https://github.com/denoland/deno" -description = "WebGPU implementation for Deno" - -[lib] -path = "lib.rs" - -[dependencies] -deno_core = { version = "0.96.0", path = "../../core" } -serde = { version = "1.0.126", features = ["derive"] } -tokio = { version = "1.8.1", features = ["full"] } -wgpu-core = { version = "0.9.0", features = ["trace"] } -wgpu-types = "0.9.0" diff --git a/extensions/webgpu/README.md b/extensions/webgpu/README.md deleted file mode 100644 index 2f915dcbb..000000000 --- a/extensions/webgpu/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# deno_webgpu - -This op crate implements the WebGPU API as defined in -https://gpuweb.github.io/gpuweb/ in Deno. The implementation targets the spec -draft as of February 22, 2021. The spec is still very much in flux. This op -crate tries to stay up to date with the spec, but is constrained by the features -implemented in our GPU backend library [wgpu](https://github.com/gfx-rs/wgpu). - -The spec is still very bare bones, and is still missing many details. As the -spec becomes more concrete, we will implement to follow the spec more closely. - -In addition, setting the `DENO_WEBGPU_TRACE` environmental variable will output -a -[wgpu trace](https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications#tracing-infrastructure) -to the specified directory. - -For testing this op crate will make use of the WebGPU conformance tests suite, -running through our WPT runner. This will be used to validate implementation -conformance. - -GitHub CI doesn't run with GPUs, so testing relies on software like DX WARP & -Vulkan lavapipe. Currently only using DX WARP works, so tests are only run on -Windows. - -## Links - -Specification: https://gpuweb.github.io/gpuweb/ - -Design documents: https://github.com/gpuweb/gpuweb/tree/main/design - -Conformance tests suite: https://github.com/gpuweb/cts - -WebGPU examples for Deno: https://github.com/crowlKats/webgpu-examples - -wgpu-users matrix channel: https://matrix.to/#/#wgpu-users:matrix.org diff --git a/extensions/webgpu/binding.rs b/extensions/webgpu/binding.rs deleted file mode 100644 index d20eb97d9..000000000 --- a/extensions/webgpu/binding.rs +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuBindGroupLayout( - pub(crate) wgpu_core::id::BindGroupLayoutId, -); -impl Resource for WebGpuBindGroupLayout { - fn name(&self) -> Cow<str> { - "webGPUBindGroupLayout".into() - } -} - -pub(crate) struct WebGpuBindGroup(pub(crate) wgpu_core::id::BindGroupId); -impl Resource for WebGpuBindGroup { - fn name(&self) -> Cow<str> { - "webGPUBindGroup".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBufferBindingLayout { - #[serde(rename = "type")] - kind: Option<String>, - has_dynamic_offset: Option<bool>, - min_binding_size: Option<u64>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuSamplerBindingLayout { - #[serde(rename = "type")] - kind: Option<String>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuTextureBindingLayout { - sample_type: Option<String>, - view_dimension: Option<String>, - multisampled: Option<bool>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuStorageTextureBindingLayout { - access: String, - format: String, - view_dimension: Option<String>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBindGroupLayoutEntry { - binding: u32, - visibility: u32, - buffer: Option<GpuBufferBindingLayout>, - sampler: Option<GpuSamplerBindingLayout>, - texture: Option<GpuTextureBindingLayout>, - storage_texture: Option<GpuStorageTextureBindingLayout>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBindGroupLayoutArgs { - device_rid: ResourceId, - label: Option<String>, - entries: Vec<GpuBindGroupLayoutEntry>, -} - -pub fn op_webgpu_create_bind_group_layout( - state: &mut OpState, - args: CreateBindGroupLayoutArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let mut entries = vec![]; - - for entry in &args.entries { - entries.push(wgpu_types::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgpu_types::ShaderStage::from_bits(entry.visibility).unwrap(), - ty: if let Some(buffer) = &entry.buffer { - wgpu_types::BindingType::Buffer { - ty: match &buffer.kind { - Some(kind) => match kind.as_str() { - "uniform" => wgpu_types::BufferBindingType::Uniform, - "storage" => { - wgpu_types::BufferBindingType::Storage { read_only: false } - } - "read-only-storage" => { - wgpu_types::BufferBindingType::Storage { read_only: true } - } - _ => unreachable!(), - }, - None => wgpu_types::BufferBindingType::Uniform, - }, - has_dynamic_offset: buffer.has_dynamic_offset.unwrap_or(false), - min_binding_size: if let Some(min_binding_size) = - buffer.min_binding_size - { - std::num::NonZeroU64::new(min_binding_size) - } else { - None - }, - } - } else if let Some(sampler) = &entry.sampler { - match &sampler.kind { - Some(kind) => match kind.as_str() { - "filtering" => wgpu_types::BindingType::Sampler { - filtering: true, - comparison: false, - }, - "non-filtering" => wgpu_types::BindingType::Sampler { - filtering: false, - comparison: false, - }, - "comparison" => wgpu_types::BindingType::Sampler { - filtering: true, - comparison: true, - }, - _ => unreachable!(), - }, - None => wgpu_types::BindingType::Sampler { - filtering: true, - comparison: false, - }, - } - } else if let Some(texture) = &entry.texture { - wgpu_types::BindingType::Texture { - sample_type: match &texture.sample_type { - Some(sample_type) => match sample_type.as_str() { - "float" => { - wgpu_types::TextureSampleType::Float { filterable: true } - } - "unfilterable-float" => { - wgpu_types::TextureSampleType::Float { filterable: false } - } - "depth" => wgpu_types::TextureSampleType::Depth, - "sint" => wgpu_types::TextureSampleType::Sint, - "uint" => wgpu_types::TextureSampleType::Uint, - _ => unreachable!(), - }, - None => wgpu_types::TextureSampleType::Float { filterable: true }, - }, - view_dimension: match &texture.view_dimension { - Some(view_dimension) => { - super::texture::serialize_dimension(view_dimension) - } - None => wgpu_types::TextureViewDimension::D2, - }, - multisampled: texture.multisampled.unwrap_or(false), - } - } else if let Some(storage_texture) = &entry.storage_texture { - wgpu_types::BindingType::StorageTexture { - access: match storage_texture.access.as_str() { - "read-only" => wgpu_types::StorageTextureAccess::ReadOnly, - "write-only" => wgpu_types::StorageTextureAccess::WriteOnly, - _ => unreachable!(), - }, - format: super::texture::serialize_texture_format( - &storage_texture.format, - )?, - view_dimension: match &storage_texture.view_dimension { - Some(view_dimension) => { - super::texture::serialize_dimension(view_dimension) - } - None => wgpu_types::TextureViewDimension::D2, - }, - } - } else { - unreachable!() - }, - count: None, // native-only - }); - } - - let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { - label: args.label.map(Cow::from), - entries: Cow::from(entries), - }; - - gfx_put!(device => instance.device_create_bind_group_layout( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBindGroupLayout) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreatePipelineLayoutArgs { - device_rid: ResourceId, - label: Option<String>, - bind_group_layouts: Vec<u32>, -} - -pub fn op_webgpu_create_pipeline_layout( - state: &mut OpState, - args: CreatePipelineLayoutArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let mut bind_group_layouts = vec![]; - - for rid in &args.bind_group_layouts { - let bind_group_layout = state - .resource_table - .get::<WebGpuBindGroupLayout>(*rid) - .ok_or_else(bad_resource_id)?; - bind_group_layouts.push(bind_group_layout.0); - } - - let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { - label: args.label.map(Cow::from), - bind_group_layouts: Cow::from(bind_group_layouts), - push_constant_ranges: Default::default(), - }; - - gfx_put!(device => instance.device_create_pipeline_layout( - device, - &descriptor, - std::marker::PhantomData - ) => state, super::pipeline::WebGpuPipelineLayout) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBindGroupEntry { - binding: u32, - kind: String, - resource: u32, - offset: Option<u64>, - size: Option<u64>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBindGroupArgs { - device_rid: ResourceId, - label: Option<String>, - layout: u32, - entries: Vec<GpuBindGroupEntry>, -} - -pub fn op_webgpu_create_bind_group( - state: &mut OpState, - args: CreateBindGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let mut entries = vec![]; - - for entry in &args.entries { - let e = wgpu_core::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.kind.as_str() { - "GPUSampler" => { - let sampler_resource = state - .resource_table - .get::<super::sampler::WebGpuSampler>(entry.resource) - .ok_or_else(bad_resource_id)?; - wgpu_core::binding_model::BindingResource::Sampler(sampler_resource.0) - } - "GPUTextureView" => { - let texture_view_resource = state - .resource_table - .get::<super::texture::WebGpuTextureView>(entry.resource) - .ok_or_else(bad_resource_id)?; - wgpu_core::binding_model::BindingResource::TextureView( - texture_view_resource.0, - ) - } - "GPUBufferBinding" => { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(entry.resource) - .ok_or_else(bad_resource_id)?; - wgpu_core::binding_model::BindingResource::Buffer( - wgpu_core::binding_model::BufferBinding { - buffer_id: buffer_resource.0, - offset: entry.offset.unwrap_or(0), - size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), - }, - ) - } - _ => unreachable!(), - }, - }; - entries.push(e); - } - - let bind_group_layout = state - .resource_table - .get::<WebGpuBindGroupLayout>(args.layout) - .ok_or_else(bad_resource_id)?; - - let descriptor = wgpu_core::binding_model::BindGroupDescriptor { - label: args.label.map(Cow::from), - layout: bind_group_layout.0, - entries: Cow::from(entries), - }; - - gfx_put!(device => instance.device_create_bind_group( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBindGroup) -} diff --git a/extensions/webgpu/buffer.rs b/extensions/webgpu/buffer.rs deleted file mode 100644 index 6980b6348..000000000 --- a/extensions/webgpu/buffer.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::type_error; -use deno_core::error::AnyError; -use deno_core::futures::channel::oneshot; -use deno_core::OpState; -use deno_core::Resource; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; -use std::time::Duration; - -use super::error::DomExceptionOperationError; -use super::error::WebGpuResult; - -pub(crate) struct WebGpuBuffer(pub(crate) wgpu_core::id::BufferId); -impl Resource for WebGpuBuffer { - fn name(&self) -> Cow<str> { - "webGPUBuffer".into() - } -} - -struct WebGpuBufferMapped(*mut u8, usize); -impl Resource for WebGpuBufferMapped { - fn name(&self) -> Cow<str> { - "webGPUBufferMapped".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBufferArgs { - device_rid: ResourceId, - label: Option<String>, - size: u64, - usage: u32, - mapped_at_creation: Option<bool>, -} - -pub fn op_webgpu_create_buffer( - state: &mut OpState, - args: CreateBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::BufferDescriptor { - label: args.label.map(Cow::from), - size: args.size, - usage: wgpu_types::BufferUsage::from_bits(args.usage) - .ok_or_else(|| type_error("usage is not valid"))?, - mapped_at_creation: args.mapped_at_creation.unwrap_or(false), - }; - - gfx_put!(device => instance.device_create_buffer( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBuffer) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferGetMapAsyncArgs { - buffer_rid: ResourceId, - device_rid: ResourceId, - mode: u32, - offset: u64, - size: u64, -} - -pub async fn op_webgpu_buffer_get_map_async( - state: Rc<RefCell<OpState>>, - args: BufferGetMapAsyncArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let (sender, receiver) = oneshot::channel::<Result<(), AnyError>>(); - - let device; - { - let state_ = state.borrow(); - let instance = state_.borrow::<super::Instance>(); - let buffer_resource = state_ - .resource_table - .get::<WebGpuBuffer>(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - let device_resource = state_ - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - device = device_resource.0; - - let boxed_sender = Box::new(sender); - let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; - - extern "C" fn buffer_map_future_wrapper( - status: wgpu_core::resource::BufferMapAsyncStatus, - user_data: *mut u8, - ) { - let sender_ptr = user_data as *mut oneshot::Sender<Result<(), AnyError>>; - let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; - boxed_sender - .send(match status { - wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()), - _ => unreachable!(), // TODO - }) - .unwrap(); - } - - // TODO(lucacasonato): error handling - let maybe_err = gfx_select!(buffer => instance.buffer_map_async( - buffer, - args.offset..(args.offset + args.size), - wgpu_core::resource::BufferMapOperation { - host: match args.mode { - 1 => wgpu_core::device::HostMap::Read, - 2 => wgpu_core::device::HostMap::Write, - _ => unreachable!(), - }, - callback: buffer_map_future_wrapper, - user_data: sender_ptr, - } - )) - .err(); - - if maybe_err.is_some() { - return Ok(WebGpuResult::maybe_err(maybe_err)); - } - } - - let done = Rc::new(RefCell::new(false)); - let done_ = done.clone(); - let device_poll_fut = async move { - while !*done.borrow() { - { - let state = state.borrow(); - let instance = state.borrow::<super::Instance>(); - gfx_select!(device => instance.device_poll(device, false)).unwrap() - } - tokio::time::sleep(Duration::from_millis(10)).await; - } - Ok::<(), AnyError>(()) - }; - - let receiver_fut = async move { - receiver.await??; - let mut done = done_.borrow_mut(); - *done = true; - Ok::<(), AnyError>(()) - }; - - tokio::try_join!(device_poll_fut, receiver_fut)?; - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferGetMappedRangeArgs { - buffer_rid: ResourceId, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_buffer_get_mapped_range( - state: &mut OpState, - args: BufferGetMappedRangeArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let mut zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let instance = state.borrow::<super::Instance>(); - let buffer_resource = state - .resource_table - .get::<WebGpuBuffer>(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - - let (slice_pointer, range_size) = - gfx_select!(buffer => instance.buffer_get_mapped_range( - buffer, - args.offset, - args.size - )) - .map_err(|e| DomExceptionOperationError::new(&e.to_string()))?; - - let slice = unsafe { - std::slice::from_raw_parts_mut(slice_pointer, range_size as usize) - }; - zero_copy.copy_from_slice(slice); - - let rid = state - .resource_table - .add(WebGpuBufferMapped(slice_pointer, range_size as usize)); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferUnmapArgs { - buffer_rid: ResourceId, - mapped_rid: ResourceId, -} - -pub fn op_webgpu_buffer_unmap( - state: &mut OpState, - args: BufferUnmapArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let mapped_resource = state - .resource_table - .take::<WebGpuBufferMapped>(args.mapped_rid) - .ok_or_else(bad_resource_id)?; - let instance = state.borrow::<super::Instance>(); - let buffer_resource = state - .resource_table - .get::<WebGpuBuffer>(args.buffer_rid) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - - let slice_pointer = mapped_resource.0; - let size = mapped_resource.1; - - if let Some(buffer) = zero_copy { - let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) }; - slice.copy_from_slice(&buffer); - } - - gfx_ok!(buffer => instance.buffer_unmap(buffer)) -} diff --git a/extensions/webgpu/bundle.rs b/extensions/webgpu/bundle.rs deleted file mode 100644 index b0c161b04..000000000 --- a/extensions/webgpu/bundle.rs +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; - -use super::error::WebGpuResult; -use super::texture::serialize_texture_format; - -struct WebGpuRenderBundleEncoder( - RefCell<wgpu_core::command::RenderBundleEncoder>, -); -impl Resource for WebGpuRenderBundleEncoder { - fn name(&self) -> Cow<str> { - "webGPURenderBundleEncoder".into() - } -} - -pub(crate) struct WebGpuRenderBundle(pub(crate) wgpu_core::id::RenderBundleId); -impl Resource for WebGpuRenderBundle { - fn name(&self) -> Cow<str> { - "webGPURenderBundle".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateRenderBundleEncoderArgs { - device_rid: ResourceId, - label: Option<String>, - color_formats: Vec<String>, - depth_stencil_format: Option<String>, - sample_count: Option<u32>, -} - -pub fn op_webgpu_create_render_bundle_encoder( - state: &mut OpState, - args: CreateRenderBundleEncoderArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let mut color_formats = vec![]; - - for format in &args.color_formats { - color_formats.push(serialize_texture_format(format)?); - } - - let descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { - label: args.label.map(Cow::from), - color_formats: Cow::from(color_formats), - depth_stencil_format: args - .depth_stencil_format - .map(|s| serialize_texture_format(&s)) - .transpose()?, - sample_count: args.sample_count.unwrap_or(1), - }; - - let res = - wgpu_core::command::RenderBundleEncoder::new(&descriptor, device, None); - let (render_bundle_encoder, maybe_err) = match res { - Ok(encoder) => (encoder, None), - Err(e) => ( - wgpu_core::command::RenderBundleEncoder::dummy(device), - Some(e), - ), - }; - - let rid = state - .resource_table - .add(WebGpuRenderBundleEncoder(RefCell::new( - render_bundle_encoder, - ))); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderFinishArgs { - render_bundle_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_render_bundle_encoder_finish( - state: &mut OpState, - args: RenderBundleEncoderFinishArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .take::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder = Rc::try_unwrap(render_bundle_encoder_resource) - .ok() - .expect("unwrapping render_bundle_encoder_resource should succeed") - .0 - .into_inner(); - let instance = state.borrow::<super::Instance>(); - - gfx_put!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( - render_bundle_encoder, - &wgpu_core::command::RenderBundleDescriptor { - label: args.label.map(Cow::from), - }, - std::marker::PhantomData - ) => state, WebGpuRenderBundle) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetBindGroupArgs { - render_bundle_encoder_rid: ResourceId, - index: u32, - bind_group: u32, - dynamic_offsets_data: Option<Vec<u32>>, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_render_bundle_encoder_set_bind_group( - state: &mut OpState, - args: RenderBundleEncoderSetBindGroupArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - // I know this might look like it can be easily deduplicated, but it can not - // be due to the lifetime of the args.dynamic_offsets_data slice. Because we - // need to use a raw pointer here the slice can be freed before the pointer - // is used in wgpu_render_pass_set_bind_group. See - // https://matrix.to/#/!XFRnMvAfptAHthwBCx:matrix.org/$HgrlhD-Me1DwsGb8UdMu2Hqubgks8s7ILwWRwigOUAg - match args.dynamic_offsets_data { - Some(data) => unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - data.as_slice().as_ptr(), - args.dynamic_offsets_data_length, - ); - }, - None => { - let zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let (prefix, data, suffix) = unsafe { zero_copy.align_to::<u32>() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - data[args.dynamic_offsets_data_start..].as_ptr(), - args.dynamic_offsets_data_length, - ); - } - } - }; - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderPushDebugGroupArgs { - render_bundle_encoder_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_render_bundle_encoder_push_debug_group( - state: &mut OpState, - args: RenderBundleEncoderPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.group_label).unwrap(); - wgpu_core::command::bundle_ffi::wgpu_render_bundle_push_debug_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - label.as_ptr(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderPopDebugGroupArgs { - render_bundle_encoder_rid: ResourceId, -} - -pub fn op_webgpu_render_bundle_encoder_pop_debug_group( - state: &mut OpState, - args: RenderBundleEncoderPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderInsertDebugMarkerArgs { - render_bundle_encoder_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( - state: &mut OpState, - args: RenderBundleEncoderInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgpu_core::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( - &mut render_bundle_encoder_resource.0.borrow_mut(), - label.as_ptr(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetPipelineArgs { - render_bundle_encoder_rid: ResourceId, - pipeline: u32, -} - -pub fn op_webgpu_render_bundle_encoder_set_pipeline( - state: &mut OpState, - args: RenderBundleEncoderSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pipeline_resource = state - .resource_table - .get::<super::pipeline::WebGpuRenderPipeline>(args.pipeline) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline( - &mut render_bundle_encoder_resource.0.borrow_mut(), - render_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetIndexBufferArgs { - render_bundle_encoder_rid: ResourceId, - buffer: u32, - index_format: String, - offset: u64, - size: u64, -} - -pub fn op_webgpu_render_bundle_encoder_set_index_buffer( - state: &mut OpState, - args: RenderBundleEncoderSetIndexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - render_bundle_encoder_resource - .0 - .borrow_mut() - .set_index_buffer( - buffer_resource.0, - super::pipeline::serialize_index_format(args.index_format), - args.offset, - std::num::NonZeroU64::new(args.size), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetVertexBufferArgs { - render_bundle_encoder_rid: ResourceId, - slot: u32, - buffer: u32, - offset: u64, - size: u64, -} - -pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( - state: &mut OpState, - args: RenderBundleEncoderSetVertexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.slot, - buffer_resource.0, - args.offset, - std::num::NonZeroU64::new(args.size), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawArgs { - render_bundle_encoder_rid: ResourceId, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, -} - -pub fn op_webgpu_render_bundle_encoder_draw( - state: &mut OpState, - args: RenderBundleEncoderDrawArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.vertex_count, - args.instance_count, - args.first_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawIndexedArgs { - render_bundle_encoder_rid: ResourceId, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, -} - -pub fn op_webgpu_render_bundle_encoder_draw_indexed( - state: &mut OpState, - args: RenderBundleEncoderDrawIndexedArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index_count, - args.instance_count, - args.first_index, - args.base_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawIndirectArgs { - render_bundle_encoder_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_bundle_encoder_draw_indirect( - state: &mut OpState, - args: RenderBundleEncoderDrawIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer) - .ok_or_else(bad_resource_id)?; - let render_bundle_encoder_resource = state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect( - &mut render_bundle_encoder_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} diff --git a/extensions/webgpu/command_encoder.rs b/extensions/webgpu/command_encoder.rs deleted file mode 100644 index 6821a2954..000000000 --- a/extensions/webgpu/command_encoder.rs +++ /dev/null @@ -1,692 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::num::NonZeroU32; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuCommandEncoder( - pub(crate) wgpu_core::id::CommandEncoderId, -); -impl Resource for WebGpuCommandEncoder { - fn name(&self) -> Cow<str> { - "webGPUCommandEncoder".into() - } -} - -pub(crate) struct WebGpuCommandBuffer( - pub(crate) wgpu_core::id::CommandBufferId, -); -impl Resource for WebGpuCommandBuffer { - fn name(&self) -> Cow<str> { - "webGPUCommandBuffer".into() - } -} - -fn serialize_store_op(store_op: String) -> wgpu_core::command::StoreOp { - match store_op.as_str() { - "store" => wgpu_core::command::StoreOp::Store, - "discard" => wgpu_core::command::StoreOp::Clear, - _ => unreachable!(), - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateCommandEncoderArgs { - device_rid: ResourceId, - label: Option<String>, - _measure_execution_time: Option<bool>, // not yet implemented -} - -pub fn op_webgpu_create_command_encoder( - state: &mut OpState, - args: CreateCommandEncoderArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let descriptor = wgpu_types::CommandEncoderDescriptor { - label: args.label.map(Cow::from), - }; - - gfx_put!(device => instance.device_create_command_encoder( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuCommandEncoder) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuRenderPassColorAttachment { - view: u32, - resolve_target: Option<u32>, - load_op: String, - load_value: Option<super::render_pass::GpuColor>, - store_op: Option<String>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuRenderPassDepthStencilAttachment { - view: u32, - depth_load_op: String, - depth_load_value: Option<f32>, - depth_store_op: String, - depth_read_only: Option<bool>, - stencil_load_op: String, - stencil_load_value: Option<u32>, - stencil_store_op: String, - stencil_read_only: Option<bool>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderBeginRenderPassArgs { - command_encoder_rid: ResourceId, - label: Option<String>, - color_attachments: Vec<GpuRenderPassColorAttachment>, - depth_stencil_attachment: Option<GpuRenderPassDepthStencilAttachment>, - _occlusion_query_set: Option<u32>, // not yet implemented -} - -pub fn op_webgpu_command_encoder_begin_render_pass( - state: &mut OpState, - args: CommandEncoderBeginRenderPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - - let mut color_attachments = vec![]; - - for color_attachment in args.color_attachments { - let texture_view_resource = state - .resource_table - .get::<super::texture::WebGpuTextureView>(color_attachment.view) - .ok_or_else(bad_resource_id)?; - - let attachment = wgpu_core::command::RenderPassColorAttachment { - view: texture_view_resource.0, - resolve_target: color_attachment - .resolve_target - .map(|rid| { - state - .resource_table - .get::<super::texture::WebGpuTextureView>(rid) - .ok_or_else(bad_resource_id) - }) - .transpose()? - .map(|texture| texture.0), - channel: match color_attachment.load_op.as_str() { - "load" => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: color_attachment - .store_op - .map_or(wgpu_core::command::StoreOp::Store, serialize_store_op), - clear_value: Default::default(), - read_only: false, - }, - "clear" => { - let color = color_attachment.load_value.unwrap(); - wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: color_attachment - .store_op - .map_or(wgpu_core::command::StoreOp::Store, serialize_store_op), - clear_value: wgpu_types::Color { - r: color.r, - g: color.g, - b: color.b, - a: color.a, - }, - read_only: false, - } - } - _ => unreachable!(), - }, - }; - - color_attachments.push(attachment) - } - - let mut depth_stencil_attachment = None; - - if let Some(attachment) = args.depth_stencil_attachment { - let texture_view_resource = state - .resource_table - .get::<super::texture::WebGpuTextureView>(attachment.view) - .ok_or_else(bad_resource_id)?; - - depth_stencil_attachment = - Some(wgpu_core::command::RenderPassDepthStencilAttachment { - view: texture_view_resource.0, - depth: match attachment.depth_load_op.as_str() { - "load" => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: serialize_store_op(attachment.depth_store_op), - clear_value: 0.0, - read_only: attachment.depth_read_only.unwrap_or(false), - }, - "clear" => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: serialize_store_op(attachment.depth_store_op), - clear_value: attachment.depth_load_value.unwrap(), - read_only: attachment.depth_read_only.unwrap_or(false), - }, - _ => unreachable!(), - }, - stencil: match attachment.stencil_load_op.as_str() { - "load" => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: 0, - read_only: attachment.stencil_read_only.unwrap_or(false), - }, - "clear" => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: serialize_store_op(attachment.stencil_store_op), - clear_value: attachment.stencil_load_value.unwrap(), - read_only: attachment.stencil_read_only.unwrap_or(false), - }, - _ => unreachable!(), - }, - }); - } - - let descriptor = wgpu_core::command::RenderPassDescriptor { - label: args.label.map(Cow::from), - color_attachments: Cow::from(color_attachments), - depth_stencil_attachment: depth_stencil_attachment.as_ref(), - }; - - let render_pass = wgpu_core::command::RenderPass::new( - command_encoder_resource.0, - &descriptor, - ); - - let rid = state - .resource_table - .add(super::render_pass::WebGpuRenderPass(RefCell::new( - render_pass, - ))); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderBeginComputePassArgs { - command_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_command_encoder_begin_compute_pass( - state: &mut OpState, - args: CommandEncoderBeginComputePassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - - let descriptor = wgpu_core::command::ComputePassDescriptor { - label: args.label.map(Cow::from), - }; - - let compute_pass = wgpu_core::command::ComputePass::new( - command_encoder_resource.0, - &descriptor, - ); - - let rid = state - .resource_table - .add(super::compute_pass::WebGpuComputePass(RefCell::new( - compute_pass, - ))); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyBufferToBufferArgs { - command_encoder_rid: ResourceId, - source: u32, - source_offset: u64, - destination: u32, - destination_offset: u64, - size: u64, -} - -pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( - state: &mut OpState, - args: CommandEncoderCopyBufferToBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let source_buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.source) - .ok_or_else(bad_resource_id)?; - let source_buffer = source_buffer_resource.0; - let destination_buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination) - .ok_or_else(bad_resource_id)?; - let destination_buffer = destination_buffer_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( - command_encoder, - source_buffer, - args.source_offset, - destination_buffer, - args.destination_offset, - args.size - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuImageCopyBuffer { - buffer: u32, - offset: Option<u64>, - bytes_per_row: Option<u32>, - rows_per_image: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuOrigin3D { - pub x: Option<u32>, - pub y: Option<u32>, - pub z: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuImageCopyTexture { - pub texture: u32, - pub mip_level: Option<u32>, - pub origin: Option<GpuOrigin3D>, - pub _aspect: Option<String>, // not yet implemented -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyBufferToTextureArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyBuffer, - destination: GpuImageCopyTexture, - copy_size: super::texture::GpuExtent3D, -} - -pub fn op_webgpu_command_encoder_copy_buffer_to_texture( - state: &mut OpState, - args: CommandEncoderCopyBufferToTextureArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let source_buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.source.buffer) - .ok_or_else(bad_resource_id)?; - let destination_texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture) - .ok_or_else(bad_resource_id)?; - - let source = wgpu_core::command::ImageCopyBuffer { - buffer: source_buffer_resource.0, - layout: wgpu_types::ImageDataLayout { - offset: args.source.offset.unwrap_or(0), - bytes_per_row: NonZeroU32::new(args.source.bytes_per_row.unwrap_or(0)), - rows_per_image: NonZeroU32::new(args.source.rows_per_image.unwrap_or(0)), - }, - }; - let destination = wgpu_core::command::ImageCopyTexture { - texture: destination_texture_resource.0, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgpu_types::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture( - command_encoder, - &source, - &destination, - &wgpu_types::Extent3d { - width: args.copy_size.width.unwrap_or(1), - height: args.copy_size.height.unwrap_or(1), - depth_or_array_layers: args.copy_size.depth_or_array_layers.unwrap_or(1), - } - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyTextureToBufferArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyBuffer, - copy_size: super::texture::GpuExtent3D, -} - -pub fn op_webgpu_command_encoder_copy_texture_to_buffer( - state: &mut OpState, - args: CommandEncoderCopyTextureToBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let source_texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.source.texture) - .ok_or_else(bad_resource_id)?; - let destination_buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination.buffer) - .ok_or_else(bad_resource_id)?; - - let source = wgpu_core::command::ImageCopyTexture { - texture: source_texture_resource.0, - mip_level: args.source.mip_level.unwrap_or(0), - origin: args.source.origin.map_or(Default::default(), |origin| { - wgpu_types::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - } - }), - }; - let destination = wgpu_core::command::ImageCopyBuffer { - buffer: destination_buffer_resource.0, - layout: wgpu_types::ImageDataLayout { - offset: args.destination.offset.unwrap_or(0), - bytes_per_row: NonZeroU32::new( - args.destination.bytes_per_row.unwrap_or(0), - ), - rows_per_image: NonZeroU32::new( - args.destination.rows_per_image.unwrap_or(0), - ), - }, - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_buffer( - command_encoder, - &source, - &destination, - &wgpu_types::Extent3d { - width: args.copy_size.width.unwrap_or(1), - height: args.copy_size.height.unwrap_or(1), - depth_or_array_layers: args.copy_size.depth_or_array_layers.unwrap_or(1), - } - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyTextureToTextureArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyTexture, - copy_size: super::texture::GpuExtent3D, -} - -pub fn op_webgpu_command_encoder_copy_texture_to_texture( - state: &mut OpState, - args: CommandEncoderCopyTextureToTextureArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let source_texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.source.texture) - .ok_or_else(bad_resource_id)?; - let destination_texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture) - .ok_or_else(bad_resource_id)?; - - let source = wgpu_core::command::ImageCopyTexture { - texture: source_texture_resource.0, - mip_level: args.source.mip_level.unwrap_or(0), - origin: args.source.origin.map_or(Default::default(), |origin| { - wgpu_types::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - } - }), - }; - let destination = wgpu_core::command::ImageCopyTexture { - texture: destination_texture_resource.0, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgpu_types::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture( - command_encoder, - &source, - &destination, - &wgpu_types::Extent3d { - width: args.copy_size.width.unwrap_or(1), - height: args.copy_size.height.unwrap_or(1), - depth_or_array_layers: args.copy_size.depth_or_array_layers.unwrap_or(1), - } - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderPushDebugGroupArgs { - command_encoder_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_command_encoder_push_debug_group( - state: &mut OpState, - args: CommandEncoderPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance - .command_encoder_push_debug_group(command_encoder, &args.group_label)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderPopDebugGroupArgs { - command_encoder_rid: ResourceId, -} - -pub fn op_webgpu_command_encoder_pop_debug_group( - state: &mut OpState, - args: CommandEncoderPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderInsertDebugMarkerArgs { - command_encoder_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_command_encoder_insert_debug_marker( - state: &mut OpState, - args: CommandEncoderInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_insert_debug_marker( - command_encoder, - &args.marker_label - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderWriteTimestampArgs { - command_encoder_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_command_encoder_write_timestamp( - state: &mut OpState, - args: CommandEncoderWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - - gfx_ok!(command_encoder => instance.command_encoder_write_timestamp( - command_encoder, - query_set_resource.0, - args.query_index - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderResolveQuerySetArgs { - command_encoder_rid: ResourceId, - query_set: u32, - first_query: u32, - query_count: u32, - destination: u32, - destination_offset: u64, -} - -pub fn op_webgpu_command_encoder_resolve_query_set( - state: &mut OpState, - args: CommandEncoderResolveQuerySetArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - let destination_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination) - .ok_or_else(bad_resource_id)?; - - gfx_ok!(command_encoder => instance.command_encoder_resolve_query_set( - command_encoder, - query_set_resource.0, - args.first_query, - args.query_count, - destination_resource.0, - args.destination_offset - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderFinishArgs { - command_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_command_encoder_finish( - state: &mut OpState, - args: CommandEncoderFinishArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .take::<WebGpuCommandEncoder>(args.command_encoder_rid) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let instance = state.borrow::<super::Instance>(); - - let descriptor = wgpu_types::CommandBufferDescriptor { - label: args.label.map(Cow::from), - }; - - gfx_put!(command_encoder => instance.command_encoder_finish( - command_encoder, - &descriptor - ) => state, WebGpuCommandBuffer) -} diff --git a/extensions/webgpu/compute_pass.rs b/extensions/webgpu/compute_pass.rs deleted file mode 100644 index 6971dbe5c..000000000 --- a/extensions/webgpu/compute_pass.rs +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuComputePass( - pub(crate) RefCell<wgpu_core::command::ComputePass>, -); -impl Resource for WebGpuComputePass { - fn name(&self) -> Cow<str> { - "webGPUComputePass".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassSetPipelineArgs { - compute_pass_rid: ResourceId, - pipeline: u32, -} - -pub fn op_webgpu_compute_pass_set_pipeline( - state: &mut OpState, - args: ComputePassSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pipeline_resource = state - .resource_table - .get::<super::pipeline::WebGpuComputePipeline>(args.pipeline) - .ok_or_else(bad_resource_id)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_set_pipeline( - &mut compute_pass_resource.0.borrow_mut(), - compute_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassDispatchArgs { - compute_pass_rid: ResourceId, - x: u32, - y: u32, - z: u32, -} - -pub fn op_webgpu_compute_pass_dispatch( - state: &mut OpState, - args: ComputePassDispatchArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch( - &mut compute_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.z, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassDispatchIndirectArgs { - compute_pass_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_compute_pass_dispatch_indirect( - state: &mut OpState, - args: ComputePassDispatchIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer) - .ok_or_else(bad_resource_id)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( - &mut compute_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassBeginPipelineStatisticsQueryArgs { - compute_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( - state: &mut OpState, - args: ComputePassBeginPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassEndPipelineStatisticsQueryArgs { - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( - state: &mut OpState, - args: ComputePassEndPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassWriteTimestampArgs { - compute_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_compute_pass_write_timestamp( - state: &mut OpState, - args: ComputePassWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_write_timestamp( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassEndPassArgs { - command_encoder_rid: ResourceId, - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_end_pass( - state: &mut OpState, - args: ComputePassEndPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<super::command_encoder::WebGpuCommandEncoder>( - args.command_encoder_rid, - ) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let compute_pass_resource = state - .resource_table - .take::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - let compute_pass = &compute_pass_resource.0.borrow(); - let instance = state.borrow::<super::Instance>(); - - gfx_ok!(command_encoder => instance.command_encoder_run_compute_pass( - command_encoder, - compute_pass - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassSetBindGroupArgs { - compute_pass_rid: ResourceId, - index: u32, - bind_group: u32, - dynamic_offsets_data: Option<Vec<u32>>, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_compute_pass_set_bind_group( - state: &mut OpState, - args: ComputePassSetBindGroupArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group) - .ok_or_else(bad_resource_id)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - wgpu_core::command::compute_ffi::wgpu_compute_pass_set_bind_group( - &mut compute_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - match args.dynamic_offsets_data { - Some(data) => data.as_ptr(), - None => { - let zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let (prefix, data, suffix) = zero_copy.align_to::<u32>(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data[args.dynamic_offsets_data_start..].as_ptr() - } - }, - args.dynamic_offsets_data_length, - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassPushDebugGroupArgs { - compute_pass_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_compute_pass_push_debug_group( - state: &mut OpState, - args: ComputePassPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.group_label).unwrap(); - wgpu_core::command::compute_ffi::wgpu_compute_pass_push_debug_group( - &mut compute_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassPopDebugGroupArgs { - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_pop_debug_group( - state: &mut OpState, - args: ComputePassPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_pop_debug_group( - &mut compute_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassInsertDebugMarkerArgs { - compute_pass_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_compute_pass_insert_debug_marker( - state: &mut OpState, - args: ComputePassInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgpu_core::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( - &mut compute_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} diff --git a/extensions/webgpu/error.rs b/extensions/webgpu/error.rs deleted file mode 100644 index 57e2e675f..000000000 --- a/extensions/webgpu/error.rs +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; -use deno_core::ResourceId; -use serde::Serialize; -use std::convert::From; -use std::fmt; -use wgpu_core::binding_model::CreateBindGroupError; -use wgpu_core::binding_model::CreateBindGroupLayoutError; -use wgpu_core::binding_model::CreatePipelineLayoutError; -use wgpu_core::binding_model::GetBindGroupLayoutError; -use wgpu_core::command::CommandAllocatorError; -use wgpu_core::command::CommandEncoderError; -use wgpu_core::command::ComputePassError; -use wgpu_core::command::CopyError; -use wgpu_core::command::CreateRenderBundleError; -use wgpu_core::command::QueryError; -use wgpu_core::command::RenderBundleError; -use wgpu_core::command::RenderPassError; -use wgpu_core::device::queue::QueueSubmitError; -use wgpu_core::device::queue::QueueWriteError; -use wgpu_core::device::DeviceError; -use wgpu_core::pipeline::CreateComputePipelineError; -use wgpu_core::pipeline::CreateRenderPipelineError; -use wgpu_core::pipeline::CreateShaderModuleError; -use wgpu_core::resource::BufferAccessError; -use wgpu_core::resource::CreateBufferError; -use wgpu_core::resource::CreateQuerySetError; -use wgpu_core::resource::CreateSamplerError; -use wgpu_core::resource::CreateTextureError; -use wgpu_core::resource::CreateTextureViewError; - -#[derive(Serialize)] -pub struct WebGpuResult { - pub rid: Option<ResourceId>, - pub err: Option<WebGpuError>, -} - -impl WebGpuResult { - pub fn rid(rid: ResourceId) -> Self { - Self { - rid: Some(rid), - err: None, - } - } - - pub fn rid_err<T: Into<WebGpuError>>( - rid: ResourceId, - err: Option<T>, - ) -> Self { - Self { - rid: Some(rid), - err: err.map(|e| e.into()), - } - } - - pub fn maybe_err<T: Into<WebGpuError>>(err: Option<T>) -> Self { - Self { - rid: None, - err: err.map(|e| e.into()), - } - } - - pub fn empty() -> Self { - Self { - rid: None, - err: None, - } - } -} - -#[derive(Serialize)] -#[serde(tag = "type", content = "value")] -#[serde(rename_all = "kebab-case")] -pub enum WebGpuError { - Lost, - OutOfMemory, - Validation(String), -} - -impl From<CreateBufferError> for WebGpuError { - fn from(err: CreateBufferError) -> Self { - match err { - CreateBufferError::Device(err) => err.into(), - CreateBufferError::AccessError(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<DeviceError> for WebGpuError { - fn from(err: DeviceError) -> Self { - match err { - DeviceError::Lost => WebGpuError::Lost, - DeviceError::OutOfMemory => WebGpuError::OutOfMemory, - DeviceError::Invalid => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<BufferAccessError> for WebGpuError { - fn from(err: BufferAccessError) -> Self { - match err { - BufferAccessError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateBindGroupLayoutError> for WebGpuError { - fn from(err: CreateBindGroupLayoutError) -> Self { - match err { - CreateBindGroupLayoutError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreatePipelineLayoutError> for WebGpuError { - fn from(err: CreatePipelineLayoutError) -> Self { - match err { - CreatePipelineLayoutError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateBindGroupError> for WebGpuError { - fn from(err: CreateBindGroupError) -> Self { - match err { - CreateBindGroupError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<RenderBundleError> for WebGpuError { - fn from(err: RenderBundleError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateRenderBundleError> for WebGpuError { - fn from(err: CreateRenderBundleError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CommandAllocatorError> for WebGpuError { - fn from(err: CommandAllocatorError) -> Self { - match err { - CommandAllocatorError::Device(err) => err.into(), - } - } -} - -impl From<CopyError> for WebGpuError { - fn from(err: CopyError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CommandEncoderError> for WebGpuError { - fn from(err: CommandEncoderError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<QueryError> for WebGpuError { - fn from(err: QueryError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<ComputePassError> for WebGpuError { - fn from(err: ComputePassError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateComputePipelineError> for WebGpuError { - fn from(err: CreateComputePipelineError) -> Self { - match err { - CreateComputePipelineError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<GetBindGroupLayoutError> for WebGpuError { - fn from(err: GetBindGroupLayoutError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateRenderPipelineError> for WebGpuError { - fn from(err: CreateRenderPipelineError) -> Self { - match err { - CreateRenderPipelineError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<RenderPassError> for WebGpuError { - fn from(err: RenderPassError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateSamplerError> for WebGpuError { - fn from(err: CreateSamplerError) -> Self { - match err { - CreateSamplerError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateShaderModuleError> for WebGpuError { - fn from(err: CreateShaderModuleError) -> Self { - match err { - CreateShaderModuleError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateTextureError> for WebGpuError { - fn from(err: CreateTextureError) -> Self { - match err { - CreateTextureError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateTextureViewError> for WebGpuError { - fn from(err: CreateTextureViewError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateQuerySetError> for WebGpuError { - fn from(err: CreateQuerySetError) -> Self { - match err { - CreateQuerySetError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<QueueSubmitError> for WebGpuError { - fn from(err: QueueSubmitError) -> Self { - match err { - QueueSubmitError::Queue(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<QueueWriteError> for WebGpuError { - fn from(err: QueueWriteError) -> Self { - match err { - QueueWriteError::Queue(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -#[derive(Debug)] -pub struct DomExceptionOperationError { - pub msg: String, -} - -impl DomExceptionOperationError { - pub fn new(msg: &str) -> Self { - DomExceptionOperationError { - msg: msg.to_string(), - } - } -} - -impl fmt::Display for DomExceptionOperationError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad(&self.msg) - } -} - -impl std::error::Error for DomExceptionOperationError {} - -pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { - e.downcast_ref::<DomExceptionOperationError>() - .map(|_| "DOMExceptionOperationError") -} diff --git a/extensions/webgpu/lib.deno_webgpu.d.ts b/extensions/webgpu/lib.deno_webgpu.d.ts deleted file mode 100644 index 9f7a31cb7..000000000 --- a/extensions/webgpu/lib.deno_webgpu.d.ts +++ /dev/null @@ -1,1131 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -// deno-lint-ignore-file no-explicit-any no-empty-interface - -/// <reference no-default-lib="true" /> -/// <reference lib="esnext" /> - -// 8cc98b6f10b7f354473a08c3773bb1de839845b9 - -interface GPUObjectBase { - label: string | null; -} - -declare interface GPUObjectDescriptorBase { - label?: string; -} - -declare class GPUSupportedLimits { - maxTextureDimension1D?: number; - maxTextureDimension2D?: number; - maxTextureDimension3D?: number; - maxTextureArrayLayers?: number; - maxBindGroups?: number; - maxDynamicUniformBuffersPerPipelineLayout?: number; - maxDynamicStorageBuffersPerPipelineLayout?: number; - maxSampledTexturesPerShaderStage?: number; - maxSamplersPerShaderStage?: number; - maxStorageBuffersPerShaderStage?: number; - maxStorageTexturesPerShaderStage?: number; - maxUniformBuffersPerShaderStage?: number; - maxUniformBufferBindingSize?: number; - maxStorageBufferBindingSize?: number; - minUniformBufferOffsetAlignment?: number; - minStorageBufferOffsetAlignment?: number; - maxVertexBuffers?: number; - maxVertexAttributes?: number; - maxVertexBufferArrayStride?: number; - maxInterStageShaderComponents?: number; - maxComputeWorkgroupStorageSize?: number; - maxComputeWorkgroupInvocations?: number; - maxComputePerDimensionDispatchSize?: number; -} - -declare class GPUSupportedFeatures { - forEach( - callbackfn: ( - value: GPUFeatureName, - value2: GPUFeatureName, - set: Set<GPUFeatureName>, - ) => void, - thisArg?: any, - ): void; - has(value: GPUFeatureName): boolean; - size: number; - [ - Symbol - .iterator - ](): IterableIterator<GPUFeatureName>; - entries(): IterableIterator<[GPUFeatureName, GPUFeatureName]>; - keys(): IterableIterator<GPUFeatureName>; - values(): IterableIterator<GPUFeatureName>; -} - -declare class GPU { - requestAdapter( - options?: GPURequestAdapterOptions, - ): Promise<GPUAdapter | null>; -} - -declare interface GPURequestAdapterOptions { - powerPreference?: GPUPowerPreference; - forceSoftware?: boolean; -} - -declare type GPUPowerPreference = "low-power" | "high-performance"; - -declare class GPUAdapter { - readonly name: string; - readonly features: GPUSupportedFeatures; - readonly limits: GPUSupportedLimits; - readonly isSoftware: boolean; - - requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>; -} - -declare interface GPUDeviceDescriptor extends GPUObjectDescriptorBase { - requiredFeatures?: GPUFeatureName[]; - requiredLimits?: Record<string, number>; -} - -declare type GPUFeatureName = - | "depth-clamping" - | "depth24unorm-stencil8" - | "depth32float-stencil8" - | "pipeline-statistics-query" - | "texture-compression-bc" - | "timestamp-query" - // extended from spec - | "mappable-primary-buffers" - | "sampled-texture-binding-array" - | "sampled-texture-array-dynamic-indexing" - | "sampled-texture-array-non-uniform-indexing" - | "unsized-binding-array" - | "multi-draw-indirect" - | "multi-draw-indirect-count" - | "push-constants" - | "address-mode-clamp-to-border" - | "non-fill-polygon-mode" - | "texture-compression-etc2" - | "texture-compression-astc-ldr" - | "texture-adapter-specific-format-features" - | "shader-float64" - | "vertex-attribute-64bit"; - -declare class GPUDevice extends EventTarget implements GPUObjectBase { - label: string | null; - - readonly lost: Promise<GPUDeviceLostInfo>; - pushErrorScope(filter: GPUErrorFilter): undefined; - popErrorScope(): Promise<GPUError | null>; - onuncapturederror: - | ((this: GPUDevice, ev: GPUUncapturedErrorEvent) => any) - | null; - - readonly features: ReadonlyArray<GPUFeatureName>; - readonly limits: Record<string, number>; - readonly queue: GPUQueue; - - destroy(): undefined; - - createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer; - createTexture(descriptor: GPUTextureDescriptor): GPUTexture; - createSampler(descriptor?: GPUSamplerDescriptor): GPUSampler; - - createBindGroupLayout( - descriptor: GPUBindGroupLayoutDescriptor, - ): GPUBindGroupLayout; - createPipelineLayout( - descriptor: GPUPipelineLayoutDescriptor, - ): GPUPipelineLayout; - createBindGroup(descriptor: GPUBindGroupDescriptor): GPUBindGroup; - - createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule; - createComputePipeline( - descriptor: GPUComputePipelineDescriptor, - ): GPUComputePipeline; - createRenderPipeline( - descriptor: GPURenderPipelineDescriptor, - ): GPURenderPipeline; - createComputePipelineAsync( - descriptor: GPUComputePipelineDescriptor, - ): Promise<GPUComputePipeline>; - createRenderPipelineAsync( - descriptor: GPURenderPipelineDescriptor, - ): Promise<GPURenderPipeline>; - - createCommandEncoder( - descriptor?: GPUCommandEncoderDescriptor, - ): GPUCommandEncoder; - createRenderBundleEncoder( - descriptor: GPURenderBundleEncoderDescriptor, - ): GPURenderBundleEncoder; - - createQuerySet(descriptor: GPUQuerySetDescriptor): GPUQuerySet; -} - -declare class GPUBuffer implements GPUObjectBase { - label: string | null; - - mapAsync( - mode: GPUMapModeFlags, - offset?: number, - size?: number, - ): Promise<undefined>; - getMappedRange(offset?: number, size?: number): ArrayBuffer; - unmap(): undefined; - - destroy(): undefined; -} - -declare interface GPUBufferDescriptor extends GPUObjectDescriptorBase { - size: number; - usage: GPUBufferUsageFlags; - mappedAtCreation?: boolean; -} - -declare type GPUBufferUsageFlags = number; -declare class GPUBufferUsage { - static MAP_READ: 0x0001; - static MAP_WRITE: 0x0002; - static COPY_SRC: 0x0004; - static COPY_DST: 0x0008; - static INDEX: 0x0010; - static VERTEX: 0x0020; - static UNIFORM: 0x0040; - static STORAGE: 0x0080; - static INDIRECT: 0x0100; - static QUERY_RESOLVE: 0x0200; -} - -declare type GPUMapModeFlags = number; -declare class GPUMapMode { - static READ: 0x0001; - static WRITE: 0x0002; -} - -declare class GPUTexture implements GPUObjectBase { - label: string | null; - - createView(descriptor?: GPUTextureViewDescriptor): GPUTextureView; - destroy(): undefined; -} - -declare interface GPUTextureDescriptor extends GPUObjectDescriptorBase { - size: GPUExtent3D; - mipLevelCount?: number; - sampleCount?: number; - dimension?: GPUTextureDimension; - format: GPUTextureFormat; - usage: GPUTextureUsageFlags; -} - -declare type GPUTextureDimension = "1d" | "2d" | "3d"; - -declare type GPUTextureUsageFlags = number; -declare class GPUTextureUsage { - static COPY_SRC: 0x01; - static COPY_DST: 0x02; - static SAMPLED: 0x04; - static STORAGE: 0x08; - static RENDER_ATTACHMENT: 0x10; -} - -declare class GPUTextureView implements GPUObjectBase { - label: string | null; -} - -declare interface GPUTextureViewDescriptor extends GPUObjectDescriptorBase { - format?: GPUTextureFormat; - dimension?: GPUTextureViewDimension; - aspect?: GPUTextureAspect; - baseMipLevel?: number; - mipLevelCount?: number; - baseArrayLayer?: number; - arrayLayerCount?: number; -} - -declare type GPUTextureViewDimension = - | "1d" - | "2d" - | "2d-array" - | "cube" - | "cube-array" - | "3d"; - -declare type GPUTextureAspect = "all" | "stencil-only" | "depth-only"; - -declare type GPUTextureFormat = - | "r8unorm" - | "r8snorm" - | "r8uint" - | "r8sint" - | "r16uint" - | "r16sint" - | "r16float" - | "rg8unorm" - | "rg8snorm" - | "rg8uint" - | "rg8sint" - | "r32uint" - | "r32sint" - | "r32float" - | "rg16uint" - | "rg16sint" - | "rg16float" - | "rgba8unorm" - | "rgba8unorm-srgb" - | "rgba8snorm" - | "rgba8uint" - | "rgba8sint" - | "bgra8unorm" - | "bgra8unorm-srgb" - | "rgb9e5ufloat" - | "rgb10a2unorm" - | "rg11b10ufloat" - | "rg32uint" - | "rg32sint" - | "rg32float" - | "rgba16uint" - | "rgba16sint" - | "rgba16float" - | "rgba32uint" - | "rgba32sint" - | "rgba32float" - | "stencil8" - | "depth16unorm" - | "depth24plus" - | "depth24plus-stencil8" - | "depth32float" - | "bc1-rgba-unorm" - | "bc1-rgba-unorm-srgb" - | "bc2-rgba-unorm" - | "bc2-rgba-unorm-srgb" - | "bc3-rgba-unorm" - | "bc3-rgba-unorm-srgb" - | "bc4-r-unorm" - | "bc4-r-snorm" - | "bc5-rg-unorm" - | "bc5-rg-snorm" - | "bc6h-rgb-ufloat" - | "bc6h-rgb-float" - | "bc7-rgba-unorm" - | "bc7-rgba-unorm-srgb" - | "depth24unorm-stencil8" - | "depth32float-stencil8"; - -declare class GPUSampler implements GPUObjectBase { - label: string | null; -} - -declare interface GPUSamplerDescriptor extends GPUObjectDescriptorBase { - addressModeU?: GPUAddressMode; - addressModeV?: GPUAddressMode; - addressModeW?: GPUAddressMode; - magFilter?: GPUFilterMode; - minFilter?: GPUFilterMode; - mipmapFilter?: GPUFilterMode; - lodMinClamp?: number; - lodMaxClamp?: number; - compare?: GPUCompareFunction; - maxAnisotropy?: number; -} - -declare type GPUAddressMode = "clamp-to-edge" | "repeat" | "mirror-repeat"; - -declare type GPUFilterMode = "nearest" | "linear"; - -declare type GPUCompareFunction = - | "never" - | "less" - | "equal" - | "less-equal" - | "greater" - | "not-equal" - | "greater-equal" - | "always"; - -declare class GPUBindGroupLayout implements GPUObjectBase { - label: string | null; -} - -declare interface GPUBindGroupLayoutDescriptor extends GPUObjectDescriptorBase { - entries: GPUBindGroupLayoutEntry[]; -} - -declare interface GPUBindGroupLayoutEntry { - binding: number; - visibility: GPUShaderStageFlags; - - buffer?: GPUBufferBindingLayout; - sampler?: GPUSamplerBindingLayout; - texture?: GPUTextureBindingLayout; - storageTexture?: GPUStorageTextureBindingLayout; -} - -declare type GPUShaderStageFlags = number; -declare class GPUShaderStage { - static VERTEX: 0x1; - static FRAGMENT: 0x2; - static COMPUTE: 0x4; -} - -declare interface GPUBufferBindingLayout { - type?: GPUBufferBindingType; - hasDynamicOffset?: boolean; - minBindingSize?: number; -} - -declare type GPUBufferBindingType = "uniform" | "storage" | "read-only-storage"; - -declare interface GPUSamplerBindingLayout { - type?: GPUSamplerBindingType; -} - -declare type GPUSamplerBindingType = - | "filtering" - | "non-filtering" - | "comparison"; - -declare interface GPUTextureBindingLayout { - sampleType?: GPUTextureSampleType; - viewDimension?: GPUTextureViewDimension; - multisampled?: boolean; -} - -declare type GPUTextureSampleType = - | "float" - | "unfilterable-float" - | "depth" - | "sint" - | "uint"; - -declare interface GPUTextureBindingLayout { - sampleType?: GPUTextureSampleType; - viewDimension?: GPUTextureViewDimension; - multisampled?: boolean; -} - -declare type GPUStorageTextureAccess = "read-only" | "write-only"; - -declare interface GPUStorageTextureBindingLayout { - access: GPUStorageTextureAccess; - format: GPUTextureFormat; - viewDimension?: GPUTextureViewDimension; -} - -declare class GPUBindGroup implements GPUObjectBase { - label: string | null; -} - -declare interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase { - layout: GPUBindGroupLayout; - entries: GPUBindGroupEntry[]; -} - -declare type GPUBindingResource = - | GPUSampler - | GPUTextureView - | GPUBufferBinding; - -declare interface GPUBindGroupEntry { - binding: number; - resource: GPUBindingResource; -} - -declare interface GPUBufferBinding { - buffer: GPUBuffer; - offset?: number; - size?: number; -} - -declare class GPUPipelineLayout implements GPUObjectBase { - label: string | null; -} - -declare interface GPUPipelineLayoutDescriptor extends GPUObjectDescriptorBase { - bindGroupLayouts: GPUBindGroupLayout[]; -} - -declare type GPUCompilationMessageType = "error" | "warning" | "info"; - -declare interface GPUCompilationMessage { - readonly message: string; - readonly type: GPUCompilationMessageType; - readonly lineNum: number; - readonly linePos: number; -} - -declare interface GPUCompilationInfo { - readonly messages: ReadonlyArray<GPUCompilationMessage>; -} - -declare class GPUShaderModule implements GPUObjectBase { - label: string | null; - - compilationInfo(): Promise<GPUCompilationInfo>; -} - -declare interface GPUShaderModuleDescriptor extends GPUObjectDescriptorBase { - code: string | Uint32Array; - sourceMap?: any; -} - -declare interface GPUPipelineDescriptorBase extends GPUObjectDescriptorBase { - layout?: GPUPipelineLayout; -} - -declare interface GPUPipelineBase { - getBindGroupLayout(index: number): GPUBindGroupLayout; -} - -declare interface GPUProgrammableStage { - module: GPUShaderModule; - entryPoint: string; -} - -declare class GPUComputePipeline implements GPUObjectBase, GPUPipelineBase { - label: string | null; - - getBindGroupLayout(index: number): GPUBindGroupLayout; -} - -declare interface GPUComputePipelineDescriptor - extends GPUPipelineDescriptorBase { - compute: GPUProgrammableStage; -} - -declare class GPURenderPipeline implements GPUObjectBase, GPUPipelineBase { - label: string | null; - - getBindGroupLayout(index: number): GPUBindGroupLayout; -} - -declare interface GPURenderPipelineDescriptor - extends GPUPipelineDescriptorBase { - vertex: GPUVertexState; - primitive?: GPUPrimitiveState; - depthStencil?: GPUDepthStencilState; - multisample?: GPUMultisampleState; - fragment?: GPUFragmentState; -} - -declare type GPUPrimitiveTopology = - | "point-list" - | "line-list" - | "line-strip" - | "triangle-list" - | "triangle-strip"; - -declare interface GPUPrimitiveState { - topology?: GPUPrimitiveTopology; - stripIndexFormat?: GPUIndexFormat; - frontFace?: GPUFrontFace; - cullMode?: GPUCullMode; - clampDepth?: boolean; -} - -declare type GPUFrontFace = "ccw" | "cw"; - -declare type GPUCullMode = "none" | "front" | "back"; - -declare interface GPUMultisampleState { - count?: number; - mask?: number; - alphaToCoverageEnabled?: boolean; -} - -declare interface GPUFragmentState extends GPUProgrammableStage { - targets: GPUColorTargetState[]; -} - -declare interface GPUColorTargetState { - format: GPUTextureFormat; - - blend?: GPUBlendState; - writeMask?: GPUColorWriteFlags; -} - -declare interface GPUBlendState { - color: GPUBlendComponent; - alpha: GPUBlendComponent; -} - -declare type GPUColorWriteFlags = number; -declare class GPUColorWrite { - static RED: 0x1; - static GREEN: 0x2; - static BLUE: 0x4; - static ALPHA: 0x8; - static ALL: 0xF; -} - -declare interface GPUBlendComponent { - srcFactor: GPUBlendFactor; - dstFactor: GPUBlendFactor; - operation: GPUBlendOperation; -} - -declare type GPUBlendFactor = - | "zero" - | "one" - | "src" - | "one-minus-src" - | "src-alpha" - | "one-minus-src-alpha" - | "dst" - | "one-minus-dst" - | "dst-alpha" - | "one-minus-dst-alpha" - | "src-alpha-saturated" - | "constant" - | "one-minus-constant"; - -declare type GPUBlendOperation = - | "add" - | "subtract" - | "reverse-subtract" - | "min" - | "max"; - -declare interface GPUDepthStencilState { - format: GPUTextureFormat; - - depthWriteEnabled?: boolean; - depthCompare?: GPUCompareFunction; - - stencilFront?: GPUStencilFaceState; - stencilBack?: GPUStencilFaceState; - - stencilReadMask?: number; - stencilWriteMask?: number; - - depthBias?: number; - depthBiasSlopeScale?: number; - depthBiasClamp?: number; -} - -declare interface GPUStencilFaceState { - compare?: GPUCompareFunction; - failOp?: GPUStencilOperation; - depthFailOp?: GPUStencilOperation; - passOp?: GPUStencilOperation; -} - -declare type GPUStencilOperation = - | "keep" - | "zero" - | "replace" - | "invert" - | "increment-clamp" - | "decrement-clamp" - | "increment-wrap" - | "decrement-wrap"; - -declare type GPUIndexFormat = "uint16" | "uint32"; - -declare type GPUVertexFormat = - | "uint8x2" - | "uint8x4" - | "sint8x2" - | "sint8x4" - | "unorm8x2" - | "unorm8x4" - | "snorm8x2" - | "snorm8x4" - | "uint16x2" - | "uint16x4" - | "sint16x2" - | "sint16x4" - | "unorm16x2" - | "unorm16x4" - | "snorm16x2" - | "snorm16x4" - | "float16x2" - | "float16x4" - | "float32" - | "float32x2" - | "float32x3" - | "float32x4" - | "uint32" - | "uint32x2" - | "uint32x3" - | "uint32x4" - | "sint32" - | "sint32x2" - | "sint32x3" - | "sint32x4"; -declare type GPUInputStepMode = "vertex" | "instance"; - -declare interface GPUVertexState extends GPUProgrammableStage { - buffers?: (GPUVertexBufferLayout | null)[]; -} - -declare interface GPUVertexBufferLayout { - arrayStride: number; - stepMode?: GPUInputStepMode; - attributes: GPUVertexAttribute[]; -} - -declare interface GPUVertexAttribute { - format: GPUVertexFormat; - offset: number; - - shaderLocation: number; -} - -declare class GPUCommandBuffer implements GPUObjectBase { - label: string | null; - - readonly executionTime: Promise<number>; -} - -declare interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {} - -declare class GPUCommandEncoder implements GPUObjectBase { - label: string | null; - - beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder; - beginComputePass( - descriptor?: GPUComputePassDescriptor, - ): GPUComputePassEncoder; - - copyBufferToBuffer( - source: GPUBuffer, - sourceOffset: number, - destination: GPUBuffer, - destinationOffset: number, - size: number, - ): undefined; - - copyBufferToTexture( - source: GPUImageCopyBuffer, - destination: GPUImageCopyTexture, - copySize: GPUExtent3D, - ): undefined; - - copyTextureToBuffer( - source: GPUImageCopyTexture, - destination: GPUImageCopyBuffer, - copySize: GPUExtent3D, - ): undefined; - - copyTextureToTexture( - source: GPUImageCopyTexture, - destination: GPUImageCopyTexture, - copySize: GPUExtent3D, - ): undefined; - - pushDebugGroup(groupLabel: string): undefined; - popDebugGroup(): undefined; - insertDebugMarker(markerLabel: string): undefined; - - writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; - - resolveQuerySet( - querySet: GPUQuerySet, - firstQuery: number, - queryCount: number, - destination: GPUBuffer, - destinationOffset: number, - ): undefined; - - finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer; -} - -declare interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase { - measureExecutionTime?: boolean; -} - -declare interface GPUImageDataLayout { - offset?: number; - bytesPerRow?: number; - rowsPerImage?: number; -} - -declare interface GPUImageCopyBuffer extends GPUImageDataLayout { - buffer: GPUBuffer; -} - -declare interface GPUImageCopyTexture { - texture: GPUTexture; - mipLevel?: number; - origin?: GPUOrigin3D; - aspect?: GPUTextureAspect; -} - -interface GPUProgrammablePassEncoder { - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsets?: number[], - ): undefined; - - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsetsData: Uint32Array, - dynamicOffsetsDataStart: number, - dynamicOffsetsDataLength: number, - ): undefined; - - pushDebugGroup(groupLabel: string): undefined; - popDebugGroup(): undefined; - insertDebugMarker(markerLabel: string): undefined; -} - -declare class GPUComputePassEncoder - implements GPUObjectBase, GPUProgrammablePassEncoder { - label: string | null; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsets?: number[], - ): undefined; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsetsData: Uint32Array, - dynamicOffsetsDataStart: number, - dynamicOffsetsDataLength: number, - ): undefined; - pushDebugGroup(groupLabel: string): undefined; - popDebugGroup(): undefined; - insertDebugMarker(markerLabel: string): undefined; - setPipeline(pipeline: GPUComputePipeline): undefined; - dispatch(x: number, y?: number, z?: number): undefined; - dispatchIndirect( - indirectBuffer: GPUBuffer, - indirectOffset: number, - ): undefined; - - beginPipelineStatisticsQuery( - querySet: GPUQuerySet, - queryIndex: number, - ): undefined; - endPipelineStatisticsQuery(): undefined; - - writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; - - endPass(): undefined; -} - -declare interface GPUComputePassDescriptor extends GPUObjectDescriptorBase {} - -interface GPURenderEncoderBase { - setPipeline(pipeline: GPURenderPipeline): undefined; - - setIndexBuffer( - buffer: GPUBuffer, - indexFormat: GPUIndexFormat, - offset?: number, - size?: number, - ): undefined; - setVertexBuffer( - slot: number, - buffer: GPUBuffer, - offset?: number, - size?: number, - ): undefined; - - draw( - vertexCount: number, - instanceCount?: number, - firstVertex?: number, - firstInstance?: number, - ): undefined; - drawIndexed( - indexCount: number, - instanceCount?: number, - firstIndex?: number, - baseVertex?: number, - firstInstance?: number, - ): undefined; - - drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; - drawIndexedIndirect( - indirectBuffer: GPUBuffer, - indirectOffset: number, - ): undefined; -} - -declare class GPURenderPassEncoder - implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { - label: string | null; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsets?: number[], - ): undefined; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsetsData: Uint32Array, - dynamicOffsetsDataStart: number, - dynamicOffsetsDataLength: number, - ): undefined; - pushDebugGroup(groupLabel: string): undefined; - popDebugGroup(): undefined; - insertDebugMarker(markerLabel: string): undefined; - setPipeline(pipeline: GPURenderPipeline): undefined; - setIndexBuffer( - buffer: GPUBuffer, - indexFormat: GPUIndexFormat, - offset?: number, - size?: number, - ): undefined; - setVertexBuffer( - slot: number, - buffer: GPUBuffer, - offset?: number, - size?: number, - ): undefined; - draw( - vertexCount: number, - instanceCount?: number, - firstVertex?: number, - firstInstance?: number, - ): undefined; - drawIndexed( - indexCount: number, - instanceCount?: number, - firstIndex?: number, - baseVertex?: number, - firstInstance?: number, - ): undefined; - drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; - drawIndexedIndirect( - indirectBuffer: GPUBuffer, - indirectOffset: number, - ): undefined; - - setViewport( - x: number, - y: number, - width: number, - height: number, - minDepth: number, - maxDepth: number, - ): undefined; - - setScissorRect( - x: number, - y: number, - width: number, - height: number, - ): undefined; - - setBlendConstant(color: GPUColor): undefined; - setStencilReference(reference: number): undefined; - - beginOcclusionQuery(queryIndex: number): undefined; - endOcclusionQuery(): undefined; - - beginPipelineStatisticsQuery( - querySet: GPUQuerySet, - queryIndex: number, - ): undefined; - endPipelineStatisticsQuery(): undefined; - - writeTimestamp(querySet: GPUQuerySet, queryIndex: number): undefined; - - executeBundles(bundles: GPURenderBundle[]): undefined; - endPass(): undefined; -} - -declare interface GPURenderPassDescriptor extends GPUObjectDescriptorBase { - colorAttachments: GPURenderPassColorAttachment[]; - depthStencilAttachment?: GPURenderPassDepthStencilAttachment; - occlusionQuerySet?: GPUQuerySet; -} - -declare interface GPURenderPassColorAttachment { - view: GPUTextureView; - resolveTarget?: GPUTextureView; - - loadValue: GPULoadOp | GPUColor; - storeOp?: GPUStoreOp; -} - -declare interface GPURenderPassDepthStencilAttachment { - view: GPUTextureView; - - depthLoadValue: GPULoadOp | number; - depthStoreOp: GPUStoreOp; - depthReadOnly?: boolean; - - stencilLoadValue: GPULoadOp | number; - stencilStoreOp: GPUStoreOp; - stencilReadOnly?: boolean; -} - -declare type GPULoadOp = "load"; - -declare type GPUStoreOp = "store" | "discard"; - -declare class GPURenderBundle implements GPUObjectBase { - label: string | null; -} - -declare interface GPURenderBundleDescriptor extends GPUObjectDescriptorBase {} - -declare class GPURenderBundleEncoder - implements GPUObjectBase, GPUProgrammablePassEncoder, GPURenderEncoderBase { - label: string | null; - draw( - vertexCount: number, - instanceCount?: number, - firstVertex?: number, - firstInstance?: number, - ): undefined; - drawIndexed( - indexCount: number, - instanceCount?: number, - firstIndex?: number, - baseVertex?: number, - firstInstance?: number, - ): undefined; - drawIndexedIndirect( - indirectBuffer: GPUBuffer, - indirectOffset: number, - ): undefined; - drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): undefined; - insertDebugMarker(markerLabel: string): undefined; - popDebugGroup(): undefined; - pushDebugGroup(groupLabel: string): undefined; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsets?: number[], - ): undefined; - setBindGroup( - index: number, - bindGroup: GPUBindGroup, - dynamicOffsetsData: Uint32Array, - dynamicOffsetsDataStart: number, - dynamicOffsetsDataLength: number, - ): undefined; - setIndexBuffer( - buffer: GPUBuffer, - indexFormat: GPUIndexFormat, - offset?: number, - size?: number, - ): undefined; - setPipeline(pipeline: GPURenderPipeline): undefined; - setVertexBuffer( - slot: number, - buffer: GPUBuffer, - offset?: number, - size?: number, - ): undefined; - - finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle; -} - -declare interface GPURenderBundleEncoderDescriptor - extends GPUObjectDescriptorBase { - colorFormats: GPUTextureFormat[]; - depthStencilFormat?: GPUTextureFormat; - sampleCount?: number; -} - -declare class GPUQueue implements GPUObjectBase { - label: string | null; - - submit(commandBuffers: GPUCommandBuffer[]): undefined; - - onSubmittedWorkDone(): Promise<undefined>; - - writeBuffer( - buffer: GPUBuffer, - bufferOffset: number, - data: BufferSource, - dataOffset?: number, - size?: number, - ): undefined; - - writeTexture( - destination: GPUImageCopyTexture, - data: BufferSource, - dataLayout: GPUImageDataLayout, - size: GPUExtent3D, - ): undefined; -} - -declare class GPUQuerySet implements GPUObjectBase { - label: string | null; - - destroy(): undefined; -} - -declare interface GPUQuerySetDescriptor extends GPUObjectDescriptorBase { - type: GPUQueryType; - count: number; - pipelineStatistics?: GPUPipelineStatisticName[]; -} - -declare type GPUQueryType = "occlusion" | "pipeline-statistics" | "timestamp"; - -declare type GPUPipelineStatisticName = - | "vertex-shader-invocations" - | "clipper-invocations" - | "clipper-primitives-out" - | "fragment-shader-invocations" - | "compute-shader-invocations"; - -declare type GPUDeviceLostReason = "destroyed"; - -declare interface GPUDeviceLostInfo { - readonly reason: GPUDeviceLostReason | undefined; - readonly message: string; -} - -declare type GPUErrorFilter = "out-of-memory" | "validation"; - -declare class GPUOutOfMemoryError { - constructor(); -} - -declare class GPUValidationError { - constructor(message: string); - readonly message: string; -} - -declare type GPUError = GPUOutOfMemoryError | GPUValidationError; - -declare class GPUUncapturedErrorEvent extends Event { - constructor( - type: string, - gpuUncapturedErrorEventInitDict: GPUUncapturedErrorEventInit, - ); - readonly error: GPUError; -} - -declare interface GPUUncapturedErrorEventInit extends EventInit { - error?: GPUError; -} - -declare interface GPUColorDict { - r: number; - g: number; - b: number; - a: number; -} - -declare type GPUColor = number[] | GPUColorDict; - -declare interface GPUOrigin3DDict { - x?: number; - y?: number; - z?: number; -} - -declare type GPUOrigin3D = number[] | GPUOrigin3DDict; - -declare interface GPUExtent3DDict { - width: number; - height?: number; - depthOrArrayLayers?: number; -} - -declare type GPUExtent3D = number[] | GPUExtent3DDict; diff --git a/extensions/webgpu/lib.rs b/extensions/webgpu/lib.rs deleted file mode 100644 index 56337d030..000000000 --- a/extensions/webgpu/lib.rs +++ /dev/null @@ -1,928 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; -use deno_core::include_js_files; -use deno_core::op_async; -use deno_core::op_sync; -use deno_core::Extension; -use deno_core::OpFn; -use deno_core::OpState; -use deno_core::Resource; -use deno_core::ResourceId; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::path::PathBuf; -use std::rc::Rc; -pub use wgpu_core; -pub use wgpu_types; - -use error::DomExceptionOperationError; -use error::WebGpuResult; - -#[macro_use] -mod macros { - macro_rules! gfx_select { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { - match $id.backend() { - #[cfg(not(target_os = "macos"))] - wgpu_types::Backend::Vulkan => $global.$method::<wgpu_core::backend::Vulkan>( $($param),* ), - #[cfg(target_os = "macos")] - wgpu_types::Backend::Metal => $global.$method::<wgpu_core::backend::Metal>( $($param),* ), - #[cfg(windows)] - wgpu_types::Backend::Dx12 => $global.$method::<wgpu_core::backend::Dx12>( $($param),* ), - #[cfg(windows)] - wgpu_types::Backend::Dx11 => $global.$method::<wgpu_core::backend::Dx11>( $($param),* ), - #[cfg(all(unix, not(target_os = "macos")))] - wgpu_types::Backend::Gl => $global.$method::<wgpu_core::backend::Gl>( $($param),+ ), - other => panic!("Unexpected backend {:?}", other), - } - }; - } - - macro_rules! gfx_put { - ($id:expr => $global:ident.$method:ident( $($param:expr),* ) => $state:expr, $rc:expr) => {{ - let (val, maybe_err) = gfx_select!($id => $global.$method($($param),*)); - let rid = $state.resource_table.add($rc(val)); - Ok(WebGpuResult::rid_err(rid, maybe_err)) - }}; - } - - macro_rules! gfx_ok { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {{ - let maybe_err = gfx_select!($id => $global.$method($($param),*)).err(); - Ok(WebGpuResult::maybe_err(maybe_err)) - }}; - } -} - -pub mod binding; -pub mod buffer; -pub mod bundle; -pub mod command_encoder; -pub mod compute_pass; -pub mod error; -pub mod pipeline; -pub mod queue; -pub mod render_pass; -pub mod sampler; -pub mod shader; -pub mod texture; - -pub struct Unstable(pub bool); - -fn check_unstable(state: &OpState, api_name: &str) { - let unstable = state.borrow::<Unstable>(); - - if !unstable.0 { - eprintln!( - "Unstable API '{}'. The --unstable flag must be provided.", - api_name - ); - std::process::exit(70); - } -} - -type Instance = wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>; - -struct WebGpuAdapter(wgpu_core::id::AdapterId); -impl Resource for WebGpuAdapter { - fn name(&self) -> Cow<str> { - "webGPUAdapter".into() - } -} - -struct WebGpuDevice(wgpu_core::id::DeviceId); -impl Resource for WebGpuDevice { - fn name(&self) -> Cow<str> { - "webGPUDevice".into() - } -} - -struct WebGpuQuerySet(wgpu_core::id::QuerySetId); -impl Resource for WebGpuQuerySet { - fn name(&self) -> Cow<str> { - "webGPUQuerySet".into() - } -} - -pub fn init(unstable: bool) -> Extension { - Extension::builder() - .js(include_js_files!( - prefix "deno:extensions/webgpu", - "01_webgpu.js", - "02_idl_types.js", - )) - .ops(declare_webgpu_ops()) - .state(move |state| { - // TODO: check & possibly streamline this - // Unstable might be able to be OpMiddleware - // let unstable_checker = state.borrow::<super::UnstableChecker>(); - // let unstable = unstable_checker.unstable; - state.put(Unstable(unstable)); - Ok(()) - }) - .build() -} - -pub fn get_declaration() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webgpu.d.ts") -} - -fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { - let mut return_features: Vec<&'static str> = vec![]; - - if features.contains(wgpu_types::Features::DEPTH_CLAMPING) { - return_features.push("depth-clamping"); - } - if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { - return_features.push("pipeline-statistics-query"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { - return_features.push("texture-compression-bc"); - } - if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { - return_features.push("timestamp-query"); - } - - // extended from spec - if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { - return_features.push("mappable-primary-buffers"); - } - if features.contains(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY) { - return_features.push("sampled-texture-binding-array"); - } - if features - .contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING) - { - return_features.push("sampled-texture-array-dynamic-indexing"); - } - if features - .contains(wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) - { - return_features.push("sampled-texture-array-non-uniform-indexing"); - } - if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { - return_features.push("unsized-binding-array"); - } - if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT) { - return_features.push("multi-draw-indirect"); - } - if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT) { - return_features.push("multi-draw-indirect-count"); - } - if features.contains(wgpu_types::Features::PUSH_CONSTANTS) { - return_features.push("push-constants"); - } - if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { - return_features.push("address-mode-clamp-to-border"); - } - if features.contains(wgpu_types::Features::NON_FILL_POLYGON_MODE) { - return_features.push("non-fill-polygon-mode"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { - return_features.push("texture-compression-etc2"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { - return_features.push("texture-compression-astc-ldr"); - } - if features - .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) - { - return_features.push("texture-adapter-specific-format-features"); - } - if features.contains(wgpu_types::Features::SHADER_FLOAT64) { - return_features.push("shader-float64"); - } - if features.contains(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT) { - return_features.push("vertex-attribute-64bit"); - } - - return_features -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RequestAdapterArgs { - power_preference: Option<String>, -} - -#[derive(Serialize)] -#[serde(untagged)] -pub enum GpuAdapterDeviceOrErr { - Error { err: String }, - Features(GpuAdapterDevice), -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuAdapterDevice { - rid: ResourceId, - name: Option<String>, - limits: wgpu_types::Limits, - features: Vec<&'static str>, - is_software: bool, -} - -pub async fn op_webgpu_request_adapter( - state: Rc<RefCell<OpState>>, - args: RequestAdapterArgs, - _: (), -) -> Result<GpuAdapterDeviceOrErr, AnyError> { - let mut state = state.borrow_mut(); - check_unstable(&state, "navigator.gpu.requestAdapter"); - let instance = if let Some(instance) = state.try_borrow::<Instance>() { - instance - } else { - state.put(wgpu_core::hub::Global::new( - "webgpu", - wgpu_core::hub::IdentityManagerFactory, - wgpu_types::BackendBit::PRIMARY, - )); - state.borrow::<Instance>() - }; - - let descriptor = wgpu_core::instance::RequestAdapterOptions { - power_preference: match args.power_preference { - Some(power_preference) => match power_preference.as_str() { - "low-power" => wgpu_types::PowerPreference::LowPower, - "high-performance" => wgpu_types::PowerPreference::HighPerformance, - _ => unreachable!(), - }, - None => Default::default(), - }, - // TODO(lucacasonato): respect forceSoftware - compatible_surface: None, // windowless - }; - let res = instance.request_adapter( - &descriptor, - wgpu_core::instance::AdapterInputs::Mask( - wgpu_types::BackendBit::PRIMARY, - |_| std::marker::PhantomData, - ), - ); - - let adapter = match res { - Ok(adapter) => adapter, - Err(err) => { - return Ok(GpuAdapterDeviceOrErr::Error { - err: err.to_string(), - }) - } - }; - let name = gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; - let adapter_features = - gfx_select!(adapter => instance.adapter_features(adapter))?; - let features = deserialize_features(&adapter_features); - let adapter_limits = - gfx_select!(adapter => instance.adapter_limits(adapter))?; - - let rid = state.resource_table.add(WebGpuAdapter(adapter)); - - Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice { - rid, - name: Some(name), - features, - limits: adapter_limits, - is_software: false, - })) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuLimits { - max_texture_dimension_1d: Option<u32>, - max_texture_dimension_2d: Option<u32>, - max_texture_dimension_3d: Option<u32>, - max_texture_array_layers: Option<u32>, - max_bind_groups: Option<u32>, - max_dynamic_uniform_buffers_per_pipeline_layout: Option<u32>, - max_dynamic_storage_buffers_per_pipeline_layout: Option<u32>, - max_sampled_textures_per_shader_stage: Option<u32>, - max_samplers_per_shader_stage: Option<u32>, - max_storage_buffers_per_shader_stage: Option<u32>, - max_storage_textures_per_shader_stage: Option<u32>, - max_uniform_buffers_per_shader_stage: Option<u32>, - max_uniform_buffer_binding_size: Option<u32>, - max_storage_buffer_binding_size: Option<u32>, - // min_uniform_buffer_offset_alignment: Option<u32>, - // min_storage_buffer_offset_alignment: Option<u32>, - max_vertex_buffers: Option<u32>, - max_vertex_attributes: Option<u32>, - max_vertex_buffer_array_stride: Option<u32>, - // max_inter_stage_shader_components: Option<u32>, - // max_compute_workgroup_storage_size: Option<u32>, - // max_compute_workgroup_invocations: Option<u32>, - // max_compute_per_dimension_dispatch_size: Option<u32>, -} - -impl From<GpuLimits> for wgpu_types::Limits { - fn from(limits: GpuLimits) -> wgpu_types::Limits { - wgpu_types::Limits { - max_texture_dimension_1d: limits.max_texture_dimension_1d.unwrap_or(8192), - max_texture_dimension_2d: limits.max_texture_dimension_2d.unwrap_or(8192), - max_texture_dimension_3d: limits.max_texture_dimension_3d.unwrap_or(2048), - max_texture_array_layers: limits.max_texture_array_layers.unwrap_or(2048), - max_bind_groups: limits.max_bind_groups.unwrap_or(4), - max_dynamic_uniform_buffers_per_pipeline_layout: limits - .max_dynamic_uniform_buffers_per_pipeline_layout - .unwrap_or(8), - max_dynamic_storage_buffers_per_pipeline_layout: limits - .max_dynamic_storage_buffers_per_pipeline_layout - .unwrap_or(4), - max_sampled_textures_per_shader_stage: limits - .max_sampled_textures_per_shader_stage - .unwrap_or(16), - max_samplers_per_shader_stage: limits - .max_samplers_per_shader_stage - .unwrap_or(16), - max_storage_buffers_per_shader_stage: limits - .max_storage_buffers_per_shader_stage - .unwrap_or(4), - max_storage_textures_per_shader_stage: limits - .max_storage_textures_per_shader_stage - .unwrap_or(4), - max_uniform_buffers_per_shader_stage: limits - .max_uniform_buffers_per_shader_stage - .unwrap_or(12), - max_uniform_buffer_binding_size: limits - .max_uniform_buffer_binding_size - .unwrap_or(16384), - max_storage_buffer_binding_size: limits - .max_storage_buffer_binding_size - .unwrap_or(134217728), - // min_uniform_buffer_offset_alignment: limits - // .min_uniform_buffer_offset_alignment - // .unwrap_or(default), - // min_storage_buffer_offset_alignment: limits - // .min_storage_buffer_offset_alignment - // .unwrap_or(default), - max_vertex_buffers: limits.max_vertex_buffers.unwrap_or(8), - max_vertex_attributes: limits.max_vertex_attributes.unwrap_or(16), - max_vertex_buffer_array_stride: limits - .max_vertex_buffer_array_stride - .unwrap_or(2048), - // max_inter_stage_shader_components: limits - // .max_inter_stage_shader_components - // .unwrap_or(default), - // max_compute_workgroup_storage_size: limits - // .max_compute_workgroup_storage_size - // .unwrap_or(default), - // max_compute_workgroup_invocations: limits - // .max_compute_workgroup_invocations - // .unwrap_or(default), - // max_compute_per_dimension_dispatch_size: limits - // .max_compute_per_dimension_dispatch_size - // .unwrap_or(default), - max_push_constant_size: 0, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RequestDeviceArgs { - adapter_rid: ResourceId, - label: Option<String>, - required_features: Option<Vec<String>>, - required_limits: Option<GpuLimits>, -} - -pub async fn op_webgpu_request_device( - state: Rc<RefCell<OpState>>, - args: RequestDeviceArgs, - _: (), -) -> Result<GpuAdapterDevice, AnyError> { - let mut state = state.borrow_mut(); - let adapter_resource = state - .resource_table - .get::<WebGpuAdapter>(args.adapter_rid) - .ok_or_else(bad_resource_id)?; - let adapter = adapter_resource.0; - let instance = state.borrow::<Instance>(); - - let mut features: wgpu_types::Features = wgpu_types::Features::empty(); - - if let Some(passed_features) = args.required_features { - if passed_features.contains(&"depth-clamping".to_string()) { - features.set(wgpu_types::Features::DEPTH_CLAMPING, true); - } - if passed_features.contains(&"pipeline-statistics-query".to_string()) { - features.set(wgpu_types::Features::PIPELINE_STATISTICS_QUERY, true); - } - if passed_features.contains(&"texture-compression-bc".to_string()) { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_BC, true); - } - if passed_features.contains(&"timestamp-query".to_string()) { - features.set(wgpu_types::Features::TIMESTAMP_QUERY, true); - } - - // extended from spec - if passed_features.contains(&"mappable-primary-buffers".to_string()) { - features.set(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, true); - } - if passed_features.contains(&"sampled-texture-binding-array".to_string()) { - features.set(wgpu_types::Features::SAMPLED_TEXTURE_BINDING_ARRAY, true); - } - if passed_features - .contains(&"sampled-texture-array-dynamic-indexing".to_string()) - { - features.set( - wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING, - true, - ); - } - if passed_features - .contains(&"sampled-texture-array-non-uniform-indexing".to_string()) - { - features.set( - wgpu_types::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - true, - ); - } - if passed_features.contains(&"unsized-binding-array".to_string()) { - features.set(wgpu_types::Features::UNSIZED_BINDING_ARRAY, true); - } - if passed_features.contains(&"multi-draw-indirect".to_string()) { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT, true); - } - if passed_features.contains(&"multi-draw-indirect-count".to_string()) { - features.set(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, true); - } - if passed_features.contains(&"push-constants".to_string()) { - features.set(wgpu_types::Features::PUSH_CONSTANTS, true); - } - if passed_features.contains(&"address-mode-clamp-to-border".to_string()) { - features.set(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); - } - if passed_features.contains(&"non-fill-polygon-mode".to_string()) { - features.set(wgpu_types::Features::NON_FILL_POLYGON_MODE, true); - } - if passed_features.contains(&"texture-compression-etc2".to_string()) { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, true); - } - if passed_features.contains(&"texture-compression-astc-ldr".to_string()) { - features.set(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, true); - } - if passed_features - .contains(&"texture-adapter-specific-format-features".to_string()) - { - features.set( - wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, - true, - ); - } - if passed_features.contains(&"shader-float64".to_string()) { - features.set(wgpu_types::Features::SHADER_FLOAT64, true); - } - if passed_features.contains(&"vertex-attribute-64bit".to_string()) { - features.set(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, true); - } - } - - let descriptor = wgpu_types::DeviceDescriptor { - label: args.label.map(Cow::from), - features, - limits: args - .required_limits - .map_or(wgpu_types::Limits::default(), Into::into), - }; - - let (device, maybe_err) = gfx_select!(adapter => instance.adapter_request_device( - adapter, - &descriptor, - std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), - std::marker::PhantomData - )); - if let Some(err) = maybe_err { - return Err(DomExceptionOperationError::new(&err.to_string()).into()); - } - - let device_features = - gfx_select!(device => instance.device_features(device))?; - let features = deserialize_features(&device_features); - let limits = gfx_select!(device => instance.device_limits(device))?; - - let rid = state.resource_table.add(WebGpuDevice(device)); - - Ok(GpuAdapterDevice { - rid, - name: None, - features, - limits, - // TODO(lucacasonato): report correctly from wgpu - is_software: false, - }) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateQuerySetArgs { - device_rid: ResourceId, - _label: Option<String>, // not yet implemented - #[serde(rename = "type")] - kind: String, - count: u32, - pipeline_statistics: Option<Vec<String>>, -} - -pub fn op_webgpu_create_query_set( - state: &mut OpState, - args: CreateQuerySetArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let device_resource = state - .resource_table - .get::<WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - let instance = &state.borrow::<Instance>(); - - let descriptor = wgpu_types::QuerySetDescriptor { - ty: match args.kind.as_str() { - "pipeline-statistics" => { - let mut pipeline_statistics_names = - wgpu_types::PipelineStatisticsTypes::empty(); - - if let Some(pipeline_statistics) = args.pipeline_statistics { - if pipeline_statistics - .contains(&"vertex-shader-invocations".to_string()) - { - pipeline_statistics_names.set( - wgpu_types::PipelineStatisticsTypes::VERTEX_SHADER_INVOCATIONS, - true, - ); - } - if pipeline_statistics.contains(&"clipper-invocations".to_string()) { - pipeline_statistics_names.set( - wgpu_types::PipelineStatisticsTypes::CLIPPER_INVOCATIONS, - true, - ); - } - if pipeline_statistics.contains(&"clipper-primitives-out".to_string()) - { - pipeline_statistics_names.set( - wgpu_types::PipelineStatisticsTypes::CLIPPER_PRIMITIVES_OUT, - true, - ); - } - if pipeline_statistics - .contains(&"fragment-shader-invocations".to_string()) - { - pipeline_statistics_names.set( - wgpu_types::PipelineStatisticsTypes::FRAGMENT_SHADER_INVOCATIONS, - true, - ); - } - if pipeline_statistics - .contains(&"compute-shader-invocations".to_string()) - { - pipeline_statistics_names.set( - wgpu_types::PipelineStatisticsTypes::COMPUTE_SHADER_INVOCATIONS, - true, - ); - } - }; - - wgpu_types::QueryType::PipelineStatistics(pipeline_statistics_names) - } - "occlusion" => return Err(not_supported()), - "timestamp" => wgpu_types::QueryType::Timestamp, - _ => unreachable!(), - }, - count: args.count, - }; - - gfx_put!(device => instance.device_create_query_set( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuQuerySet) -} - -fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> { - vec![ - // Request device/adapter - ( - "op_webgpu_request_adapter", - op_async(op_webgpu_request_adapter), - ), - ( - "op_webgpu_request_device", - op_async(op_webgpu_request_device), - ), - // Query Set - ( - "op_webgpu_create_query_set", - op_sync(op_webgpu_create_query_set), - ), - // buffer - ( - "op_webgpu_create_buffer", - op_sync(buffer::op_webgpu_create_buffer), - ), - ( - "op_webgpu_buffer_get_mapped_range", - op_sync(buffer::op_webgpu_buffer_get_mapped_range), - ), - ( - "op_webgpu_buffer_unmap", - op_sync(buffer::op_webgpu_buffer_unmap), - ), - // buffer async - ( - "op_webgpu_buffer_get_map_async", - op_async(buffer::op_webgpu_buffer_get_map_async), - ), - // remaining sync ops - - // texture - ( - "op_webgpu_create_texture", - op_sync(texture::op_webgpu_create_texture), - ), - ( - "op_webgpu_create_texture_view", - op_sync(texture::op_webgpu_create_texture_view), - ), - // sampler - ( - "op_webgpu_create_sampler", - op_sync(sampler::op_webgpu_create_sampler), - ), - // binding - ( - "op_webgpu_create_bind_group_layout", - op_sync(binding::op_webgpu_create_bind_group_layout), - ), - ( - "op_webgpu_create_pipeline_layout", - op_sync(binding::op_webgpu_create_pipeline_layout), - ), - ( - "op_webgpu_create_bind_group", - op_sync(binding::op_webgpu_create_bind_group), - ), - // pipeline - ( - "op_webgpu_create_compute_pipeline", - op_sync(pipeline::op_webgpu_create_compute_pipeline), - ), - ( - "op_webgpu_compute_pipeline_get_bind_group_layout", - op_sync(pipeline::op_webgpu_compute_pipeline_get_bind_group_layout), - ), - ( - "op_webgpu_create_render_pipeline", - op_sync(pipeline::op_webgpu_create_render_pipeline), - ), - ( - "op_webgpu_render_pipeline_get_bind_group_layout", - op_sync(pipeline::op_webgpu_render_pipeline_get_bind_group_layout), - ), - // command_encoder - ( - "op_webgpu_create_command_encoder", - op_sync(command_encoder::op_webgpu_create_command_encoder), - ), - ( - "op_webgpu_command_encoder_begin_render_pass", - op_sync(command_encoder::op_webgpu_command_encoder_begin_render_pass), - ), - ( - "op_webgpu_command_encoder_begin_compute_pass", - op_sync(command_encoder::op_webgpu_command_encoder_begin_compute_pass), - ), - ( - "op_webgpu_command_encoder_copy_buffer_to_buffer", - op_sync(command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer), - ), - ( - "op_webgpu_command_encoder_copy_buffer_to_texture", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, - ), - ), - ( - "op_webgpu_command_encoder_copy_texture_to_buffer", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, - ), - ), - ( - "op_webgpu_command_encoder_copy_texture_to_texture", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, - ), - ), - ( - "op_webgpu_command_encoder_push_debug_group", - op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group), - ), - ( - "op_webgpu_command_encoder_pop_debug_group", - op_sync(command_encoder::op_webgpu_command_encoder_pop_debug_group), - ), - ( - "op_webgpu_command_encoder_insert_debug_marker", - op_sync(command_encoder::op_webgpu_command_encoder_insert_debug_marker), - ), - ( - "op_webgpu_command_encoder_write_timestamp", - op_sync(command_encoder::op_webgpu_command_encoder_write_timestamp), - ), - ( - "op_webgpu_command_encoder_resolve_query_set", - op_sync(command_encoder::op_webgpu_command_encoder_resolve_query_set), - ), - ( - "op_webgpu_command_encoder_finish", - op_sync(command_encoder::op_webgpu_command_encoder_finish), - ), - // render_pass - ( - "op_webgpu_render_pass_set_viewport", - op_sync(render_pass::op_webgpu_render_pass_set_viewport), - ), - ( - "op_webgpu_render_pass_set_scissor_rect", - op_sync(render_pass::op_webgpu_render_pass_set_scissor_rect), - ), - ( - "op_webgpu_render_pass_set_blend_constant", - op_sync(render_pass::op_webgpu_render_pass_set_blend_constant), - ), - ( - "op_webgpu_render_pass_set_stencil_reference", - op_sync(render_pass::op_webgpu_render_pass_set_stencil_reference), - ), - ( - "op_webgpu_render_pass_begin_pipeline_statistics_query", - op_sync( - render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, - ), - ), - ( - "op_webgpu_render_pass_end_pipeline_statistics_query", - op_sync(render_pass::op_webgpu_render_pass_end_pipeline_statistics_query), - ), - ( - "op_webgpu_render_pass_write_timestamp", - op_sync(render_pass::op_webgpu_render_pass_write_timestamp), - ), - ( - "op_webgpu_render_pass_execute_bundles", - op_sync(render_pass::op_webgpu_render_pass_execute_bundles), - ), - ( - "op_webgpu_render_pass_end_pass", - op_sync(render_pass::op_webgpu_render_pass_end_pass), - ), - ( - "op_webgpu_render_pass_set_bind_group", - op_sync(render_pass::op_webgpu_render_pass_set_bind_group), - ), - ( - "op_webgpu_render_pass_push_debug_group", - op_sync(render_pass::op_webgpu_render_pass_push_debug_group), - ), - ( - "op_webgpu_render_pass_pop_debug_group", - op_sync(render_pass::op_webgpu_render_pass_pop_debug_group), - ), - ( - "op_webgpu_render_pass_insert_debug_marker", - op_sync(render_pass::op_webgpu_render_pass_insert_debug_marker), - ), - ( - "op_webgpu_render_pass_set_pipeline", - op_sync(render_pass::op_webgpu_render_pass_set_pipeline), - ), - ( - "op_webgpu_render_pass_set_index_buffer", - op_sync(render_pass::op_webgpu_render_pass_set_index_buffer), - ), - ( - "op_webgpu_render_pass_set_vertex_buffer", - op_sync(render_pass::op_webgpu_render_pass_set_vertex_buffer), - ), - ( - "op_webgpu_render_pass_draw", - op_sync(render_pass::op_webgpu_render_pass_draw), - ), - ( - "op_webgpu_render_pass_draw_indexed", - op_sync(render_pass::op_webgpu_render_pass_draw_indexed), - ), - ( - "op_webgpu_render_pass_draw_indirect", - op_sync(render_pass::op_webgpu_render_pass_draw_indirect), - ), - ( - "op_webgpu_render_pass_draw_indexed_indirect", - op_sync(render_pass::op_webgpu_render_pass_draw_indexed_indirect), - ), - // compute_pass - ( - "op_webgpu_compute_pass_set_pipeline", - op_sync(compute_pass::op_webgpu_compute_pass_set_pipeline), - ), - ( - "op_webgpu_compute_pass_dispatch", - op_sync(compute_pass::op_webgpu_compute_pass_dispatch), - ), - ( - "op_webgpu_compute_pass_dispatch_indirect", - op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect), - ), - ( - "op_webgpu_compute_pass_end_pass", - op_sync(compute_pass::op_webgpu_compute_pass_end_pass), - ), - ( - "op_webgpu_compute_pass_set_bind_group", - op_sync(compute_pass::op_webgpu_compute_pass_set_bind_group), - ), - ( - "op_webgpu_compute_pass_push_debug_group", - op_sync(compute_pass::op_webgpu_compute_pass_push_debug_group), - ), - ( - "op_webgpu_compute_pass_pop_debug_group", - op_sync(compute_pass::op_webgpu_compute_pass_pop_debug_group), - ), - ( - "op_webgpu_compute_pass_insert_debug_marker", - op_sync(compute_pass::op_webgpu_compute_pass_insert_debug_marker), - ), - // bundle - ( - "op_webgpu_create_render_bundle_encoder", - op_sync(bundle::op_webgpu_create_render_bundle_encoder), - ), - ( - "op_webgpu_render_bundle_encoder_finish", - op_sync(bundle::op_webgpu_render_bundle_encoder_finish), - ), - ( - "op_webgpu_render_bundle_encoder_set_bind_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_bind_group), - ), - ( - "op_webgpu_render_bundle_encoder_push_debug_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_push_debug_group), - ), - ( - "op_webgpu_render_bundle_encoder_pop_debug_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_pop_debug_group), - ), - ( - "op_webgpu_render_bundle_encoder_insert_debug_marker", - op_sync(bundle::op_webgpu_render_bundle_encoder_insert_debug_marker), - ), - ( - "op_webgpu_render_bundle_encoder_set_pipeline", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_pipeline), - ), - ( - "op_webgpu_render_bundle_encoder_set_index_buffer", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_index_buffer), - ), - ( - "op_webgpu_render_bundle_encoder_set_vertex_buffer", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer), - ), - ( - "op_webgpu_render_bundle_encoder_draw", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw), - ), - ( - "op_webgpu_render_bundle_encoder_draw_indexed", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indexed), - ), - ( - "op_webgpu_render_bundle_encoder_draw_indirect", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indirect), - ), - // queue - ( - "op_webgpu_queue_submit", - op_sync(queue::op_webgpu_queue_submit), - ), - ( - "op_webgpu_write_buffer", - op_sync(queue::op_webgpu_write_buffer), - ), - ( - "op_webgpu_write_texture", - op_sync(queue::op_webgpu_write_texture), - ), - // shader - ( - "op_webgpu_create_shader_module", - op_sync(shader::op_webgpu_create_shader_module), - ), - ] -} diff --git a/extensions/webgpu/pipeline.rs b/extensions/webgpu/pipeline.rs deleted file mode 100644 index 6d11179a4..000000000 --- a/extensions/webgpu/pipeline.rs +++ /dev/null @@ -1,686 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; - -use super::error::{WebGpuError, WebGpuResult}; - -pub(crate) struct WebGpuPipelineLayout( - pub(crate) wgpu_core::id::PipelineLayoutId, -); -impl Resource for WebGpuPipelineLayout { - fn name(&self) -> Cow<str> { - "webGPUPipelineLayout".into() - } -} - -pub(crate) struct WebGpuComputePipeline( - pub(crate) wgpu_core::id::ComputePipelineId, -); -impl Resource for WebGpuComputePipeline { - fn name(&self) -> Cow<str> { - "webGPUComputePipeline".into() - } -} - -pub(crate) struct WebGpuRenderPipeline( - pub(crate) wgpu_core::id::RenderPipelineId, -); -impl Resource for WebGpuRenderPipeline { - fn name(&self) -> Cow<str> { - "webGPURenderPipeline".into() - } -} - -pub fn serialize_index_format(format: String) -> wgpu_types::IndexFormat { - match format.as_str() { - "uint16" => wgpu_types::IndexFormat::Uint16, - "uint32" => wgpu_types::IndexFormat::Uint32, - _ => unreachable!(), - } -} - -fn serialize_stencil_operation( - operation: &str, -) -> wgpu_types::StencilOperation { - match operation { - "keep" => wgpu_types::StencilOperation::Keep, - "zero" => wgpu_types::StencilOperation::Zero, - "replace" => wgpu_types::StencilOperation::Replace, - "invert" => wgpu_types::StencilOperation::Invert, - "increment-clamp" => wgpu_types::StencilOperation::IncrementClamp, - "decrement-clamp" => wgpu_types::StencilOperation::DecrementClamp, - "increment-wrap" => wgpu_types::StencilOperation::IncrementWrap, - "decrement-wrap" => wgpu_types::StencilOperation::DecrementWrap, - _ => unreachable!(), - } -} - -fn serialize_stencil_face_state( - state: GpuStencilFaceState, -) -> wgpu_types::StencilFaceState { - wgpu_types::StencilFaceState { - compare: state - .compare - .as_ref() - .map_or(wgpu_types::CompareFunction::Always, |op| { - super::sampler::serialize_compare_function(op) - }), - fail_op: state - .fail_op - .as_ref() - .map_or(wgpu_types::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), - depth_fail_op: state - .depth_fail_op - .as_ref() - .map_or(wgpu_types::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), - pass_op: state - .pass_op - .as_ref() - .map_or(wgpu_types::StencilOperation::Keep, |op| { - serialize_stencil_operation(op) - }), - } -} - -fn serialize_blend_factor(blend_factor: &str) -> wgpu_types::BlendFactor { - match blend_factor { - "zero" => wgpu_types::BlendFactor::Zero, - "one" => wgpu_types::BlendFactor::One, - "src" => wgpu_types::BlendFactor::Src, - "one-minus-src" => wgpu_types::BlendFactor::OneMinusSrc, - "src-alpha" => wgpu_types::BlendFactor::SrcAlpha, - "one-minus-src-alpha" => wgpu_types::BlendFactor::OneMinusSrcAlpha, - "dst" => wgpu_types::BlendFactor::Dst, - "one-minus-dst" => wgpu_types::BlendFactor::OneMinusDst, - "dst-alpha" => wgpu_types::BlendFactor::DstAlpha, - "one-minus-dst-alpha" => wgpu_types::BlendFactor::OneMinusDstAlpha, - "src-alpha-saturated" => wgpu_types::BlendFactor::SrcAlphaSaturated, - "constant" => wgpu_types::BlendFactor::Constant, - "one-minus-constant" => wgpu_types::BlendFactor::OneMinusConstant, - _ => unreachable!(), - } -} - -fn serialize_blend_state(state: GpuBlendState) -> wgpu_types::BlendState { - wgpu_types::BlendState { - alpha: serialize_blend_component(state.alpha), - color: serialize_blend_component(state.color), - } -} - -fn serialize_blend_component( - blend: GpuBlendComponent, -) -> wgpu_types::BlendComponent { - wgpu_types::BlendComponent { - src_factor: blend - .src_factor - .as_ref() - .map_or(wgpu_types::BlendFactor::One, |factor| { - serialize_blend_factor(factor) - }), - dst_factor: blend - .dst_factor - .as_ref() - .map_or(wgpu_types::BlendFactor::Zero, |factor| { - serialize_blend_factor(factor) - }), - operation: match &blend.operation { - Some(operation) => match operation.as_str() { - "add" => wgpu_types::BlendOperation::Add, - "subtract" => wgpu_types::BlendOperation::Subtract, - "reverse-subtract" => wgpu_types::BlendOperation::ReverseSubtract, - "min" => wgpu_types::BlendOperation::Min, - "max" => wgpu_types::BlendOperation::Max, - _ => unreachable!(), - }, - None => wgpu_types::BlendOperation::Add, - }, - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuProgrammableStage { - module: u32, - entry_point: String, - // constants: HashMap<String, GPUPipelineConstantValue> -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateComputePipelineArgs { - device_rid: ResourceId, - label: Option<String>, - layout: Option<u32>, - compute: GpuProgrammableStage, -} - -pub fn op_webgpu_create_compute_pipeline( - state: &mut OpState, - args: CreateComputePipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let pipeline_layout = if let Some(rid) = args.layout { - let id = state - .resource_table - .get::<WebGpuPipelineLayout>(rid) - .ok_or_else(bad_resource_id)?; - Some(id.0) - } else { - None - }; - - let compute_shader_module_resource = state - .resource_table - .get::<super::shader::WebGpuShaderModule>(args.compute.module) - .ok_or_else(bad_resource_id)?; - - let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: args.label.map(Cow::from), - layout: pipeline_layout, - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: compute_shader_module_resource.0, - entry_point: Cow::from(args.compute.entry_point), - // TODO(lucacasonato): support args.compute.constants - }, - }; - let implicit_pipelines = match args.layout { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgpu_core::MAX_BIND_GROUPS], - }), - }; - - let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuComputePipeline(compute_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePipelineGetBindGroupLayoutArgs { - compute_pipeline_rid: ResourceId, - index: u32, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PipelineLayout { - rid: ResourceId, - label: String, - err: Option<WebGpuError>, -} - -pub fn op_webgpu_compute_pipeline_get_bind_group_layout( - state: &mut OpState, - args: ComputePipelineGetBindGroupLayoutArgs, - _: (), -) -> Result<PipelineLayout, AnyError> { - let instance = state.borrow::<super::Instance>(); - let compute_pipeline_resource = state - .resource_table - .get::<WebGpuComputePipeline>(args.compute_pipeline_rid) - .ok_or_else(bad_resource_id)?; - let compute_pipeline = compute_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuPrimitiveState { - topology: Option<String>, - strip_index_format: Option<String>, - front_face: Option<String>, - cull_mode: Option<String>, - clamp_depth: bool, -} - -#[derive(Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -struct GpuBlendComponent { - src_factor: Option<String>, - dst_factor: Option<String>, - operation: Option<String>, -} - -#[derive(Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -struct GpuBlendState { - color: GpuBlendComponent, - alpha: GpuBlendComponent, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuColorTargetState { - format: String, - blend: Option<GpuBlendState>, - write_mask: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuStencilFaceState { - compare: Option<String>, - fail_op: Option<String>, - depth_fail_op: Option<String>, - pass_op: Option<String>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuDepthStencilState { - format: String, - depth_write_enabled: Option<bool>, - depth_compare: Option<String>, - stencil_front: Option<GpuStencilFaceState>, - stencil_back: Option<GpuStencilFaceState>, - stencil_read_mask: Option<u32>, - stencil_write_mask: Option<u32>, - depth_bias: Option<i32>, - depth_bias_slope_scale: Option<f32>, - depth_bias_clamp: Option<f32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexAttribute { - format: GpuVertexFormat, - offset: u64, - shader_location: u32, -} - -#[derive(Deserialize)] -#[serde(rename_all = "lowercase")] -enum GpuVertexFormat { - Uint8x2, - Uint8x4, - Sint8x2, - Sint8x4, - Unorm8x2, - Unorm8x4, - Snorm8x2, - Snorm8x4, - Uint16x2, - Uint16x4, - Sint16x2, - Sint16x4, - Unorm16x2, - Unorm16x4, - Snorm16x2, - Snorm16x4, - Float16x2, - Float16x4, - Float32, - Float32x2, - Float32x3, - Float32x4, - Uint32, - Uint32x2, - Uint32x3, - Uint32x4, - Sint32, - Sint32x2, - Sint32x3, - Sint32x4, - Float64, - Float64x2, - Float64x3, - Float64x4, -} - -impl From<GpuVertexFormat> for wgpu_types::VertexFormat { - fn from(vf: GpuVertexFormat) -> wgpu_types::VertexFormat { - use wgpu_types::VertexFormat; - match vf { - GpuVertexFormat::Uint8x2 => VertexFormat::Uint8x2, - GpuVertexFormat::Uint8x4 => VertexFormat::Uint8x4, - GpuVertexFormat::Sint8x2 => VertexFormat::Sint8x2, - GpuVertexFormat::Sint8x4 => VertexFormat::Sint8x4, - GpuVertexFormat::Unorm8x2 => VertexFormat::Unorm8x2, - GpuVertexFormat::Unorm8x4 => VertexFormat::Unorm8x4, - GpuVertexFormat::Snorm8x2 => VertexFormat::Snorm8x2, - GpuVertexFormat::Snorm8x4 => VertexFormat::Snorm8x4, - GpuVertexFormat::Uint16x2 => VertexFormat::Uint16x2, - GpuVertexFormat::Uint16x4 => VertexFormat::Uint16x4, - GpuVertexFormat::Sint16x2 => VertexFormat::Sint16x2, - GpuVertexFormat::Sint16x4 => VertexFormat::Sint16x4, - GpuVertexFormat::Unorm16x2 => VertexFormat::Unorm16x2, - GpuVertexFormat::Unorm16x4 => VertexFormat::Unorm16x4, - GpuVertexFormat::Snorm16x2 => VertexFormat::Snorm16x2, - GpuVertexFormat::Snorm16x4 => VertexFormat::Snorm16x4, - GpuVertexFormat::Float16x2 => VertexFormat::Float16x2, - GpuVertexFormat::Float16x4 => VertexFormat::Float16x4, - GpuVertexFormat::Float32 => VertexFormat::Float32, - GpuVertexFormat::Float32x2 => VertexFormat::Float32x2, - GpuVertexFormat::Float32x3 => VertexFormat::Float32x3, - GpuVertexFormat::Float32x4 => VertexFormat::Float32x4, - GpuVertexFormat::Uint32 => VertexFormat::Uint32, - GpuVertexFormat::Uint32x2 => VertexFormat::Uint32x2, - GpuVertexFormat::Uint32x3 => VertexFormat::Uint32x3, - GpuVertexFormat::Uint32x4 => VertexFormat::Uint32x4, - GpuVertexFormat::Sint32 => VertexFormat::Sint32, - GpuVertexFormat::Sint32x2 => VertexFormat::Sint32x2, - GpuVertexFormat::Sint32x3 => VertexFormat::Sint32x3, - GpuVertexFormat::Sint32x4 => VertexFormat::Sint32x4, - GpuVertexFormat::Float64 => VertexFormat::Float64, - GpuVertexFormat::Float64x2 => VertexFormat::Float64x2, - GpuVertexFormat::Float64x3 => VertexFormat::Float64x3, - GpuVertexFormat::Float64x4 => VertexFormat::Float64x4, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexBufferLayout { - array_stride: u64, - step_mode: Option<String>, - attributes: Vec<GpuVertexAttribute>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuVertexState { - module: u32, - entry_point: String, - buffers: Option<Vec<Option<GpuVertexBufferLayout>>>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuMultisampleState { - count: Option<u32>, - mask: Option<u64>, // against spec, but future proof - alpha_to_coverage_enabled: Option<bool>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuFragmentState { - targets: Vec<GpuColorTargetState>, - module: u32, - entry_point: String, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateRenderPipelineArgs { - device_rid: ResourceId, - label: Option<String>, - layout: Option<u32>, - vertex: GpuVertexState, - primitive: Option<GpuPrimitiveState>, - depth_stencil: Option<GpuDepthStencilState>, - multisample: Option<GpuMultisampleState>, - fragment: Option<GpuFragmentState>, -} - -pub fn op_webgpu_create_render_pipeline( - state: &mut OpState, - args: CreateRenderPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let layout = if let Some(rid) = args.layout { - let pipeline_layout_resource = state - .resource_table - .get::<WebGpuPipelineLayout>(rid) - .ok_or_else(bad_resource_id)?; - Some(pipeline_layout_resource.0) - } else { - None - }; - - let vertex_shader_module_resource = state - .resource_table - .get::<super::shader::WebGpuShaderModule>(args.vertex.module) - .ok_or_else(bad_resource_id)?; - - let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { - label: args.label.map(Cow::from), - layout, - vertex: wgpu_core::pipeline::VertexState { - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: vertex_shader_module_resource.0, - entry_point: Cow::from(args.vertex.entry_point), - }, - buffers: Cow::from(if let Some(buffers) = args.vertex.buffers { - let mut return_buffers = vec![]; - for buffer in buffers.into_iter().flatten() { - return_buffers.push(wgpu_core::pipeline::VertexBufferLayout { - array_stride: buffer.array_stride, - step_mode: match buffer.step_mode { - Some(step_mode) => match step_mode.as_str() { - "vertex" => wgpu_types::InputStepMode::Vertex, - "instance" => wgpu_types::InputStepMode::Instance, - _ => unreachable!(), - }, - None => wgpu_types::InputStepMode::Vertex, - }, - attributes: Cow::from( - buffer - .attributes - .into_iter() - .map(|attribute| wgpu_types::VertexAttribute { - format: attribute.format.into(), - offset: attribute.offset, - shader_location: attribute.shader_location, - }) - .collect::<Vec<wgpu_types::VertexAttribute>>(), - ), - }); - } - return_buffers - } else { - vec![] - }), - }, - primitive: args.primitive.map_or(Default::default(), |primitive| { - wgpu_types::PrimitiveState { - topology: match primitive.topology { - Some(topology) => match topology.as_str() { - "point-list" => wgpu_types::PrimitiveTopology::PointList, - "line-list" => wgpu_types::PrimitiveTopology::LineList, - "line-strip" => wgpu_types::PrimitiveTopology::LineStrip, - "triangle-list" => wgpu_types::PrimitiveTopology::TriangleList, - "triangle-strip" => wgpu_types::PrimitiveTopology::TriangleStrip, - _ => unreachable!(), - }, - None => wgpu_types::PrimitiveTopology::TriangleList, - }, - strip_index_format: primitive - .strip_index_format - .map(serialize_index_format), - front_face: match primitive.front_face { - Some(front_face) => match front_face.as_str() { - "ccw" => wgpu_types::FrontFace::Ccw, - "cw" => wgpu_types::FrontFace::Cw, - _ => unreachable!(), - }, - None => wgpu_types::FrontFace::Ccw, - }, - cull_mode: match primitive.cull_mode { - Some(cull_mode) => match cull_mode.as_str() { - "none" => None, - "front" => Some(wgpu_types::Face::Front), - "back" => Some(wgpu_types::Face::Back), - _ => unreachable!(), - }, - None => None, - }, - polygon_mode: Default::default(), // native-only - conservative: false, // native-only - clamp_depth: primitive.clamp_depth, - } - }), - depth_stencil: args.depth_stencil.map(|depth_stencil| { - wgpu_types::DepthStencilState { - format: super::texture::serialize_texture_format(&depth_stencil.format) - .unwrap(), - depth_write_enabled: depth_stencil.depth_write_enabled.unwrap_or(false), - depth_compare: match depth_stencil.depth_compare { - Some(depth_compare) => { - super::sampler::serialize_compare_function(&depth_compare) - } - None => wgpu_types::CompareFunction::Always, - }, - stencil: wgpu_types::StencilState { - front: depth_stencil - .stencil_front - .map_or(Default::default(), serialize_stencil_face_state), - back: depth_stencil - .stencil_back - .map_or(Default::default(), serialize_stencil_face_state), - read_mask: depth_stencil.stencil_read_mask.unwrap_or(0xFFFFFFFF), - write_mask: depth_stencil.stencil_write_mask.unwrap_or(0xFFFFFFFF), - }, - bias: wgpu_types::DepthBiasState { - constant: depth_stencil.depth_bias.unwrap_or(0), - slope_scale: depth_stencil.depth_bias_slope_scale.unwrap_or(0.0), - clamp: depth_stencil.depth_bias_clamp.unwrap_or(0.0), - }, - } - }), - multisample: args.multisample.map_or(Default::default(), |multisample| { - wgpu_types::MultisampleState { - count: multisample.count.unwrap_or(1), - mask: multisample.mask.unwrap_or(0xFFFFFFFF), - alpha_to_coverage_enabled: multisample - .alpha_to_coverage_enabled - .unwrap_or(false), - } - }), - fragment: args.fragment.map(|fragment| { - let fragment_shader_module_resource = state - .resource_table - .get::<super::shader::WebGpuShaderModule>(fragment.module) - .ok_or_else(bad_resource_id) - .unwrap(); - - wgpu_core::pipeline::FragmentState { - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: fragment_shader_module_resource.0, - entry_point: Cow::from(fragment.entry_point), - }, - targets: Cow::from( - fragment - .targets - .into_iter() - .map(|target| wgpu_types::ColorTargetState { - format: super::texture::serialize_texture_format(&target.format) - .unwrap(), - blend: target.blend.map(serialize_blend_state), - write_mask: target - .write_mask - .map_or(Default::default(), |mask| { - wgpu_types::ColorWrite::from_bits(mask).unwrap() - }), - }) - .collect::<Vec<wgpu_types::ColorTargetState>>(), - ), - } - }), - }; - - let implicit_pipelines = match args.layout { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; wgpu_core::MAX_BIND_GROUPS], - }), - }; - - let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuRenderPipeline(render_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPipelineGetBindGroupLayoutArgs { - render_pipeline_rid: ResourceId, - index: u32, -} - -pub fn op_webgpu_render_pipeline_get_bind_group_layout( - state: &mut OpState, - args: RenderPipelineGetBindGroupLayoutArgs, - _: (), -) -> Result<PipelineLayout, AnyError> { - let instance = state.borrow::<super::Instance>(); - let render_pipeline_resource = state - .resource_table - .get::<WebGpuRenderPipeline>(args.render_pipeline_rid) - .ok_or_else(bad_resource_id)?; - let render_pipeline = render_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} diff --git a/extensions/webgpu/queue.rs b/extensions/webgpu/queue.rs deleted file mode 100644 index 876c2a207..000000000 --- a/extensions/webgpu/queue.rs +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use std::num::NonZeroU32; - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::AnyError; -use deno_core::OpState; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use serde::Deserialize; - -use super::error::WebGpuResult; - -type WebGpuQueue = super::WebGpuDevice; - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueSubmitArgs { - queue_rid: ResourceId, - command_buffers: Vec<u32>, -} - -pub fn op_webgpu_queue_submit( - state: &mut OpState, - args: QueueSubmitArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let queue_resource = state - .resource_table - .get::<WebGpuQueue>(args.queue_rid) - .ok_or_else(bad_resource_id)?; - let queue = queue_resource.0; - - let mut ids = vec![]; - - for rid in args.command_buffers { - let buffer_resource = state - .resource_table - .get::<super::command_encoder::WebGpuCommandBuffer>(rid) - .ok_or_else(bad_resource_id)?; - ids.push(buffer_resource.0); - } - - let maybe_err = - gfx_select!(queue => instance.queue_submit(queue, &ids)).err(); - - Ok(WebGpuResult::maybe_err(maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuImageDataLayout { - offset: Option<u64>, - bytes_per_row: Option<u32>, - rows_per_image: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueWriteBufferArgs { - queue_rid: ResourceId, - buffer: u32, - buffer_offset: u64, - data_offset: usize, - size: Option<usize>, -} - -pub fn op_webgpu_write_buffer( - state: &mut OpState, - args: QueueWriteBufferArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let instance = state.borrow::<super::Instance>(); - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer) - .ok_or_else(bad_resource_id)?; - let buffer = buffer_resource.0; - let queue_resource = state - .resource_table - .get::<WebGpuQueue>(args.queue_rid) - .ok_or_else(bad_resource_id)?; - let queue = queue_resource.0; - - let data = match args.size { - Some(size) => &zero_copy[args.data_offset..(args.data_offset + size)], - None => &zero_copy[args.data_offset..], - }; - let maybe_err = gfx_select!(queue => instance.queue_write_buffer( - queue, - buffer, - args.buffer_offset, - data - )) - .err(); - - Ok(WebGpuResult::maybe_err(maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueWriteTextureArgs { - queue_rid: ResourceId, - destination: super::command_encoder::GpuImageCopyTexture, - data_layout: GpuImageDataLayout, - size: super::texture::GpuExtent3D, -} - -pub fn op_webgpu_write_texture( - state: &mut OpState, - args: QueueWriteTextureArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let instance = state.borrow::<super::Instance>(); - let texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture) - .ok_or_else(bad_resource_id)?; - let queue_resource = state - .resource_table - .get::<WebGpuQueue>(args.queue_rid) - .ok_or_else(bad_resource_id)?; - let queue = queue_resource.0; - - let destination = wgpu_core::command::ImageCopyTexture { - texture: texture_resource.0, - mip_level: args.destination.mip_level.unwrap_or(0), - origin: args - .destination - .origin - .map_or(Default::default(), |origin| wgpu_types::Origin3d { - x: origin.x.unwrap_or(0), - y: origin.y.unwrap_or(0), - z: origin.z.unwrap_or(0), - }), - }; - let data_layout = wgpu_types::ImageDataLayout { - offset: args.data_layout.offset.unwrap_or(0), - bytes_per_row: NonZeroU32::new(args.data_layout.bytes_per_row.unwrap_or(0)), - rows_per_image: NonZeroU32::new( - args.data_layout.rows_per_image.unwrap_or(0), - ), - }; - - gfx_ok!(queue => instance.queue_write_texture( - queue, - &destination, - &*zero_copy, - &data_layout, - &wgpu_types::Extent3d { - width: args.size.width.unwrap_or(1), - height: args.size.height.unwrap_or(1), - depth_or_array_layers: args.size.depth_or_array_layers.unwrap_or(1), - } - )) -} diff --git a/extensions/webgpu/render_pass.rs b/extensions/webgpu/render_pass.rs deleted file mode 100644 index 81f2e6640..000000000 --- a/extensions/webgpu/render_pass.rs +++ /dev/null @@ -1,688 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::type_error; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuRenderPass( - pub(crate) RefCell<wgpu_core::command::RenderPass>, -); -impl Resource for WebGpuRenderPass { - fn name(&self) -> Cow<str> { - "webGPURenderPass".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetViewportArgs { - render_pass_rid: ResourceId, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, -} - -pub fn op_webgpu_render_pass_set_viewport( - state: &mut OpState, - args: RenderPassSetViewportArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_viewport( - &mut render_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.width, - args.height, - args.min_depth, - args.max_depth, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetScissorRectArgs { - render_pass_rid: ResourceId, - x: u32, - y: u32, - width: u32, - height: u32, -} - -pub fn op_webgpu_render_pass_set_scissor_rect( - state: &mut OpState, - args: RenderPassSetScissorRectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_scissor_rect( - &mut render_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.width, - args.height, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuColor { - pub r: f64, - pub g: f64, - pub b: f64, - pub a: f64, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetBlendConstantArgs { - render_pass_rid: ResourceId, - color: GpuColor, -} - -pub fn op_webgpu_render_pass_set_blend_constant( - state: &mut OpState, - args: RenderPassSetBlendConstantArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant( - &mut render_pass_resource.0.borrow_mut(), - &wgpu_types::Color { - r: args.color.r, - g: args.color.g, - b: args.color.b, - a: args.color.a, - }, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetStencilReferenceArgs { - render_pass_rid: ResourceId, - reference: u32, -} - -pub fn op_webgpu_render_pass_set_stencil_reference( - state: &mut OpState, - args: RenderPassSetStencilReferenceArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_stencil_reference( - &mut render_pass_resource.0.borrow_mut(), - args.reference, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassBeginPipelineStatisticsQueryArgs { - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( - state: &mut OpState, - args: RenderPassBeginPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassEndPipelineStatisticsQueryArgs { - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_end_pipeline_statistics_query( - state: &mut OpState, - args: RenderPassEndPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassWriteTimestampArgs { - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_render_pass_write_timestamp( - state: &mut OpState, - args: RenderPassWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_write_timestamp( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassExecuteBundlesArgs { - render_pass_rid: ResourceId, - bundles: Vec<u32>, -} - -pub fn op_webgpu_render_pass_execute_bundles( - state: &mut OpState, - args: RenderPassExecuteBundlesArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let mut render_bundle_ids = vec![]; - - for rid in &args.bundles { - let render_bundle_resource = state - .resource_table - .get::<super::bundle::WebGpuRenderBundle>(*rid) - .ok_or_else(bad_resource_id)?; - render_bundle_ids.push(render_bundle_resource.0); - } - - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_execute_bundles( - &mut render_pass_resource.0.borrow_mut(), - render_bundle_ids.as_ptr(), - args.bundles.len(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassEndPassArgs { - command_encoder_rid: ResourceId, - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_end_pass( - state: &mut OpState, - args: RenderPassEndPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<super::command_encoder::WebGpuCommandEncoder>( - args.command_encoder_rid, - ) - .ok_or_else(bad_resource_id)?; - let command_encoder = command_encoder_resource.0; - let render_pass_resource = state - .resource_table - .take::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - let render_pass = &render_pass_resource.0.borrow(); - let instance = state.borrow::<super::Instance>(); - - gfx_ok!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetBindGroupArgs { - render_pass_rid: ResourceId, - index: u32, - bind_group: u32, - dynamic_offsets_data: Option<Vec<u32>>, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_render_pass_set_bind_group( - state: &mut OpState, - args: RenderPassSetBindGroupArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - // I know this might look like it can be easily deduplicated, but it can not - // be due to the lifetime of the args.dynamic_offsets_data slice. Because we - // need to use a raw pointer here the slice can be freed before the pointer - // is used in wgpu_render_pass_set_bind_group. See - // https://matrix.to/#/!XFRnMvAfptAHthwBCx:matrix.org/$HgrlhD-Me1DwsGb8UdMu2Hqubgks8s7ILwWRwigOUAg - match args.dynamic_offsets_data { - Some(data) => unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( - &mut render_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - data.as_slice().as_ptr(), - args.dynamic_offsets_data_length, - ); - }, - None => { - let zero_copy = zero_copy.ok_or_else(null_opbuf)?; - let (prefix, data, suffix) = unsafe { zero_copy.align_to::<u32>() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( - &mut render_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - data[args.dynamic_offsets_data_start..].as_ptr(), - args.dynamic_offsets_data_length, - ); - } - } - }; - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassPushDebugGroupArgs { - render_pass_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_render_pass_push_debug_group( - state: &mut OpState, - args: RenderPassPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.group_label).unwrap(); - wgpu_core::command::render_ffi::wgpu_render_pass_push_debug_group( - &mut render_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassPopDebugGroupArgs { - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_pop_debug_group( - state: &mut OpState, - args: RenderPassPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_pop_debug_group( - &mut render_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassInsertDebugMarkerArgs { - render_pass_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_render_pass_insert_debug_marker( - state: &mut OpState, - args: RenderPassInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - unsafe { - let label = std::ffi::CString::new(args.marker_label).unwrap(); - wgpu_core::command::render_ffi::wgpu_render_pass_insert_debug_marker( - &mut render_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetPipelineArgs { - render_pass_rid: ResourceId, - pipeline: u32, -} - -pub fn op_webgpu_render_pass_set_pipeline( - state: &mut OpState, - args: RenderPassSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pipeline_resource = state - .resource_table - .get::<super::pipeline::WebGpuRenderPipeline>(args.pipeline) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_pipeline( - &mut render_pass_resource.0.borrow_mut(), - render_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetIndexBufferArgs { - render_pass_rid: ResourceId, - buffer: u32, - index_format: String, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_render_pass_set_index_buffer( - state: &mut OpState, - args: RenderPassSetIndexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - let size = if let Some(size) = args.size { - Some( - std::num::NonZeroU64::new(size) - .ok_or_else(|| type_error("size must be larger than 0"))?, - ) - } else { - None - }; - - render_pass_resource.0.borrow_mut().set_index_buffer( - buffer_resource.0, - super::pipeline::serialize_index_format(args.index_format), - args.offset, - size, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetVertexBufferArgs { - render_pass_rid: ResourceId, - slot: u32, - buffer: u32, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_render_pass_set_vertex_buffer( - state: &mut OpState, - args: RenderPassSetVertexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - let size = if let Some(size) = args.size { - Some( - std::num::NonZeroU64::new(size) - .ok_or_else(|| type_error("size must be larger than 0"))?, - ) - } else { - None - }; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_vertex_buffer( - &mut render_pass_resource.0.borrow_mut(), - args.slot, - buffer_resource.0, - args.offset, - size, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawArgs { - render_pass_rid: ResourceId, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, -} - -pub fn op_webgpu_render_pass_draw( - state: &mut OpState, - args: RenderPassDrawArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw( - &mut render_pass_resource.0.borrow_mut(), - args.vertex_count, - args.instance_count, - args.first_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndexedArgs { - render_pass_rid: ResourceId, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, -} - -pub fn op_webgpu_render_pass_draw_indexed( - state: &mut OpState, - args: RenderPassDrawIndexedArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed( - &mut render_pass_resource.0.borrow_mut(), - args.index_count, - args.instance_count, - args.first_index, - args.base_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndirectArgs { - render_pass_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_pass_draw_indirect( - state: &mut OpState, - args: RenderPassDrawIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indirect( - &mut render_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndexedIndirectArgs { - render_pass_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_pass_draw_indexed_indirect( - state: &mut OpState, - args: RenderPassDrawIndexedIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer) - .ok_or_else(bad_resource_id)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid) - .ok_or_else(bad_resource_id)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( - &mut render_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} diff --git a/extensions/webgpu/sampler.rs b/extensions/webgpu/sampler.rs deleted file mode 100644 index 7921c4151..000000000 --- a/extensions/webgpu/sampler.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuSampler(pub(crate) wgpu_core::id::SamplerId); -impl Resource for WebGpuSampler { - fn name(&self) -> Cow<str> { - "webGPUSampler".into() - } -} - -fn serialize_address_mode( - address_mode: Option<String>, -) -> wgpu_types::AddressMode { - match address_mode { - Some(address_mode) => match address_mode.as_str() { - "clamp-to-edge" => wgpu_types::AddressMode::ClampToEdge, - "repeat" => wgpu_types::AddressMode::Repeat, - "mirror-repeat" => wgpu_types::AddressMode::MirrorRepeat, - _ => unreachable!(), - }, - None => wgpu_types::AddressMode::ClampToEdge, - } -} - -fn serialize_filter_mode( - filter_mode: Option<String>, -) -> wgpu_types::FilterMode { - match filter_mode { - Some(filter_mode) => match filter_mode.as_str() { - "nearest" => wgpu_types::FilterMode::Nearest, - "linear" => wgpu_types::FilterMode::Linear, - _ => unreachable!(), - }, - None => wgpu_types::FilterMode::Nearest, - } -} - -pub fn serialize_compare_function( - compare: &str, -) -> wgpu_types::CompareFunction { - match compare { - "never" => wgpu_types::CompareFunction::Never, - "less" => wgpu_types::CompareFunction::Less, - "equal" => wgpu_types::CompareFunction::Equal, - "less-equal" => wgpu_types::CompareFunction::LessEqual, - "greater" => wgpu_types::CompareFunction::Greater, - "not-equal" => wgpu_types::CompareFunction::NotEqual, - "greater-equal" => wgpu_types::CompareFunction::GreaterEqual, - "always" => wgpu_types::CompareFunction::Always, - _ => unreachable!(), - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateSamplerArgs { - device_rid: ResourceId, - label: Option<String>, - address_mode_u: Option<String>, - address_mode_v: Option<String>, - address_mode_w: Option<String>, - mag_filter: Option<String>, - min_filter: Option<String>, - mipmap_filter: Option<String>, - lod_min_clamp: Option<f32>, - lod_max_clamp: Option<f32>, - compare: Option<String>, - max_anisotropy: Option<u8>, -} - -pub fn op_webgpu_create_sampler( - state: &mut OpState, - args: CreateSamplerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::SamplerDescriptor { - label: args.label.map(Cow::from), - address_modes: [ - serialize_address_mode(args.address_mode_u), - serialize_address_mode(args.address_mode_v), - serialize_address_mode(args.address_mode_w), - ], - mag_filter: serialize_filter_mode(args.mag_filter), - min_filter: serialize_filter_mode(args.min_filter), - mipmap_filter: serialize_filter_mode(args.mipmap_filter), - lod_min_clamp: args.lod_min_clamp.unwrap_or(0.0), - lod_max_clamp: args.lod_max_clamp.unwrap_or( - wgpu_core::resource::SamplerDescriptor::default().lod_max_clamp, - ), - compare: args - .compare - .as_ref() - .map(|compare| serialize_compare_function(compare)), - anisotropy_clamp: std::num::NonZeroU8::new( - args.max_anisotropy.unwrap_or(0), - ), - border_color: None, // native-only - }; - - gfx_put!(device => instance.device_create_sampler( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuSampler) -} diff --git a/extensions/webgpu/shader.rs b/extensions/webgpu/shader.rs deleted file mode 100644 index f48411969..000000000 --- a/extensions/webgpu/shader.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::null_opbuf; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuShaderModule(pub(crate) wgpu_core::id::ShaderModuleId); -impl Resource for WebGpuShaderModule { - fn name(&self) -> Cow<str> { - "webGPUShaderModule".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateShaderModuleArgs { - device_rid: ResourceId, - label: Option<String>, - code: Option<String>, - _source_map: Option<()>, // not yet implemented -} - -pub fn op_webgpu_create_shader_module( - state: &mut OpState, - args: CreateShaderModuleArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let source = match args.code { - Some(code) => { - wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::from(code)) - } - None => wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::from(unsafe { - match &zero_copy { - Some(zero_copy) => { - let (prefix, data, suffix) = zero_copy.align_to::<u32>(); - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - data - } - None => return Err(null_opbuf()), - } - })), - }; - - let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { - label: args.label.map(Cow::from), - flags: wgpu_types::ShaderFlags::all(), - }; - - gfx_put!(device => instance.device_create_shader_module( - device, - &descriptor, - source, - std::marker::PhantomData - ) => state, WebGpuShaderModule) -} diff --git a/extensions/webgpu/texture.rs b/extensions/webgpu/texture.rs deleted file mode 100644 index 587ac46a7..000000000 --- a/extensions/webgpu/texture.rs +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::error::{bad_resource_id, not_supported}; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; -pub(crate) struct WebGpuTexture(pub(crate) wgpu_core::id::TextureId); -impl Resource for WebGpuTexture { - fn name(&self) -> Cow<str> { - "webGPUTexture".into() - } -} - -pub(crate) struct WebGpuTextureView(pub(crate) wgpu_core::id::TextureViewId); -impl Resource for WebGpuTextureView { - fn name(&self) -> Cow<str> { - "webGPUTextureView".into() - } -} - -pub fn serialize_texture_format( - format: &str, -) -> Result<wgpu_types::TextureFormat, AnyError> { - Ok(match format { - // 8-bit formats - "r8unorm" => wgpu_types::TextureFormat::R8Unorm, - "r8snorm" => wgpu_types::TextureFormat::R8Snorm, - "r8uint" => wgpu_types::TextureFormat::R8Uint, - "r8sint" => wgpu_types::TextureFormat::R8Sint, - - // 16-bit formats - "r16uint" => wgpu_types::TextureFormat::R16Uint, - "r16sint" => wgpu_types::TextureFormat::R16Sint, - "r16float" => wgpu_types::TextureFormat::R16Float, - "rg8unorm" => wgpu_types::TextureFormat::Rg8Unorm, - "rg8snorm" => wgpu_types::TextureFormat::Rg8Snorm, - "rg8uint" => wgpu_types::TextureFormat::Rg8Uint, - "rg8sint" => wgpu_types::TextureFormat::Rg8Sint, - - // 32-bit formats - "r32uint" => wgpu_types::TextureFormat::R32Uint, - "r32sint" => wgpu_types::TextureFormat::R32Sint, - "r32float" => wgpu_types::TextureFormat::R32Float, - "rg16uint" => wgpu_types::TextureFormat::Rg16Uint, - "rg16sint" => wgpu_types::TextureFormat::Rg16Sint, - "rg16float" => wgpu_types::TextureFormat::Rg16Float, - "rgba8unorm" => wgpu_types::TextureFormat::Rgba8Unorm, - "rgba8unorm-srgb" => wgpu_types::TextureFormat::Rgba8UnormSrgb, - "rgba8snorm" => wgpu_types::TextureFormat::Rgba8Snorm, - "rgba8uint" => wgpu_types::TextureFormat::Rgba8Uint, - "rgba8sint" => wgpu_types::TextureFormat::Rgba8Sint, - "bgra8unorm" => wgpu_types::TextureFormat::Bgra8Unorm, - "bgra8unorm-srgb" => wgpu_types::TextureFormat::Bgra8UnormSrgb, - // Packed 32-bit formats - "rgb9e5ufloat" => return Err(not_supported()), // wgpu#967 - "rgb10a2unorm" => wgpu_types::TextureFormat::Rgb10a2Unorm, - "rg11b10ufloat" => wgpu_types::TextureFormat::Rg11b10Float, - - // 64-bit formats - "rg32uint" => wgpu_types::TextureFormat::Rg32Uint, - "rg32sint" => wgpu_types::TextureFormat::Rg32Sint, - "rg32float" => wgpu_types::TextureFormat::Rg32Float, - "rgba16uint" => wgpu_types::TextureFormat::Rgba16Uint, - "rgba16sint" => wgpu_types::TextureFormat::Rgba16Sint, - "rgba16float" => wgpu_types::TextureFormat::Rgba16Float, - - // 128-bit formats - "rgba32uint" => wgpu_types::TextureFormat::Rgba32Uint, - "rgba32sint" => wgpu_types::TextureFormat::Rgba32Sint, - "rgba32float" => wgpu_types::TextureFormat::Rgba32Float, - - // Depth and stencil formats - "stencil8" => return Err(not_supported()), // wgpu#967 - "depth16unorm" => return Err(not_supported()), // wgpu#967 - "depth24plus" => wgpu_types::TextureFormat::Depth24Plus, - "depth24plus-stencil8" => wgpu_types::TextureFormat::Depth24PlusStencil8, - "depth32float" => wgpu_types::TextureFormat::Depth32Float, - - // BC compressed formats usable if "texture-compression-bc" is both - // supported by the device/user agent and enabled in requestDevice. - "bc1-rgba-unorm" => wgpu_types::TextureFormat::Bc1RgbaUnorm, - "bc1-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc1RgbaUnormSrgb, - "bc2-rgba-unorm" => wgpu_types::TextureFormat::Bc2RgbaUnorm, - "bc2-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc2RgbaUnormSrgb, - "bc3-rgba-unorm" => wgpu_types::TextureFormat::Bc3RgbaUnorm, - "bc3-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc3RgbaUnormSrgb, - "bc4-r-unorm" => wgpu_types::TextureFormat::Bc4RUnorm, - "bc4-r-snorm" => wgpu_types::TextureFormat::Bc4RSnorm, - "bc5-rg-unorm" => wgpu_types::TextureFormat::Bc5RgUnorm, - "bc5-rg-snorm" => wgpu_types::TextureFormat::Bc5RgSnorm, - "bc6h-rgb-ufloat" => wgpu_types::TextureFormat::Bc6hRgbUfloat, - "bc6h-rgb-float" => wgpu_types::TextureFormat::Bc6hRgbSfloat, // wgpu#967 - "bc7-rgba-unorm" => wgpu_types::TextureFormat::Bc7RgbaUnorm, - "bc7-rgba-unorm-srgb" => wgpu_types::TextureFormat::Bc7RgbaUnormSrgb, - - // "depth24unorm-stencil8" extension - "depth24unorm-stencil8" => return Err(not_supported()), // wgpu#967 - - // "depth32float-stencil8" extension - "depth32float-stencil8" => return Err(not_supported()), // wgpu#967 - _ => unreachable!(), - }) -} - -pub fn serialize_dimension( - dimension: &str, -) -> wgpu_types::TextureViewDimension { - match dimension { - "1d" => wgpu_types::TextureViewDimension::D1, - "2d" => wgpu_types::TextureViewDimension::D2, - "2d-array" => wgpu_types::TextureViewDimension::D2Array, - "cube" => wgpu_types::TextureViewDimension::Cube, - "cube-array" => wgpu_types::TextureViewDimension::CubeArray, - "3d" => wgpu_types::TextureViewDimension::D3, - _ => unreachable!(), - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuExtent3D { - pub width: Option<u32>, - pub height: Option<u32>, - pub depth_or_array_layers: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateTextureArgs { - device_rid: ResourceId, - label: Option<String>, - size: GpuExtent3D, - mip_level_count: Option<u32>, - sample_count: Option<u32>, - dimension: Option<String>, - format: String, - usage: u32, -} - -pub fn op_webgpu_create_texture( - state: &mut OpState, - args: CreateTextureArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid) - .ok_or_else(bad_resource_id)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::TextureDescriptor { - label: args.label.map(Cow::from), - size: wgpu_types::Extent3d { - width: args.size.width.unwrap_or(1), - height: args.size.height.unwrap_or(1), - depth_or_array_layers: args.size.depth_or_array_layers.unwrap_or(1), - }, - mip_level_count: args.mip_level_count.unwrap_or(1), - sample_count: args.sample_count.unwrap_or(1), - dimension: match args.dimension { - Some(dimension) => match dimension.as_str() { - "1d" => wgpu_types::TextureDimension::D1, - "2d" => wgpu_types::TextureDimension::D2, - "3d" => wgpu_types::TextureDimension::D3, - _ => unreachable!(), - }, - None => wgpu_types::TextureDimension::D2, - }, - format: serialize_texture_format(&args.format)?, - usage: wgpu_types::TextureUsage::from_bits(args.usage).unwrap(), - }; - - gfx_put!(device => instance.device_create_texture( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuTexture) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateTextureViewArgs { - texture_rid: ResourceId, - label: Option<String>, - format: Option<String>, - dimension: Option<String>, - aspect: Option<String>, - base_mip_level: Option<u32>, - mip_level_count: Option<u32>, - base_array_layer: Option<u32>, - array_layer_count: Option<u32>, -} - -pub fn op_webgpu_create_texture_view( - state: &mut OpState, - args: CreateTextureViewArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let texture_resource = state - .resource_table - .get::<WebGpuTexture>(args.texture_rid) - .ok_or_else(bad_resource_id)?; - let texture = texture_resource.0; - - let descriptor = wgpu_core::resource::TextureViewDescriptor { - label: args.label.map(Cow::from), - format: args - .format - .map(|s| serialize_texture_format(&s)) - .transpose()?, - dimension: args.dimension.map(|s| serialize_dimension(&s)), - range: wgpu_types::ImageSubresourceRange { - aspect: match args.aspect { - Some(aspect) => match aspect.as_str() { - "all" => wgpu_types::TextureAspect::All, - "stencil-only" => wgpu_types::TextureAspect::StencilOnly, - "depth-only" => wgpu_types::TextureAspect::DepthOnly, - _ => unreachable!(), - }, - None => wgpu_types::TextureAspect::All, - }, - base_mip_level: args.base_mip_level.unwrap_or(0), - mip_level_count: std::num::NonZeroU32::new( - args.mip_level_count.unwrap_or(0), - ), - base_array_layer: args.base_array_layer.unwrap_or(0), - array_layer_count: std::num::NonZeroU32::new( - args.array_layer_count.unwrap_or(0), - ), - }, - }; - - gfx_put!(texture => instance.texture_create_view( - texture, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuTextureView) -} diff --git a/extensions/webgpu/webgpu.idl b/extensions/webgpu/webgpu.idl deleted file mode 100644 index b2a536f2f..000000000 --- a/extensions/webgpu/webgpu.idl +++ /dev/null @@ -1,1057 +0,0 @@ -interface mixin GPUObjectBase { - attribute USVString? label; -}; - -dictionary GPUObjectDescriptorBase { - USVString label; -}; - -[Exposed=Window] -interface GPUSupportedLimits { - readonly attribute unsigned long maxTextureDimension1D; - readonly attribute unsigned long maxTextureDimension2D; - readonly attribute unsigned long maxTextureDimension3D; - readonly attribute unsigned long maxTextureArrayLayers; - readonly attribute unsigned long maxBindGroups; - readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout; - readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout; - readonly attribute unsigned long maxSampledTexturesPerShaderStage; - readonly attribute unsigned long maxSamplersPerShaderStage; - readonly attribute unsigned long maxStorageBuffersPerShaderStage; - readonly attribute unsigned long maxStorageTexturesPerShaderStage; - readonly attribute unsigned long maxUniformBuffersPerShaderStage; - readonly attribute unsigned long maxUniformBufferBindingSize; - readonly attribute unsigned long maxStorageBufferBindingSize; - readonly attribute unsigned long minUniformBufferOffsetAlignment; - readonly attribute unsigned long minStorageBufferOffsetAlignment; - readonly attribute unsigned long maxVertexBuffers; - readonly attribute unsigned long maxVertexAttributes; - readonly attribute unsigned long maxVertexBufferArrayStride; - readonly attribute unsigned long maxInterStageShaderComponents; - readonly attribute unsigned long maxComputeWorkgroupStorageSize; - readonly attribute unsigned long maxComputeWorkgroupInvocations; - readonly attribute unsigned long maxComputePerDimensionDispatchSize; -}; - -[Exposed=Window] -interface GPUSupportedFeatures { - readonly setlike<DOMString>; -}; - -enum GPUPredefinedColorSpace { - "srgb", -}; - -interface mixin NavigatorGPU { - [SameObject] readonly attribute GPU gpu; -}; -Navigator includes NavigatorGPU; -WorkerNavigator includes NavigatorGPU; - -[Exposed=(Window, DedicatedWorker)] -interface GPU { - Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {}); -}; - -dictionary GPURequestAdapterOptions { - GPUPowerPreference powerPreference; - boolean forceSoftware = false; -}; - -enum GPUPowerPreference { - "low-power", - "high-performance" -}; - -[Exposed=Window] -interface GPUAdapter { - readonly attribute DOMString name; - [SameObject] readonly attribute GPUSupportedFeatures features; - [SameObject] readonly attribute GPUSupportedLimits limits; - readonly attribute boolean isSoftware; - - Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {}); -}; - -dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { - sequence<GPUFeatureName> requiredFeatures = []; - record<DOMString, GPUSize32> requiredLimits = {}; -}; - -enum GPUFeatureName { - "depth-clamping", - "depth24unorm-stencil8", - "depth32float-stencil8", - "pipeline-statistics-query", - "texture-compression-bc", - "timestamp-query", -}; - -[Exposed=(Window, DedicatedWorker), Serializable] -interface GPUDevice : EventTarget { - [SameObject] readonly attribute GPUSupportedFeatures features; - [SameObject] readonly attribute GPUSupportedLimits limits; - - [SameObject] readonly attribute GPUQueue queue; - - undefined destroy(); - - GPUBuffer createBuffer(GPUBufferDescriptor descriptor); - GPUTexture createTexture(GPUTextureDescriptor descriptor); - GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); - - GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); - GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor); - GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); - - GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); - GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); - GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); - Promise<GPUComputePipeline> createComputePipelineAsync(GPUComputePipelineDescriptor descriptor); - Promise<GPURenderPipeline> createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor); - - GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); - GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); - - GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor); -}; -GPUDevice includes GPUObjectBase; - -[Exposed=Window, Serializable] -interface GPUBuffer { - Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); - ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); - undefined unmap(); - - undefined destroy(); -}; -GPUBuffer includes GPUObjectBase; - -dictionary GPUBufferDescriptor : GPUObjectDescriptorBase { - required GPUSize64 size; - required GPUBufferUsageFlags usage; - boolean mappedAtCreation = false; -}; - -typedef [EnforceRange] unsigned long GPUBufferUsageFlags; -[Exposed=Window] -interface GPUBufferUsage { - const GPUFlagsConstant MAP_READ = 0x0001; - const GPUFlagsConstant MAP_WRITE = 0x0002; - const GPUFlagsConstant COPY_SRC = 0x0004; - const GPUFlagsConstant COPY_DST = 0x0008; - const GPUFlagsConstant INDEX = 0x0010; - const GPUFlagsConstant VERTEX = 0x0020; - const GPUFlagsConstant UNIFORM = 0x0040; - const GPUFlagsConstant STORAGE = 0x0080; - const GPUFlagsConstant INDIRECT = 0x0100; - const GPUFlagsConstant QUERY_RESOLVE = 0x0200; -}; - -typedef [EnforceRange] unsigned long GPUMapModeFlags; -[Exposed=Window] -interface GPUMapMode { - const GPUFlagsConstant READ = 0x0001; - const GPUFlagsConstant WRITE = 0x0002; -}; - -[Exposed=Window, Serializable] -interface GPUTexture { - GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); - - undefined destroy(); -}; -GPUTexture includes GPUObjectBase; - -dictionary GPUTextureDescriptor : GPUObjectDescriptorBase { - required GPUExtent3D size; - GPUIntegerCoordinate mipLevelCount = 1; - GPUSize32 sampleCount = 1; - GPUTextureDimension dimension = "2d"; - required GPUTextureFormat format; - required GPUTextureUsageFlags usage; -}; - -enum GPUTextureDimension { - "1d", - "2d", - "3d", -}; - -typedef [EnforceRange] unsigned long GPUTextureUsageFlags; -[Exposed=Window] -interface GPUTextureUsage { - const GPUFlagsConstant COPY_SRC = 0x01; - const GPUFlagsConstant COPY_DST = 0x02; - const GPUFlagsConstant SAMPLED = 0x04; - const GPUFlagsConstant STORAGE = 0x08; - const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; -}; - -[Exposed=Window] -interface GPUTextureView { -}; -GPUTextureView includes GPUObjectBase; - -dictionary GPUTextureViewDescriptor : GPUObjectDescriptorBase { - GPUTextureFormat format; - GPUTextureViewDimension dimension; - GPUTextureAspect aspect = "all"; - GPUIntegerCoordinate baseMipLevel = 0; - GPUIntegerCoordinate mipLevelCount; - GPUIntegerCoordinate baseArrayLayer = 0; - GPUIntegerCoordinate arrayLayerCount; -}; - -enum GPUTextureViewDimension { - "1d", - "2d", - "2d-array", - "cube", - "cube-array", - "3d" -}; - -enum GPUTextureAspect { - "all", - "stencil-only", - "depth-only" -}; - -enum GPUTextureFormat { - // 8-bit formats - "r8unorm", - "r8snorm", - "r8uint", - "r8sint", - - // 16-bit formats - "r16uint", - "r16sint", - "r16float", - "rg8unorm", - "rg8snorm", - "rg8uint", - "rg8sint", - - // 32-bit formats - "r32uint", - "r32sint", - "r32float", - "rg16uint", - "rg16sint", - "rg16float", - "rgba8unorm", - "rgba8unorm-srgb", - "rgba8snorm", - "rgba8uint", - "rgba8sint", - "bgra8unorm", - "bgra8unorm-srgb", - // Packed 32-bit formats - "rgb9e5ufloat", - "rgb10a2unorm", - "rg11b10ufloat", - - // 64-bit formats - "rg32uint", - "rg32sint", - "rg32float", - "rgba16uint", - "rgba16sint", - "rgba16float", - - // 128-bit formats - "rgba32uint", - "rgba32sint", - "rgba32float", - - // Depth and stencil formats - "stencil8", - "depth16unorm", - "depth24plus", - "depth24plus-stencil8", - "depth32float", - - // BC compressed formats usable if "texture-compression-bc" is both - // supported by the device/user agent and enabled in requestDevice. - "bc1-rgba-unorm", - "bc1-rgba-unorm-srgb", - "bc2-rgba-unorm", - "bc2-rgba-unorm-srgb", - "bc3-rgba-unorm", - "bc3-rgba-unorm-srgb", - "bc4-r-unorm", - "bc4-r-snorm", - "bc5-rg-unorm", - "bc5-rg-snorm", - "bc6h-rgb-ufloat", - "bc6h-rgb-float", - "bc7-rgba-unorm", - "bc7-rgba-unorm-srgb", - - // "depth24unorm-stencil8" feature - "depth24unorm-stencil8", - - // "depth32float-stencil8" feature - "depth32float-stencil8", -}; - -[Exposed=Window] -interface GPUSampler { -}; -GPUSampler includes GPUObjectBase; - -dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase { - GPUAddressMode addressModeU = "clamp-to-edge"; - GPUAddressMode addressModeV = "clamp-to-edge"; - GPUAddressMode addressModeW = "clamp-to-edge"; - GPUFilterMode magFilter = "nearest"; - GPUFilterMode minFilter = "nearest"; - GPUFilterMode mipmapFilter = "nearest"; - float lodMinClamp = 0; - float lodMaxClamp = 0xffffffff; // TODO: What should this be? Was Number.MAX_VALUE. - GPUCompareFunction compare; - [Clamp] unsigned short maxAnisotropy = 1; -}; - -enum GPUAddressMode { - "clamp-to-edge", - "repeat", - "mirror-repeat" -}; - -enum GPUFilterMode { - "nearest", - "linear" -}; - -enum GPUCompareFunction { - "never", - "less", - "equal", - "less-equal", - "greater", - "not-equal", - "greater-equal", - "always" -}; - -[Exposed=Window, Serializable] -interface GPUBindGroupLayout { -}; -GPUBindGroupLayout includes GPUObjectBase; - -dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase { - required sequence<GPUBindGroupLayoutEntry> entries; -}; - -typedef [EnforceRange] unsigned long GPUShaderStageFlags; -[Exposed=Window] -interface GPUShaderStage { - const GPUFlagsConstant VERTEX = 0x1; - const GPUFlagsConstant FRAGMENT = 0x2; - const GPUFlagsConstant COMPUTE = 0x4; -}; - -dictionary GPUBindGroupLayoutEntry { - required GPUIndex32 binding; - required GPUShaderStageFlags visibility; - - GPUBufferBindingLayout buffer; - GPUSamplerBindingLayout sampler; - GPUTextureBindingLayout texture; - GPUStorageTextureBindingLayout storageTexture; -}; - -enum GPUBufferBindingType { - "uniform", - "storage", - "read-only-storage", -}; - -dictionary GPUBufferBindingLayout { - GPUBufferBindingType type = "uniform"; - boolean hasDynamicOffset = false; - GPUSize64 minBindingSize = 0; -}; - -enum GPUSamplerBindingType { - "filtering", - "non-filtering", - "comparison", -}; - -dictionary GPUSamplerBindingLayout { - GPUSamplerBindingType type = "filtering"; -}; - -enum GPUTextureSampleType { - "float", - "unfilterable-float", - "depth", - "sint", - "uint", -}; - -dictionary GPUTextureBindingLayout { - GPUTextureSampleType sampleType = "float"; - GPUTextureViewDimension viewDimension = "2d"; - boolean multisampled = false; -}; - -enum GPUStorageTextureAccess { - "read-only", - "write-only", -}; - -dictionary GPUStorageTextureBindingLayout { - required GPUStorageTextureAccess access; - required GPUTextureFormat format; - GPUTextureViewDimension viewDimension = "2d"; -}; - -[Exposed=Window] -interface GPUBindGroup { -}; -GPUBindGroup includes GPUObjectBase; - -dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase { - required GPUBindGroupLayout layout; - required sequence<GPUBindGroupEntry> entries; -}; - -typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource; - -dictionary GPUBindGroupEntry { - required GPUIndex32 binding; - required GPUBindingResource resource; -}; - -dictionary GPUBufferBinding { - required GPUBuffer buffer; - GPUSize64 offset = 0; - GPUSize64 size; -}; - -[Exposed=Window, Serializable] -interface GPUPipelineLayout { -}; -GPUPipelineLayout includes GPUObjectBase; - -dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase { - required sequence<GPUBindGroupLayout> bindGroupLayouts; -}; - -[Exposed=Window, Serializable] -interface GPUShaderModule { - Promise<GPUCompilationInfo> compilationInfo(); -}; -GPUShaderModule includes GPUObjectBase; - -dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { - required USVString code; - object sourceMap; -}; - -enum GPUCompilationMessageType { - "error", - "warning", - "info" -}; - -[Exposed=Window, Serializable] -interface GPUCompilationMessage { - readonly attribute DOMString message; - readonly attribute GPUCompilationMessageType type; - readonly attribute unsigned long long lineNum; - readonly attribute unsigned long long linePos; - readonly attribute unsigned long long offset; - readonly attribute unsigned long long length; -}; - -[Exposed=Window, Serializable] -interface GPUCompilationInfo { - readonly attribute FrozenArray<GPUCompilationMessage> messages; -}; - -dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase { - GPUPipelineLayout layout; -}; - -interface mixin GPUPipelineBase { - GPUBindGroupLayout getBindGroupLayout(unsigned long index); -}; - -dictionary GPUProgrammableStage { - required GPUShaderModule module; - required USVString entryPoint; - record<USVString, GPUPipelineConstantValue> constants; -}; - -typedef double GPUPipelineConstantValue; // May represent WGSL’s bool, f32, i32, u32. - -[Exposed=Window, Serializable] -interface GPUComputePipeline { -}; -GPUComputePipeline includes GPUObjectBase; -GPUComputePipeline includes GPUPipelineBase; - -dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase { - required GPUProgrammableStage compute; -}; - -[Exposed=Window, Serializable] -interface GPURenderPipeline { -}; -GPURenderPipeline includes GPUObjectBase; -GPURenderPipeline includes GPUPipelineBase; - -dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { - required GPUVertexState vertex; - GPUPrimitiveState primitive = {}; - GPUDepthStencilState depthStencil; - GPUMultisampleState multisample = {}; - GPUFragmentState fragment; -}; - -enum GPUPrimitiveTopology { - "point-list", - "line-list", - "line-strip", - "triangle-list", - "triangle-strip" -}; - -dictionary GPUPrimitiveState { - GPUPrimitiveTopology topology = "triangle-list"; - GPUIndexFormat stripIndexFormat; - GPUFrontFace frontFace = "ccw"; - GPUCullMode cullMode = "none"; - - // Enable depth clamping (requires "depth-clamping" feature) - boolean clampDepth = false; -}; - -enum GPUFrontFace { - "ccw", - "cw" -}; - -enum GPUCullMode { - "none", - "front", - "back" -}; - -dictionary GPUMultisampleState { - GPUSize32 count = 1; - GPUSampleMask mask = 0xFFFFFFFF; - boolean alphaToCoverageEnabled = false; -}; - -dictionary GPUFragmentState: GPUProgrammableStage { - required sequence<GPUColorTargetState> targets; -}; - -dictionary GPUColorTargetState { - required GPUTextureFormat format; - - GPUBlendState blend; - GPUColorWriteFlags writeMask = 0xF; // GPUColorWrite.ALL -}; - -dictionary GPUBlendState { - required GPUBlendComponent color; - required GPUBlendComponent alpha; -}; - -typedef [EnforceRange] unsigned long GPUColorWriteFlags; -[Exposed=Window] -interface GPUColorWrite { - const GPUFlagsConstant RED = 0x1; - const GPUFlagsConstant GREEN = 0x2; - const GPUFlagsConstant BLUE = 0x4; - const GPUFlagsConstant ALPHA = 0x8; - const GPUFlagsConstant ALL = 0xF; -}; - -dictionary GPUBlendComponent { - GPUBlendFactor srcFactor = "one"; - GPUBlendFactor dstFactor = "zero"; - GPUBlendOperation operation = "add"; -}; - -enum 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 { - "add", - "subtract", - "reverse-subtract", - "min", - "max" -}; - -dictionary GPUDepthStencilState { - required GPUTextureFormat format; - - boolean depthWriteEnabled = false; - GPUCompareFunction depthCompare = "always"; - - GPUStencilFaceState stencilFront = {}; - GPUStencilFaceState stencilBack = {}; - - GPUStencilValue stencilReadMask = 0xFFFFFFFF; - GPUStencilValue stencilWriteMask = 0xFFFFFFFF; - - GPUDepthBias depthBias = 0; - float depthBiasSlopeScale = 0; - float depthBiasClamp = 0; -}; - -dictionary GPUStencilFaceState { - GPUCompareFunction compare = "always"; - GPUStencilOperation failOp = "keep"; - GPUStencilOperation depthFailOp = "keep"; - GPUStencilOperation passOp = "keep"; -}; - -enum GPUStencilOperation { - "keep", - "zero", - "replace", - "invert", - "increment-clamp", - "decrement-clamp", - "increment-wrap", - "decrement-wrap" -}; - -enum GPUIndexFormat { - "uint16", - "uint32" -}; - -enum GPUVertexFormat { - "uint8x2", - "uint8x4", - "sint8x2", - "sint8x4", - "unorm8x2", - "unorm8x4", - "snorm8x2", - "snorm8x4", - "uint16x2", - "uint16x4", - "sint16x2", - "sint16x4", - "unorm16x2", - "unorm16x4", - "snorm16x2", - "snorm16x4", - "float16x2", - "float16x4", - "float32", - "float32x2", - "float32x3", - "float32x4", - "uint32", - "uint32x2", - "uint32x3", - "uint32x4", - "sint32", - "sint32x2", - "sint32x3", - "sint32x4", -}; - -enum GPUInputStepMode { - "vertex", - "instance" -}; - -dictionary GPUVertexState: GPUProgrammableStage { - sequence<GPUVertexBufferLayout?> buffers = []; -}; - -dictionary GPUVertexBufferLayout { - required GPUSize64 arrayStride; - GPUInputStepMode stepMode = "vertex"; - required sequence<GPUVertexAttribute> attributes; -}; - -dictionary GPUVertexAttribute { - required GPUVertexFormat format; - required GPUSize64 offset; - - required GPUIndex32 shaderLocation; -}; - -[Exposed=Window] -interface GPUCommandBuffer { - readonly attribute Promise<double> executionTime; -}; -GPUCommandBuffer includes GPUObjectBase; - -dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase { -}; - -[Exposed=Window] -interface GPUCommandEncoder { - GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); - GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); - - undefined copyBufferToBuffer( - GPUBuffer source, - GPUSize64 sourceOffset, - GPUBuffer destination, - GPUSize64 destinationOffset, - GPUSize64 size); - - undefined copyBufferToTexture( - GPUImageCopyBuffer source, - GPUImageCopyTexture destination, - GPUExtent3D copySize); - - undefined copyTextureToBuffer( - GPUImageCopyTexture source, - GPUImageCopyBuffer destination, - GPUExtent3D copySize); - - undefined copyTextureToTexture( - GPUImageCopyTexture source, - GPUImageCopyTexture destination, - GPUExtent3D copySize); - - undefined pushDebugGroup(USVString groupLabel); - undefined popDebugGroup(); - undefined insertDebugMarker(USVString markerLabel); - - undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); - - undefined resolveQuerySet( - GPUQuerySet querySet, - GPUSize32 firstQuery, - GPUSize32 queryCount, - GPUBuffer destination, - GPUSize64 destinationOffset); - - GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {}); -}; -GPUCommandEncoder includes GPUObjectBase; - -dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase { - boolean measureExecutionTime = false; - - // TODO: reusability flag? -}; - -dictionary GPUImageDataLayout { - GPUSize64 offset = 0; - GPUSize32 bytesPerRow; - GPUSize32 rowsPerImage; -}; - -dictionary GPUImageCopyBuffer : GPUImageDataLayout { - required GPUBuffer buffer; -}; - -dictionary GPUImageCopyTexture { - required GPUTexture texture; - GPUIntegerCoordinate mipLevel = 0; - GPUOrigin3D origin = {}; - GPUTextureAspect aspect = "all"; -}; - -interface mixin GPUProgrammablePassEncoder { - undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup, - optional sequence<GPUBufferDynamicOffset> dynamicOffsets = []); - - undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup, - Uint32Array dynamicOffsetsData, - GPUSize64 dynamicOffsetsDataStart, - GPUSize32 dynamicOffsetsDataLength); - - undefined pushDebugGroup(USVString groupLabel); - undefined popDebugGroup(); - undefined insertDebugMarker(USVString markerLabel); -}; - -[Exposed=Window] -interface GPUComputePassEncoder { - undefined setPipeline(GPUComputePipeline pipeline); - undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1); - undefined dispatchIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); - - undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); - undefined endPipelineStatisticsQuery(); - - undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); - - undefined endPass(); -}; -GPUComputePassEncoder includes GPUObjectBase; -GPUComputePassEncoder includes GPUProgrammablePassEncoder; - -dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase { -}; - -interface mixin GPURenderEncoderBase { - undefined setPipeline(GPURenderPipeline pipeline); - - undefined setIndexBuffer(GPUBuffer buffer, GPUIndexFormat indexFormat, optional GPUSize64 offset = 0, optional GPUSize64 size); - undefined setVertexBuffer(GPUIndex32 slot, GPUBuffer buffer, optional GPUSize64 offset = 0, optional GPUSize64 size); - - undefined draw(GPUSize32 vertexCount, optional GPUSize32 instanceCount = 1, - optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0); - undefined drawIndexed(GPUSize32 indexCount, optional GPUSize32 instanceCount = 1, - optional GPUSize32 firstIndex = 0, - optional GPUSignedOffset32 baseVertex = 0, - optional GPUSize32 firstInstance = 0); - - undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); - undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); -}; - -[Exposed=Window] -interface GPURenderPassEncoder { - undefined setViewport(float x, float y, - float width, float height, - float minDepth, float maxDepth); - - undefined setScissorRect(GPUIntegerCoordinate x, GPUIntegerCoordinate y, - GPUIntegerCoordinate width, GPUIntegerCoordinate height); - - undefined setBlendConstant(GPUColor color); - undefined setStencilReference(GPUStencilValue reference); - - undefined beginOcclusionQuery(GPUSize32 queryIndex); - undefined endOcclusionQuery(); - - undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); - undefined endPipelineStatisticsQuery(); - - undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex); - - undefined executeBundles(sequence<GPURenderBundle> bundles); - undefined endPass(); -}; -GPURenderPassEncoder includes GPUObjectBase; -GPURenderPassEncoder includes GPUProgrammablePassEncoder; -GPURenderPassEncoder includes GPURenderEncoderBase; - -dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase { - required sequence<GPURenderPassColorAttachment> colorAttachments; - GPURenderPassDepthStencilAttachment depthStencilAttachment; - GPUQuerySet occlusionQuerySet; -}; - -dictionary GPURenderPassColorAttachment { - required GPUTextureView view; - GPUTextureView resolveTarget; - - required (GPULoadOp or GPUColor) loadValue; - required GPUStoreOp storeOp; -}; - -dictionary GPURenderPassDepthStencilAttachment { - required GPUTextureView view; - - required (GPULoadOp or float) depthLoadValue; - required GPUStoreOp depthStoreOp; - boolean depthReadOnly = false; - - required (GPULoadOp or GPUStencilValue) stencilLoadValue; - required GPUStoreOp stencilStoreOp; - boolean stencilReadOnly = false; -}; - -enum GPULoadOp { - "load" -}; - -enum GPUStoreOp { - "store", - "discard" -}; - -[Exposed=Window] -interface GPURenderBundle { -}; -GPURenderBundle includes GPUObjectBase; - -dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase { -}; - -[Exposed=Window] -interface GPURenderBundleEncoder { - GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); -}; -GPURenderBundleEncoder includes GPUObjectBase; -GPURenderBundleEncoder includes GPUProgrammablePassEncoder; -GPURenderBundleEncoder includes GPURenderEncoderBase; - -dictionary GPURenderBundleEncoderDescriptor : GPUObjectDescriptorBase { - required sequence<GPUTextureFormat> colorFormats; - GPUTextureFormat depthStencilFormat; - GPUSize32 sampleCount = 1; -}; - -[Exposed=Window] -interface GPUQueue { - undefined submit(sequence<GPUCommandBuffer> commandBuffers); - - Promise<undefined> onSubmittedWorkDone(); - - undefined writeBuffer( - GPUBuffer buffer, - GPUSize64 bufferOffset, - [AllowShared] BufferSource data, - optional GPUSize64 dataOffset = 0, - optional GPUSize64 size); - - undefined writeTexture( - GPUImageCopyTexture destination, - [AllowShared] BufferSource data, - GPUImageDataLayout dataLayout, - GPUExtent3D size); -}; -GPUQueue includes GPUObjectBase; - -[Exposed=Window] -interface GPUQuerySet { - undefined destroy(); -}; -GPUQuerySet includes GPUObjectBase; - -dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase { - required GPUQueryType type; - required GPUSize32 count; - sequence<GPUPipelineStatisticName> pipelineStatistics = []; -}; - -enum GPUQueryType { - "occlusion", - "pipeline-statistics", - "timestamp" -}; - -enum GPUPipelineStatisticName { - "vertex-shader-invocations", - "clipper-invocations", - "clipper-primitives-out", - "fragment-shader-invocations", - "compute-shader-invocations" -}; - -enum GPUDeviceLostReason { - "destroyed", -}; - -[Exposed=Window] -interface GPUDeviceLostInfo { - readonly attribute (GPUDeviceLostReason or undefined) reason; - readonly attribute DOMString message; -}; - -partial interface GPUDevice { - readonly attribute Promise<GPUDeviceLostInfo> lost; -}; - -enum GPUErrorFilter { - "out-of-memory", - "validation" -}; - -[Exposed=Window] -interface GPUOutOfMemoryError { - constructor(); -}; - -[Exposed=Window] -interface GPUValidationError { - constructor(DOMString message); - readonly attribute DOMString message; -}; - -typedef (GPUOutOfMemoryError or GPUValidationError) GPUError; - -partial interface GPUDevice { - undefined pushErrorScope(GPUErrorFilter filter); - Promise<GPUError?> popErrorScope(); -}; - -[ - Exposed=(Window, DedicatedWorker) -] -interface GPUUncapturedErrorEvent : Event { - constructor( - DOMString type, - GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict - ); - [SameObject] readonly attribute GPUError error; -}; - -dictionary GPUUncapturedErrorEventInit : EventInit { - required GPUError error; -}; - -partial interface GPUDevice { - [Exposed=(Window, DedicatedWorker)] - attribute EventHandler onuncapturederror; -}; - -typedef [EnforceRange] unsigned long GPUBufferDynamicOffset; -typedef [EnforceRange] unsigned long GPUStencilValue; -typedef [EnforceRange] unsigned long GPUSampleMask; -typedef [EnforceRange] long GPUDepthBias; - -typedef [EnforceRange] unsigned long long GPUSize64; -typedef [EnforceRange] unsigned long GPUIntegerCoordinate; -typedef [EnforceRange] unsigned long GPUIndex32; -typedef [EnforceRange] unsigned long GPUSize32; -typedef [EnforceRange] long GPUSignedOffset32; - -typedef unsigned long GPUFlagsConstant; - -dictionary GPUColorDict { - required double r; - required double g; - required double b; - required double a; -}; -typedef (sequence<double> or GPUColorDict) GPUColor; - -dictionary GPUOrigin2DDict { - GPUIntegerCoordinate x = 0; - GPUIntegerCoordinate y = 0; -}; -typedef (sequence<GPUIntegerCoordinate> or GPUOrigin2DDict) GPUOrigin2D; - -dictionary GPUOrigin3DDict { - GPUIntegerCoordinate x = 0; - GPUIntegerCoordinate y = 0; - GPUIntegerCoordinate z = 0; -}; -typedef (sequence<GPUIntegerCoordinate> or GPUOrigin3DDict) GPUOrigin3D; - -dictionary GPUExtent3DDict { - required GPUIntegerCoordinate width; - GPUIntegerCoordinate height = 1; - GPUIntegerCoordinate depthOrArrayLayers = 1; -}; -typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D; |