New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@luma.gl/webgpu

Package Overview
Dependencies
Maintainers
0
Versions
111
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@luma.gl/webgpu - npm Package Compare versions

Comparing version 9.1.0-beta.8 to 9.1.0-beta.9

4

dist/adapter/helpers/get-bind-group.d.ts

@@ -11,5 +11,3 @@ import type { ComputeShaderLayout, BindingDeclaration, Binding } from '@luma.gl/core';

export declare function getBindGroup(device: GPUDevice, bindGroupLayout: GPUBindGroupLayout, shaderLayout: ComputeShaderLayout, bindings: Record<string, Binding>): GPUBindGroup;
export declare function getShaderLayoutBinding(shaderLayout: ComputeShaderLayout, bindingName: string, options?: {
ignoreWarnings?: boolean;
}): BindingDeclaration | null;
export declare function getShaderLayoutBinding(shaderLayout: ComputeShaderLayout, bindingName: string): BindingDeclaration | null;
//# sourceMappingURL=get-bind-group.d.ts.map

@@ -26,5 +26,5 @@ // luma.gl

}
export function getShaderLayoutBinding(shaderLayout, bindingName, options) {
export function getShaderLayoutBinding(shaderLayout, bindingName) {
const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());
if (!bindingLayout && !options?.ignoreWarnings) {
if (!bindingLayout) {
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();

@@ -46,5 +46,3 @@ }

// TODO - hack to automatically bind samplers to supplied texture default samplers
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
ignoreWarnings: true
});
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`);
if (bindingLayout) {

@@ -51,0 +49,0 @@ entries.push(getBindGroupEntry(value, bindingLayout.location, { sampler: true }));

@@ -127,7 +127,7 @@ // luma.gl

if (!attribute) {
log.warn(`Supplied attribute not present in shader layout: ${name}`)();
log.warn(`Unknown attribute ${name}`)();
return null;
}
if (attributeNames.has(name)) {
throw new Error(`Found multiple entries for attribute: ${name}`);
throw new Error(`Duplicate attribute ${name}`);
}

@@ -134,0 +134,0 @@ attributeNames.add(name);

@@ -15,3 +15,2 @@ import type { Binding, RenderPass, VertexArray } from '@luma.gl/core';

private _bindGroup;
get [Symbol.toStringTag](): string;
constructor(device: WebGPUDevice, props: RenderPipelineProps);

@@ -18,0 +17,0 @@ destroy(): void;

@@ -18,5 +18,2 @@ // luma.gl MIT license

_bindGroup = null;
get [Symbol.toStringTag]() {
return 'WebGPURenderPipeline';
}
constructor(device, props) {

@@ -55,8 +52,2 @@ super(device, props);

setBindings(bindings) {
// Invalidate the cached bind group if any value has changed
for (const [name, binding] of Object.entries(bindings)) {
if (this._bindings[name] !== binding) {
this._bindGroup = null;
}
}
Object.assign(this._bindings, bindings);

@@ -119,13 +110,2 @@ }

};
// Populate color targets
// TODO - at the moment blend and write mask are only set on the first target
const targets = [];
if (this.props.colorAttachmentFormats) {
for (const format of this.props.colorAttachmentFormats) {
targets.push(format ? { format: getWebGPUTextureFormat(format) } : null);
}
}
else {
targets.push({ format: getWebGPUTextureFormat(this.device.preferredColorFormat) });
}
// Set up the fragment stage

@@ -135,3 +115,8 @@ const fragment = {

entryPoint: this.props.fragmentEntryPoint || 'main',
targets
targets: [
{
// TODO exclamation mark hack!
format: getWebGPUTextureFormat(this.device.getCanvasContext().format)
}
]
};

@@ -147,9 +132,2 @@ // Create a partially populated descriptor

};
// Set depth format if required, defaulting to the preferred depth format
const depthFormat = this.props.depthStencilAttachmentFormat || this.device.preferredDepthFormat;
if (this.props.parameters.depthWriteEnabled) {
descriptor.depthStencil = {
format: getWebGPUTextureFormat(depthFormat)
};
}
// Set parameters on the descriptor

@@ -156,0 +134,0 @@ applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);

@@ -1,2 +0,2 @@

import type { DepthStencilTextureFormat, CanvasContextProps } from '@luma.gl/core';
import type { Texture, TextureFormat, CanvasContextProps } from '@luma.gl/core';
import { CanvasContext } from '@luma.gl/core';

@@ -13,3 +13,7 @@ import { WebGPUDevice } from "./webgpu-device.js";

readonly device: WebGPUDevice;
readonly handle: GPUCanvasContext;
readonly gpuCanvasContext: GPUCanvasContext;
/** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
readonly format: TextureFormat;
/** Default stencil format for depth textures */
readonly depthStencilFormat: TextureFormat;
private depthStencilAttachment;

@@ -21,7 +25,5 @@ get [Symbol.toStringTag](): string;

/** Update framebuffer with properly resized "swap chain" texture views */
getCurrentFramebuffer(options?: {
depthStencilFormat?: DepthStencilTextureFormat | false;
}): WebGPUFramebuffer;
getCurrentFramebuffer(): WebGPUFramebuffer;
/** Resizes and updates render targets if necessary */
updateSize(size: [newWidth: number, newHeight: number]): void;
update(): void;
resize(options?: {

@@ -35,4 +37,4 @@ width?: number;

/** We build render targets on demand (i.e. not when size changes but when about to render) */
_createDepthStencilAttachment(depthStencilFormat: DepthStencilTextureFormat): WebGPUTexture;
_createDepthStencilAttachment(): Texture;
}
//# sourceMappingURL=webgpu-canvas-context.d.ts.map
// luma.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import { CanvasContext, Texture, log } from '@luma.gl/core';
import { CanvasContext, log } from '@luma.gl/core';
import { getWebGPUTextureFormat } from "./helpers/convert-texture-format.js";
import { WebGPUFramebuffer } from "./resources/webgpu-framebuffer.js";

@@ -13,3 +14,7 @@ /**

device;
handle;
gpuCanvasContext;
/** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
format = navigator.gpu.getPreferredCanvasFormat();
/** Default stencil format for depth textures */
depthStencilFormat = 'depth24plus';
depthStencilAttachment = null;

@@ -22,28 +27,34 @@ get [Symbol.toStringTag]() {

this.device = device;
// Base class constructor cannot access derived methods/fields, so we need to call these functions in the subclass constructor
// TODO - ugly hack to trigger first resize
this.width = -1;
this.height = -1;
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
this.updateSize([this.drawingBufferWidth, this.drawingBufferHeight]);
// @ts-ignore TODO - we don't handle OffscreenRenderingContext.
this.gpuCanvasContext = this.canvas.getContext('webgpu');
// TODO this has been replaced
// this.format = this.gpuCanvasContext.getPreferredFormat(adapter);
this.format = 'bgra8unorm';
}
/** Destroy any textures produced while configured and remove the context configuration. */
destroy() {
this.handle.unconfigure();
this.gpuCanvasContext.unconfigure();
}
/** Update framebuffer with properly resized "swap chain" texture views */
getCurrentFramebuffer(options = {
depthStencilFormat: 'depth24plus'
}) {
getCurrentFramebuffer() {
// Ensure the canvas context size is updated
this.update();
// Wrap the current canvas context texture in a luma.gl texture
// const currentColorAttachment = this.device.createTexture({
// id: 'default-render-target',
// handle: this.gpuCanvasContext.getCurrentTexture(),
// format: this.format,
// width: this.width,
// height: this.height
// });
// Wrap the current canvas context texture in a luma.gl texture
const currentColorAttachment = this.getCurrentTexture();
// TODO - temporary debug code
if (currentColorAttachment.width !== this.drawingBufferWidth ||
currentColorAttachment.height !== this.drawingBufferHeight) {
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
this.drawingBufferWidth = currentColorAttachment.width;
this.drawingBufferHeight = currentColorAttachment.height;
log.log(1, `${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)();
}
this.width = currentColorAttachment.width;
this.height = currentColorAttachment.height;
// Resize the depth stencil attachment
if (options?.depthStencilFormat) {
this._createDepthStencilAttachment(options?.depthStencilFormat);
}
this._createDepthStencilAttachment();
return new WebGPUFramebuffer(this.device, {

@@ -55,28 +66,35 @@ colorAttachments: [currentColorAttachment],

/** Resizes and updates render targets if necessary */
updateSize(size) {
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
update() {
const oldWidth = this.width;
const oldHeight = this.height;
const [newWidth, newHeight] = this.getPixelSize();
const sizeChanged = newWidth !== oldWidth || newHeight !== oldHeight;
if (sizeChanged) {
this.width = newWidth;
this.height = newHeight;
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
}
// Reconfigure the canvas size.
// https://www.w3.org/TR/webgpu/#canvas-configuration
this.gpuCanvasContext.configure({
device: this.device.handle,
format: getWebGPUTextureFormat(this.format),
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
log.log(1, `${this} Resized ${oldWidth}x${oldHeight} => ${newWidth}x${newHeight}px`)();
}
// Reconfigure the canvas size.
// https://www.w3.org/TR/webgpu/#canvas-configuration
this.handle.configure({
device: this.device.handle,
format: this.device.preferredColorFormat,
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
}
resize(options) {
this.update();
if (!this.device.handle)
return;
if (this.props.autoResize) {
return;
}
// Resize browser context .
if (this.canvas) {
const devicePixelRatio = this.getDevicePixelRatio(options?.useDevicePixels);
this._setDevicePixelRatio(devicePixelRatio, options);
this.setDevicePixelRatio(devicePixelRatio, options);
return;

@@ -89,15 +107,15 @@ }

id: `${this.id}#color-texture`,
handle: this.handle.getCurrentTexture(),
format: this.device.preferredColorFormat
handle: this.gpuCanvasContext.getCurrentTexture(),
format: this.format
});
}
/** We build render targets on demand (i.e. not when size changes but when about to render) */
_createDepthStencilAttachment(depthStencilFormat) {
_createDepthStencilAttachment() {
if (!this.depthStencilAttachment) {
this.depthStencilAttachment = this.device.createTexture({
id: `${this.id}#depth-stencil-texture`,
usage: Texture.RENDER_ATTACHMENT,
format: depthStencilFormat,
width: this.drawingBufferWidth,
height: this.drawingBufferHeight
format: this.depthStencilFormat,
width: this.width,
height: this.height,
usage: GPUTextureUsage.RENDER_ATTACHMENT
});

@@ -104,0 +122,0 @@ }

@@ -17,8 +17,8 @@ import type { DeviceInfo, DeviceLimits, DeviceTextureFormatCapabilities, CanvasContextProps, BufferProps, SamplerProps, ShaderProps, Texture, TextureProps, ExternalTextureProps, FramebufferProps, RenderPipelineProps, ComputePipelineProps, RenderPassProps, ComputePassProps, VertexArrayProps, TransformFeedback, TransformFeedbackProps, QuerySet, QuerySetProps, DeviceProps } from '@luma.gl/core';

export declare class WebGPUDevice extends Device {
/** type of this device */
readonly type = "webgpu";
/** The underlying WebGPU device */
readonly handle: GPUDevice;
/** type of this device */
readonly type = "webgpu";
readonly preferredColorFormat: "rgba8unorm" | "bgra8unorm";
readonly preferredDepthFormat = "depth24plus";
readonly adapter: GPUAdapter;
readonly adapterInfo: GPUAdapterInfo;
readonly features: DeviceFeatures;

@@ -31,8 +31,6 @@ readonly info: DeviceInfo;

}>;
renderPass: WebGPURenderPass | null;
canvasContext: WebGPUCanvasContext | null;
private _isLost;
commandEncoder: GPUCommandEncoder | null;
readonly adapter: GPUAdapter;
readonly adapterInfo: GPUAdapterInfo;
renderPass: WebGPURenderPass | null;
constructor(props: DeviceProps, device: GPUDevice, adapter: GPUAdapter, adapterInfo: GPUAdapterInfo);

@@ -39,0 +37,0 @@ destroy(): void;

@@ -21,8 +21,10 @@ // luma.gl

export class WebGPUDevice extends Device {
/** type of this device */
type = 'webgpu';
/** The underlying WebGPU device */
handle;
/** type of this device */
type = 'webgpu';
preferredColorFormat = navigator.gpu.getPreferredCanvasFormat();
preferredDepthFormat = 'depth24plus';
/* The underlying WebGPU adapter */
adapter;
/* The underlying WebGPU adapter's info */
adapterInfo;
features;

@@ -32,11 +34,6 @@ info;

lost;
renderPass = null;
canvasContext;
canvasContext = null;
_isLost = false;
// canvasContext: WebGPUCanvasContext | null = null;
commandEncoder = null;
/* The underlying WebGPU adapter */
adapter;
/* The underlying WebGPU adapter's info */
adapterInfo;
renderPass = null;
constructor(props, device, adapter, adapterInfo) {

@@ -43,0 +40,0 @@ super({ ...props, id: props.id || 'webgpu-device' });

@@ -691,7 +691,7 @@ (function webpackUniversalModuleDefinition(root, factory) {

}
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
function getShaderLayoutBinding(shaderLayout, bindingName) {
const bindingLayout = shaderLayout.bindings.find(
(binding) => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase()
);
if (!bindingLayout && !options?.ignoreWarnings) {
if (!bindingLayout) {
import_core7.log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();

@@ -708,5 +708,3 @@ }

}
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
ignoreWarnings: true
});
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`);
if (bindingLayout) {

@@ -816,7 +814,7 @@ entries.push(getBindGroupEntry(value, bindingLayout.location, { sampler: true }));

if (!attribute) {
import_core8.log.warn(`Supplied attribute not present in shader layout: ${name}`)();
import_core8.log.warn(`Unknown attribute ${name}`)();
return null;
}
if (attributeNames.has(name)) {
throw new Error(`Found multiple entries for attribute: ${name}`);
throw new Error(`Duplicate attribute ${name}`);
}

@@ -837,5 +835,2 @@ attributeNames.add(name);

_bindGroup = null;
get [Symbol.toStringTag]() {
return "WebGPURenderPipeline";
}
constructor(device, props) {

@@ -872,7 +867,2 @@ super(device, props);

setBindings(bindings) {
for (const [name, binding] of Object.entries(bindings)) {
if (this._bindings[name] !== binding) {
this._bindGroup = null;
}
}
Object.assign(this._bindings, bindings);

@@ -933,14 +923,11 @@ }

};
const targets = [];
if (this.props.colorAttachmentFormats) {
for (const format of this.props.colorAttachmentFormats) {
targets.push(format ? { format: getWebGPUTextureFormat(format) } : null);
}
} else {
targets.push({ format: getWebGPUTextureFormat(this.device.preferredColorFormat) });
}
const fragment = {
module: this.props.fs.handle,
entryPoint: this.props.fragmentEntryPoint || "main",
targets
targets: [
{
// TODO exclamation mark hack!
format: getWebGPUTextureFormat(this.device.getCanvasContext().format)
}
]
};

@@ -955,8 +942,2 @@ const descriptor = {

};
const depthFormat = this.props.depthStencilAttachmentFormat || this.device.preferredDepthFormat;
if (this.props.parameters.depthWriteEnabled) {
descriptor.depthStencil = {
format: getWebGPUTextureFormat(depthFormat)
};
}
applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);

@@ -1384,3 +1365,7 @@ return descriptor;

device;
handle;
gpuCanvasContext;
/** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
format = navigator.gpu.getPreferredCanvasFormat();
/** Default stencil format for depth textures */
depthStencilFormat = "depth24plus";
depthStencilAttachment = null;

@@ -1393,26 +1378,19 @@ get [Symbol.toStringTag]() {

this.device = device;
this.width = -1;
this.height = -1;
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
this.updateSize([this.drawingBufferWidth, this.drawingBufferHeight]);
this.gpuCanvasContext = this.canvas.getContext("webgpu");
this.format = "bgra8unorm";
}
/** Destroy any textures produced while configured and remove the context configuration. */
destroy() {
this.handle.unconfigure();
this.gpuCanvasContext.unconfigure();
}
/** Update framebuffer with properly resized "swap chain" texture views */
getCurrentFramebuffer(options = {
depthStencilFormat: "depth24plus"
}) {
getCurrentFramebuffer() {
this.update();
const currentColorAttachment = this.getCurrentTexture();
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
this.drawingBufferWidth = currentColorAttachment.width;
this.drawingBufferHeight = currentColorAttachment.height;
import_core15.log.log(
1,
`${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`
)();
}
if (options?.depthStencilFormat) {
this._createDepthStencilAttachment(options?.depthStencilFormat);
}
this.width = currentColorAttachment.width;
this.height = currentColorAttachment.height;
this._createDepthStencilAttachment();
return new WebGPUFramebuffer(this.device, {

@@ -1424,25 +1402,32 @@ colorAttachments: [currentColorAttachment],

/** Resizes and updates render targets if necessary */
updateSize(size) {
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
update() {
const oldWidth = this.width;
const oldHeight = this.height;
const [newWidth, newHeight] = this.getPixelSize();
const sizeChanged = newWidth !== oldWidth || newHeight !== oldHeight;
if (sizeChanged) {
this.width = newWidth;
this.height = newHeight;
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
}
this.gpuCanvasContext.configure({
device: this.device.handle,
format: getWebGPUTextureFormat(this.format),
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
import_core15.log.log(1, `${this} Resized ${oldWidth}x${oldHeight} => ${newWidth}x${newHeight}px`)();
}
this.handle.configure({
device: this.device.handle,
format: this.device.preferredColorFormat,
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
}
resize(options) {
this.update();
if (!this.device.handle)
return;
if (this.props.autoResize) {
return;
}
if (this.canvas) {
const devicePixelRatio = this.getDevicePixelRatio(options?.useDevicePixels);
this._setDevicePixelRatio(devicePixelRatio, options);
this.setDevicePixelRatio(devicePixelRatio, options);
return;

@@ -1455,15 +1440,15 @@ }

id: `${this.id}#color-texture`,
handle: this.handle.getCurrentTexture(),
format: this.device.preferredColorFormat
handle: this.gpuCanvasContext.getCurrentTexture(),
format: this.format
});
}
/** We build render targets on demand (i.e. not when size changes but when about to render) */
_createDepthStencilAttachment(depthStencilFormat) {
_createDepthStencilAttachment() {
if (!this.depthStencilAttachment) {
this.depthStencilAttachment = this.device.createTexture({
id: `${this.id}#depth-stencil-texture`,
usage: import_core15.Texture.RENDER_ATTACHMENT,
format: depthStencilFormat,
width: this.drawingBufferWidth,
height: this.drawingBufferHeight
format: this.depthStencilFormat,
width: this.width,
height: this.height,
usage: GPUTextureUsage.RENDER_ATTACHMENT
});

@@ -1497,8 +1482,10 @@ }

var WebGPUDevice = class extends import_core17.Device {
/** type of this device */
type = "webgpu";
/** The underlying WebGPU device */
handle;
/** type of this device */
type = "webgpu";
preferredColorFormat = navigator.gpu.getPreferredCanvasFormat();
preferredDepthFormat = "depth24plus";
/* The underlying WebGPU adapter */
adapter;
/* The underlying WebGPU adapter's info */
adapterInfo;
features;

@@ -1508,11 +1495,6 @@ info;

lost;
renderPass = null;
canvasContext;
canvasContext = null;
_isLost = false;
// canvasContext: WebGPUCanvasContext | null = null;
commandEncoder = null;
/* The underlying WebGPU adapter */
adapter;
/* The underlying WebGPU adapter's info */
adapterInfo;
renderPass = null;
constructor(props, device, adapter, adapterInfo) {

@@ -1519,0 +1501,0 @@ super({ ...props, id: props.id || "webgpu-device" });

@@ -7,8 +7,8 @@ (function webpackUniversalModuleDefinition(root, factory) {

else root['luma'] = factory();})(globalThis, function () {
var __exports__=(()=>{var Se=Object.create;var R=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var Pe=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var Ae=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),Ge=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},W=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ce(e))!Be.call(n,i)&&i!==t&&R(n,i,{get:()=>e[i],enumerable:!(r=Ee(e,i))||r.enumerable});return n},O=(n,e,t)=>(W(n,e,"default"),t&&W(t,e,"default")),d=(n,e,t)=>(t=n!=null?Se(Pe(n)):{},W(e||!n||!n.__esModule?R(t,"default",{value:n,enumerable:!0}):t,n)),Te=n=>W(R({},"__esModule",{value:!0}),n);var o=Ae((Oe,te)=>{te.exports=globalThis.luma});var F={};Ge(F,{WebGPUBuffer:()=>b,WebGPUDevice:()=>S,WebGPUSampler:()=>p,WebGPUShader:()=>P,WebGPUTexture:()=>C,webgpuAdapter:()=>be});O(F,d(o(),1));var f=d(o(),1);var X=d(o(),1);var M=d(o(),1);function _e(n){return n.byteLength||n.data?.byteLength||0}var b=class extends M.Buffer{device;handle;byteLength;constructor(e,t){super(e,t),this.device=e,this.byteLength=_e(t);let r=Boolean(t.data),i=Math.ceil(this.byteLength/4)*4;this.handle=this.props.handle||this.device.handle.createBuffer({size:i,usage:this.props.usage||GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,mappedAtCreation:this.props.mappedAtCreation||r,label:this.props.id}),t.data&&this._writeMapped(t.data),r&&!t.mappedAtCreation&&this.handle.unmap()}destroy(){this.handle?.destroy(),this.handle=null}write(e,t=0){this.device.handle.queue.writeBuffer(this.handle,t,e.buffer,e.byteOffset,e.byteLength)}async readAsync(e=0,t=this.byteLength){let r=new b(this.device,{usage:M.Buffer.MAP_READ|M.Buffer.COPY_DST,byteLength:t}),i=this.device.handle.createCommandEncoder();i.copyBufferToBuffer(this.handle,e,r.handle,0,t),this.device.handle.queue.submit([i.finish()]),await r.handle.mapAsync(GPUMapMode.READ,e,t);let s=r.handle.getMappedRange().slice(0);return r.handle.unmap(),r.destroy(),new Uint8Array(s)}_writeMapped(e){let t=this.handle.getMappedRange();new e.constructor(t).set(e)}mapAsync(e,t=0,r){return this.handle.mapAsync(e,t,r)}getMappedRange(e=0,t){return this.handle.getMappedRange(e,t)}unmap(){this.handle.unmap()}};var v=d(o(),1);function E(n){if(n.includes("webgl"))throw new Error("webgl-only format");return n}var re=d(o(),1),p=class extends re.Sampler{device;handle;constructor(e,t){super(e,t),this.device=e;let r={...this.props,mipmapFilter:void 0};t.type!=="comparison-sampler"&&delete r.compare,t.mipmapFilter&&t.mipmapFilter!=="none"&&(r.mipmapFilter=t.mipmapFilter),this.handle=this.handle||this.device.handle.createSampler(r),this.handle.label=this.props.id}destroy(){this.handle=null}};var ne=d(o(),1),_=class extends ne.TextureView{device;handle;texture;constructor(e,t){super(e,t),this.device=e,this.texture=t.texture,this.handle=this.handle||this.texture.handle.createView({format:t.format||this.texture.format,dimension:t.dimension||this.texture.dimension,aspect:t.aspect,baseMipLevel:t.baseMipLevel,mipLevelCount:t.mipLevelCount,baseArrayLayer:t.baseArrayLayer,arrayLayerCount:t.arrayLayerCount}),this.handle.label=this.props.id}destroy(){this.handle=null}};var De={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},C=class extends v.Texture{device;handle;sampler;view;constructor(e,t){super(e,t),this.device=e;let r={...this.props};t.data&&(r.data=t.data),this.initialize(r)}destroy(){this.handle?.destroy(),this.handle=null}createView(e){return new _(this.device,{...e,texture:this})}initialize(e){this.handle=this.props.handle||this.createHandle(),this.handle.label||=this.id,this.props.data&&(v.Texture.isExternalImage(this.props.data)?this.copyExternalImage({image:this.props.data}):this.setData({data:this.props.data})),this.width=this.handle.width,this.height=this.handle.height,this.sampler=e.sampler instanceof p?e.sampler:new p(this.device,e.sampler||{}),this.view=new _(this.device,{...this.props,texture:this})}createHandle(){let e=this.props.width||this.props.data?.width||1,t=this.props.height||this.props.data?.height||1;return this.device.handle.createTexture({label:this.id,size:{width:e,height:t,depthOrArrayLayers:this.depth},usage:this.props.usage||v.Texture.TEXTURE|v.Texture.COPY_DST,dimension:De[this.dimension],format:E(this.format),mipLevelCount:this.mipLevels,sampleCount:this.props.samples})}createGPUTextureView(){return this.handle.createView({label:this.id})}setSampler(e){return this.sampler=e instanceof p?e:new p(this.device,e),this}setTexture1DData(e){throw new Error("not implemented")}setTexture2DData(e,t,r){throw new Error("not implemented")}setTexture3DData(e,t,r){throw new Error("not implemented")}setTextureCubeData(e,t){throw new Error("not implemented")}setTextureArrayData(e){throw new Error("not implemented")}setTextureCubeArrayData(e){throw new Error("not implemented")}setData(e){if(ArrayBuffer.isView(e.data)){let t=new Uint8ClampedArray(e.data.buffer),r=new ImageData(t,this.width,this.height);return this.copyExternalImage({image:r})}throw new Error("Texture.setData: Use CommandEncoder to upload data to texture in WebGPU")}copyExternalImage(e){let t=v.Texture.getExternalImageSize(e.image),r={...v.Texture.defaultCopyExternalImageOptions,...t,...e},{image:i,sourceX:s,sourceY:a,width:l,height:c,depth:h,mipLevel:g,x:u,y:T,z:J,aspect:xe,colorSpace:we,premultipliedAlpha:ye,flipY:ve}=r;return this.device.handle.queue.copyExternalImageToTexture({source:i,origin:[s,a],flipY:ve},{texture:this.handle,origin:[u,T,J],mipLevel:g,aspect:xe,colorSpace:we,premultipliedAlpha:ye},[l,c,h]),{width:l,height:c}}};var ie=d(o(),1);var U=class extends ie.ExternalTexture{device;handle;sampler;constructor(e,t){super(e,t),this.device=e,this.handle=this.props.handle||this.device.handle.importExternalTexture({source:t.source,colorSpace:t.colorSpace}),this.sampler=null}destroy(){this.handle=null}setSampler(e){return this.sampler=e instanceof p?e:new p(this.device,e),this}};var D=d(o(),1),P=class extends D.Shader{device;handle;constructor(e,t){super(e,t),this.device=e;let r=t.source.includes("#version");if(this.props.language==="glsl"||r)throw new Error("GLSL shaders are not supported in WebGPU");this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||this.device.handle.createShaderModule({code:t.source}),this.device.handle.popErrorScope().then(i=>{i&&D.log.error(`${this} creation failed:
"${i.message}"`,this,this.props.source)()}),this.handle.label=this.props.id,this._checkCompilationError()}get asyncCompilationStatus(){return this.getCompilationInfo().then(()=>this.compilationStatus)}async _checkCompilationError(){let e=await this.getCompilationInfo(),t=Boolean(e.find(r=>r.type==="error"));this.compilationStatus=t?"error":"success",this.debugShader(),this.compilationStatus==="error"&&D.log.error("Shader compilation error",e)()}destroy(){this.handle=null}async getCompilationInfo(){return(await this.handle.getCompilationInfo()).messages}};var w=d(o(),1);function m(n){return n.depthStencil=n.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},n.depthStencil}function k(n){return m(n).stencilFront}function V(n){return m(n).stencilBack}var Le={cullMode:(n,e,t)=>{t.primitive=t.primitive||{},t.primitive.cullMode=e},frontFace:(n,e,t)=>{t.primitive=t.primitive||{},t.primitive.frontFace=e},depthWriteEnabled:(n,e,t)=>{let r=m(t);r.depthWriteEnabled=e},depthCompare:(n,e,t)=>{let r=m(t);r.depthCompare=e},depthFormat:(n,e,t)=>{let r=m(t);r.format=e},depthBias:(n,e,t)=>{let r=m(t);r.depthBias=e},depthBiasSlopeScale:(n,e,t)=>{let r=m(t);r.depthBiasSlopeScale=e},depthBiasClamp:(n,e,t)=>{let r=m(t);r.depthBiasClamp=e},stencilReadMask:(n,e,t)=>{let r=m(t);r.stencilReadMask=e},stencilWriteMask:(n,e,t)=>{let r=m(t);r.stencilWriteMask=e},stencilCompare:(n,e,t)=>{let r=k(t),i=V(t);r.compare=e,i.compare=e},stencilPassOperation:(n,e,t)=>{let r=k(t),i=V(t);r.passOp=e,i.passOp=e},stencilFailOperation:(n,e,t)=>{let r=k(t),i=V(t);r.failOp=e,i.failOp=e},stencilDepthFailOperation:(n,e,t)=>{let r=k(t),i=V(t);r.depthFailOp=e,i.depthFailOp=e},sampleCount:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.count=e},sampleMask:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.mask=e},sampleAlphaToCoverageEnabled:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.alphaToCoverageEnabled=e},colorMask:(n,e,t)=>{let r=se(t);r[0].writeMask=e},blendColorOperation:(n,e,t)=>{se(t)}},Ie={primitive:{cullMode:"back",topology:"triangle-list"},vertex:{module:void 0,entryPoint:"main"},fragment:{module:void 0,entryPoint:"main",targets:[]},layout:"auto"};function ae(n,e={}){Object.assign(n,{...Ie,...n}),Fe(n,e)}function Fe(n,e){for(let[t,r]of Object.entries(e)){let i=Le[t];if(!i)throw new Error(`Illegal parameter ${t}`);i(t,r,n)}}function se(n){if(n.fragment.targets=n.fragment?.targets||[],!Array.isArray(n.fragment?.targets))throw new Error("colorstate");return n.fragment?.targets?.length===0&&n.fragment.targets?.push({}),n.fragment?.targets}var x=d(o(),1);function $(n,e,t,r){let i=We(r,t);return n.createBindGroup({layout:e,entries:i})}function oe(n,e,t){let r=n.bindings.find(i=>i.name===e||`${i.name}uniforms`===e.toLocaleLowerCase());return!r&&!t?.ignoreWarnings&&x.log.warn(`Binding ${e} not set: Not found in shader layout.`)(),r||null}function We(n,e){let t=[];for(let[r,i]of Object.entries(n)){let s=oe(e,r);s&&t.push(de(i,s.location)),s=oe(e,`${r}Sampler`,{ignoreWarnings:!0}),s&&t.push(de(i,s.location,{sampler:!0}))}return t}function de(n,e,t){if(n instanceof x.Buffer)return{binding:e,resource:{buffer:n.handle}};if(n instanceof x.Sampler)return{binding:e,resource:n.handle};if(n instanceof x.Texture)return t?.sampler?{binding:e,resource:n.sampler.handle}:{binding:e,resource:n.handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var B=d(o(),1);function Z(n){if(n.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${n}`);return n}function le(n,e){let t=[],r=new Set;for(let i of e){let s=[],a="vertex",l=0,c=i.format;if(i.attributes)for(let h of i.attributes){let g=h.attribute,u=he(n,g,r),T=u?.location;a=u?.stepMode||(u?.name.startsWith("instance")?"instance":"vertex"),s.push({format:Z(h.format||i.format),offset:h.byteOffset,shaderLocation:T}),l+=(0,B.decodeVertexFormat)(c).byteLength}else{let h=he(n,i.name,r);if(!h)continue;l=(0,B.decodeVertexFormat)(c).byteLength,a=h.stepMode||(h.name.startsWith("instance")?"instance":"vertex"),s.push({format:Z(c),offset:0,shaderLocation:h.location})}t.push({arrayStride:i.byteStride||l,stepMode:a,attributes:s})}for(let i of n.attributes)r.has(i.name)||t.push({arrayStride:(0,B.decodeVertexFormat)("float32x3").byteLength,stepMode:i.stepMode||(i.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:Z("float32x3"),offset:0,shaderLocation:i.location}]});return t}function he(n,e,t){let r=n.attributes.find(i=>i.name===e);if(!r)return B.log.warn(`Supplied attribute not present in shader layout: ${e}`)(),null;if(t.has(e))throw new Error(`Found multiple entries for attribute: ${e}`);return t.add(e),r}var z=class extends w.RenderPipeline{device;handle;vs;fs=null;_bindings;_bindGroupLayout=null;_bindGroup=null;get[Symbol.toStringTag](){return"WebGPURenderPipeline"}constructor(e,t){if(super(e,t),this.device=e,this.handle=this.props.handle,!this.handle){let r=this._getRenderPipelineDescriptor();w.log.groupCollapsed(1,`new WebGPURenderPipeline(${this.id})`)(),w.log.probe(1,JSON.stringify(r,null,2))(),w.log.groupEnd(1)(),this.device.handle.pushErrorScope("validation"),this.handle=this.device.handle.createRenderPipeline(r),this.device.handle.popErrorScope().then(i=>{i&&w.log.error(`${this} creation failed:
"${i.message}"`,this,this.props.vs?.source)()})}this.handle.label=this.props.id,this.vs=t.vs,this.fs=t.fs,this._bindings={...this.props.bindings}}destroy(){this.handle=null}setBindings(e){for(let[t,r]of Object.entries(e))this._bindings[t]!==r&&(this._bindGroup=null);Object.assign(this._bindings,e)}draw(e){let t=e.renderPass;this.device.handle.pushErrorScope("validation"),t.handle.setPipeline(this.handle),this.device.handle.popErrorScope().then(i=>{i&&w.log.error(`${this} setPipeline failed:
"${i.message}"`,this)()});let r=this._getBindGroup();return r&&t.handle.setBindGroup(0,r),e.vertexArray.bindBeforeRender(e.renderPass),e.indexCount?t.handle.drawIndexed(e.indexCount,e.instanceCount,e.firstIndex,e.baseVertex,e.firstInstance):t.handle.draw(e.vertexCount||0,e.instanceCount||1,e.firstInstance),e.vertexArray.unbindAfterRender(e.renderPass),!0}_getBindGroup(){return this.shaderLayout.bindings.length===0?null:(this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||$(this.device.handle,this._bindGroupLayout,this.shaderLayout,this._bindings),this._bindGroup)}_getRenderPipelineDescriptor(){let e={module:this.props.vs.handle,entryPoint:this.props.vertexEntryPoint||"main",buffers:le(this.shaderLayout,this.props.bufferLayout)},t=[];if(this.props.colorAttachmentFormats)for(let a of this.props.colorAttachmentFormats)t.push(a?{format:E(a)}:null);else t.push({format:E(this.device.preferredColorFormat)});let r={module:this.props.fs.handle,entryPoint:this.props.fragmentEntryPoint||"main",targets:t},i={vertex:e,fragment:r,primitive:{topology:this.props.topology},layout:"auto"},s=this.props.depthStencilAttachmentFormat||this.device.preferredDepthFormat;return this.props.parameters.depthWriteEnabled&&(i.depthStencil={format:E(s)}),ae(i,this.props.parameters),i}};var pe=d(o(),1),A=class extends pe.Framebuffer{device;colorAttachments=[];depthStencilAttachment=null;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}updateAttachments(){}};var ce=d(o(),1);var q=class extends ce.ComputePipeline{device;handle;_bindGroupLayout=null;_bindGroup=null;_bindings={};constructor(e,t){super(e,t),this.device=e;let r=this.props.shader;this.handle=this.props.handle||this.device.handle.createComputePipeline({label:this.props.id,compute:{module:r.handle,entryPoint:this.props.entryPoint,constants:this.props.constants},layout:"auto"})}setBindings(e){Object.assign(this._bindings,e)}_getBindGroup(){return this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||$(this.device.handle,this._bindGroupLayout,this.shaderLayout,this._bindings),this._bindGroup}};var y=d(o(),1),Q=class extends y.RenderPass{device;handle;pipeline=null;constructor(e,t={}){super(e,t),this.device=e;let r=t.framebuffer||e.getCanvasContext().getCurrentFramebuffer(),i=this.getRenderPassDescriptor(r),s=t.timestampQuerySet;if(s&&(i.occlusionQuerySet=s.handle),e.features.has("timestamp-query")){let a=t.timestampQuerySet;i.timestampWrites=a?{querySet:a.handle,beginningOfPassWriteIndex:t.beginTimestampIndex,endOfPassWriteIndex:t.endTimestampIndex}:void 0}if(!e.commandEncoder)throw new Error("commandEncoder not available");this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||e.commandEncoder.beginRenderPass(i),this.device.handle.popErrorScope().then(a=>{a&&y.log.error(`${this} creation failed:
"${a.message}"`,this)()}),this.handle.label=this.props.id,y.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),y.log.probe(3,JSON.stringify(i,null,2))(),y.log.groupEnd(3)()}destroy(){}end(){this.handle.end()}setPipeline(e){this.pipeline=e,this.handle.setPipeline(this.pipeline.handle)}setBindings(e){this.pipeline?.setBindings(e);let t=this.pipeline?._getBindGroup();t&&this.handle.setBindGroup(0,t)}setIndexBuffer(e,t,r=0,i){this.handle.setIndexBuffer(e.handle,t,r,i)}setVertexBuffer(e,t,r=0){this.handle.setVertexBuffer(e,t.handle,r)}draw(e){e.indexCount?this.handle.drawIndexed(e.indexCount,e.instanceCount,e.firstIndex,e.baseVertex,e.firstInstance):this.handle.draw(e.vertexCount||0,e.instanceCount||1,e.firstIndex,e.firstInstance)}drawIndirect(){}setParameters(e){let{blendConstant:t,stencilReference:r,scissorRect:i,viewport:s}=e;t&&this.handle.setBlendConstant(t),r&&this.handle.setStencilReference(r),i&&this.handle.setScissorRect(i[0],i[1],i[2],i[3]),s&&this.handle.setViewport(s[0],s[1],s[2],s[3],s[4],s[5])}pushDebugGroup(e){this.handle.pushDebugGroup(e)}popDebugGroup(){this.handle.popDebugGroup()}insertDebugMarker(e){this.handle.insertDebugMarker(e)}beginOcclusionQuery(e){this.handle.beginOcclusionQuery(e)}endOcclusionQuery(){this.handle.endOcclusionQuery()}getRenderPassDescriptor(e){let t={colorAttachments:[]};if(t.colorAttachments=e.colorAttachments.map((r,i)=>({loadOp:this.props.clearColor!==!1?"clear":"load",colorClearValue:this.props.clearColors?.[i]||this.props.clearColor||y.RenderPass.defaultClearColor,storeOp:this.props.discard?"discard":"store",view:r.handle})),e.depthStencilAttachment){t.depthStencilAttachment={view:e.depthStencilAttachment.handle};let{depthStencilAttachment:r}=t;this.props.depthReadOnly&&(r.depthReadOnly=!0),this.props.clearDepth!==!1&&(r.depthClearValue=this.props.clearDepth),!0&&(r.depthLoadOp=this.props.clearDepth!==!1?"clear":"load",r.depthStoreOp="store"),!1&&(r.stencilLoadOp=this.props.clearStencil!==!1?"clear":"load",r.stencilStoreOp="store")}return t}};var ue=d(o(),1),N=class extends ue.ComputePass{device;handle;_webgpuPipeline=null;constructor(e,t){super(e,t),this.device=e;let r;if(e.features.has("timestamp-query")){let i=t.timestampQuerySet;i&&(r={querySet:i.handle,beginningOfPassWriteIndex:t.beginTimestampIndex,endOfPassWriteIndex:t.endTimestampIndex})}this.handle=this.props.handle||e.commandEncoder?.beginComputePass({label:this.props.id,timestampWrites:r})}destroy(){}end(){this.handle.end()}setPipeline(e){let t=e;this.handle.setPipeline(t.handle),this._webgpuPipeline=t,this.setBindings([])}setBindings(e){let t=this._webgpuPipeline._getBindGroup();this.handle.setBindGroup(0,t)}dispatch(e,t,r){this.handle.dispatchWorkgroups(e,t,r)}dispatchIndirect(e,t=0){let r=e;this.handle.dispatchWorkgroupsIndirect(r.handle,t)}pushDebugGroup(e){this.handle.pushDebugGroup(e)}popDebugGroup(){this.handle.popDebugGroup()}insertDebugMarker(e){this.handle.insertDebugMarker(e)}};var L=d(o(),1);var dt=globalThis.document||{},ht=globalThis.process||{},lt=globalThis.console,me=globalThis.navigator||{};function j(n){if(typeof window<"u"&&window.process?.type==="renderer"||typeof process<"u"&&Boolean(process.versions?.electron))return!0;let e=typeof navigator<"u"&&navigator.userAgent,t=n||e;return Boolean(t&&t.indexOf("Electron")>=0)}function fe(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process?.browser)||j()}function K(n){return!n&&!fe()?"Node":j(n)?"Electron":(n||me.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown"}var H=class extends L.VertexArray{get[Symbol.toStringTag](){return"WebGPUVertexArray"}device;handle;constructor(e,t){super(e,t),this.device=e}destroy(){}setIndexBuffer(e){this.indexBuffer=e}setBuffer(e,t){this.attributes[e]=t}bindBeforeRender(e,t,r){let i=e,s=this.indexBuffer;s?.handle&&(L.log.info(3,"setting index buffer",s?.handle,s?.indexType)(),i.handle.setIndexBuffer(s?.handle,s?.indexType));for(let a=0;a<this.maxVertexAttributes;a++){let l=this.attributes[a];l?.handle&&(L.log.info(3,`setting vertex buffer ${a}`,l?.handle)(),i.handle.setVertexBuffer(a,l?.handle))}}unbindAfterRender(e){}static isConstantAttributeZeroSupported(e){return K()==="Chrome"}};var G=d(o(),1);var I=class extends G.CanvasContext{device;handle;depthStencilAttachment=null;get[Symbol.toStringTag](){return"WebGPUCanvasContext"}constructor(e,t,r){super(r),this.device=e,this._setAutoCreatedCanvasId(`${this.device.id}-canvas`),this.updateSize([this.drawingBufferWidth,this.drawingBufferHeight])}destroy(){this.handle.unconfigure()}getCurrentFramebuffer(e={depthStencilFormat:"depth24plus"}){let t=this.getCurrentTexture();if(t.width!==this.drawingBufferWidth||t.height!==this.drawingBufferHeight){let[r,i]=this.getDrawingBufferSize();this.drawingBufferWidth=t.width,this.drawingBufferHeight=t.height,G.log.log(1,`${this}: Resized to compensate for initial canvas size mismatch ${r}x${i} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)()}return e?.depthStencilFormat&&this._createDepthStencilAttachment(e?.depthStencilFormat),new A(this.device,{colorAttachments:[t],depthStencilAttachment:this.depthStencilAttachment})}updateSize(e){this.depthStencilAttachment&&(this.depthStencilAttachment.destroy(),this.depthStencilAttachment=null),this.handle.configure({device:this.device.handle,format:this.device.preferredColorFormat,colorSpace:this.props.colorSpace,alphaMode:this.props.alphaMode})}resize(e){if(this.device.handle&&!this.props.autoResize&&this.canvas){let t=this.getDevicePixelRatio(e?.useDevicePixels);this._setDevicePixelRatio(t,e);return}}getCurrentTexture(){return this.device.createTexture({id:`${this.id}#color-texture`,handle:this.handle.getCurrentTexture(),format:this.device.preferredColorFormat})}_createDepthStencilAttachment(e){return this.depthStencilAttachment||(this.depthStencilAttachment=this.device.createTexture({id:`${this.id}#depth-stencil-texture`,usage:G.Texture.RENDER_ATTACHMENT,format:e,width:this.drawingBufferWidth,height:this.drawingBufferHeight})),this.depthStencilAttachment}};var ge=d(o(),1),Y=class extends ge.QuerySet{device;handle;constructor(e,t){super(e,t),this.device=e,this.handle=this.props.handle||this.device.handle.createQuerySet({type:this.props.type,count:this.props.count}),this.handle.label=this.props.id}destroy(){this.handle?.destroy(),this.handle=null}};var S=class extends X.Device{handle;type="webgpu";preferredColorFormat=navigator.gpu.getPreferredCanvasFormat();preferredDepthFormat="depth24plus";features;info;limits;lost;renderPass=null;canvasContext;_isLost=!1;commandEncoder=null;adapter;adapterInfo;constructor(e,t,r,i){if(super({...e,id:e.id||"webgpu-device"}),this.handle=t,this.adapter=r,this.adapterInfo=i,this.info=this._getInfo(),this.features=this._getFeatures(),this.limits=this.handle.limits,t.addEventListener("uncapturederror",s=>{let a=s instanceof GPUUncapturedErrorEvent?s.error.message:"Unknown WebGPU error";if(this.reportError(new Error(a)),this.props.debug)debugger;s.preventDefault()}),this.lost=new Promise(async s=>{let a=await this.handle.lost;this._isLost=!0,s({reason:"destroyed",message:a.message})}),e.createCanvasContext){let s=e.createCanvasContext===!0?{}:e.createCanvasContext;this.canvasContext=new I(this,this.adapter,s)}}destroy(){this.handle.destroy()}get isLost(){return this._isLost}createBuffer(e){let t=this._normalizeBufferProps(e);return new b(this,t)}createTexture(e){return new C(this,e)}createExternalTexture(e){return new U(this,e)}createShader(e){return new P(this,e)}createSampler(e){return new p(this,e)}createRenderPipeline(e){return new z(this,e)}createFramebuffer(e){return new A(this,e)}createComputePipeline(e){return new q(this,e)}createVertexArray(e){return new H(this,e)}beginRenderPass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new Q(this,e)}beginComputePass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new N(this,e)}createTransformFeedback(e){throw new Error("Transform feedback not supported in WebGPU")}createQuerySet(e){return new Y(this,e)}createCanvasContext(e){return new I(this,this.adapter,e)}submit(){let e=this.commandEncoder?.finish();e&&(this.handle.pushErrorScope("validation"),this.handle.queue.submit([e]),this.handle.popErrorScope().then(t=>{t&&this.reportError(new Error(`WebGPU command submission failed: ${t.message}`))})),this.commandEncoder=null}_getInfo(){let[e,t]=(this.adapterInfo.driver||"").split(" Version "),r=this.adapterInfo.vendor||this.adapter.__brand||"unknown",i=e||"",s=t||"",a=r==="apple"?"apple":"unknown",l=this.adapterInfo.architecture||"unknown",c=this.adapterInfo.backend||"unknown",h=(this.adapterInfo.type||"").split(" ")[0].toLowerCase()||"unknown";return{type:"webgpu",vendor:r,renderer:i,version:s,gpu:a,gpuType:h,gpuBackend:c,gpuArchitecture:l,shadingLanguage:"wgsl",shadingLanguageVersion:100}}_getFeatures(){let e=new Set(this.handle.features);e.has("depth-clamping")&&(e.delete("depth-clamping"),e.add("depth-clip-control")),e.has("texture-compression-bc")&&e.add("texture-compression-bc5-webgl");let t=["timer-query-webgl","compilation-status-async-webgl","float32-renderable-webgl","float16-renderable-webgl","norm16-renderable-webgl","texture-filterable-anisotropic-webgl","shader-noperspective-interpolation-webgl"];for(let r of t)e.add(r);return new X.DeviceFeatures(Array.from(e),this.props._disabledFeatures)}_getDeviceSpecificTextureFormatCapabilities(e){let{format:t}=e;return t.includes("webgl")?{format:t,create:!1,render:!1,filter:!1,blend:!1,store:!1}:e}copyExternalImageToTexture(e){let{source:t,sourceX:r=0,sourceY:i=0,texture:s,mipLevel:a=0,aspect:l="all",colorSpace:c="display-p3",premultipliedAlpha:h=!1,width:g=s.width,height:u=s.height,depth:T=1}=e,J=s;this.handle?.queue.copyExternalImageToTexture({source:t,origin:[r,i]},{texture:J.handle,origin:[0,0,0],mipLevel:a,aspect:l,colorSpace:c,premultipliedAlpha:h},[g,u,T])}};var ee=class extends f.Adapter{type="webgpu";constructor(){super(),S.adapter=this}isSupported(){return Boolean(typeof navigator<"u"&&navigator.gpu)}async create(e){if(!navigator.gpu)throw new Error("WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu");f.log.groupCollapsed(1,"WebGPUDevice created")();let t=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!t)throw new Error("Failed to request WebGPU adapter");let r=await t.requestAdapterInfo();f.log.probe(2,"Adapter available",r)();let i=[],s={};if(e._requestMaxLimits){i.push(...Array.from(t.features));let c=Object.keys(t.limits).filter(h=>!["minSubgroupSize","maxSubgroupSize"].includes(h));for(let h of c){let g=h,u=t.limits[g];typeof u=="number"&&(s[g]=u)}}let a=await t.requestDevice({requiredFeatures:i,requiredLimits:s});f.log.probe(1,"GPUDevice available")();let l=new S(e,a,t,r);return f.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),f.log.table(1,l.info)(),f.log.groupEnd(1)(),l}async attach(e){throw new Error("WebGPUAdapter.attach() not implemented")}},be=new ee;return Te(F);})();
var __exports__=(()=>{var Se=Object.create;var W=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Pe=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var Ae=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),Ge=(n,e)=>{for(var t in e)W(n,t,{get:e[t],enumerable:!0})},R=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ee(e))!Be.call(n,i)&&i!==t&&W(n,i,{get:()=>e[i],enumerable:!(r=Ce(e,i))||r.enumerable});return n},F=(n,e,t)=>(R(n,e,"default"),t&&R(t,e,"default")),h=(n,e,t)=>(t=n!=null?Se(Pe(n)):{},R(e||!n||!n.__esModule?W(t,"default",{value:n,enumerable:!0}):t,n)),Te=n=>R(W({},"__esModule",{value:!0}),n);var o=Ae((Oe,te)=>{te.exports=globalThis.luma});var I={};Ge(I,{WebGPUBuffer:()=>b,WebGPUDevice:()=>S,WebGPUSampler:()=>p,WebGPUShader:()=>P,WebGPUTexture:()=>E,webgpuAdapter:()=>be});F(I,h(o(),1));var f=h(o(),1);var X=h(o(),1);var O=h(o(),1);function Le(n){return n.byteLength||n.data?.byteLength||0}var b=class extends O.Buffer{device;handle;byteLength;constructor(e,t){super(e,t),this.device=e,this.byteLength=Le(t);let r=Boolean(t.data),i=Math.ceil(this.byteLength/4)*4;this.handle=this.props.handle||this.device.handle.createBuffer({size:i,usage:this.props.usage||GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,mappedAtCreation:this.props.mappedAtCreation||r,label:this.props.id}),t.data&&this._writeMapped(t.data),r&&!t.mappedAtCreation&&this.handle.unmap()}destroy(){this.handle?.destroy(),this.handle=null}write(e,t=0){this.device.handle.queue.writeBuffer(this.handle,t,e.buffer,e.byteOffset,e.byteLength)}async readAsync(e=0,t=this.byteLength){let r=new b(this.device,{usage:O.Buffer.MAP_READ|O.Buffer.COPY_DST,byteLength:t}),i=this.device.handle.createCommandEncoder();i.copyBufferToBuffer(this.handle,e,r.handle,0,t),this.device.handle.queue.submit([i.finish()]),await r.handle.mapAsync(GPUMapMode.READ,e,t);let s=r.handle.getMappedRange().slice(0);return r.handle.unmap(),r.destroy(),new Uint8Array(s)}_writeMapped(e){let t=this.handle.getMappedRange();new e.constructor(t).set(e)}mapAsync(e,t=0,r){return this.handle.mapAsync(e,t,r)}getMappedRange(e=0,t){return this.handle.getMappedRange(e,t)}unmap(){this.handle.unmap()}};var v=h(o(),1);function C(n){if(n.includes("webgl"))throw new Error("webgl-only format");return n}var re=h(o(),1),p=class extends re.Sampler{device;handle;constructor(e,t){super(e,t),this.device=e;let r={...this.props,mipmapFilter:void 0};t.type!=="comparison-sampler"&&delete r.compare,t.mipmapFilter&&t.mipmapFilter!=="none"&&(r.mipmapFilter=t.mipmapFilter),this.handle=this.handle||this.device.handle.createSampler(r),this.handle.label=this.props.id}destroy(){this.handle=null}};var ne=h(o(),1),T=class extends ne.TextureView{device;handle;texture;constructor(e,t){super(e,t),this.device=e,this.texture=t.texture,this.handle=this.handle||this.texture.handle.createView({format:t.format||this.texture.format,dimension:t.dimension||this.texture.dimension,aspect:t.aspect,baseMipLevel:t.baseMipLevel,mipLevelCount:t.mipLevelCount,baseArrayLayer:t.baseArrayLayer,arrayLayerCount:t.arrayLayerCount}),this.handle.label=this.props.id}destroy(){this.handle=null}};var De={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},E=class extends v.Texture{device;handle;sampler;view;constructor(e,t){super(e,t),this.device=e;let r={...this.props};t.data&&(r.data=t.data),this.initialize(r)}destroy(){this.handle?.destroy(),this.handle=null}createView(e){return new T(this.device,{...e,texture:this})}initialize(e){this.handle=this.props.handle||this.createHandle(),this.handle.label||=this.id,this.props.data&&(v.Texture.isExternalImage(this.props.data)?this.copyExternalImage({image:this.props.data}):this.setData({data:this.props.data})),this.width=this.handle.width,this.height=this.handle.height,this.sampler=e.sampler instanceof p?e.sampler:new p(this.device,e.sampler||{}),this.view=new T(this.device,{...this.props,texture:this})}createHandle(){let e=this.props.width||this.props.data?.width||1,t=this.props.height||this.props.data?.height||1;return this.device.handle.createTexture({label:this.id,size:{width:e,height:t,depthOrArrayLayers:this.depth},usage:this.props.usage||v.Texture.TEXTURE|v.Texture.COPY_DST,dimension:De[this.dimension],format:C(this.format),mipLevelCount:this.mipLevels,sampleCount:this.props.samples})}createGPUTextureView(){return this.handle.createView({label:this.id})}setSampler(e){return this.sampler=e instanceof p?e:new p(this.device,e),this}setTexture1DData(e){throw new Error("not implemented")}setTexture2DData(e,t,r){throw new Error("not implemented")}setTexture3DData(e,t,r){throw new Error("not implemented")}setTextureCubeData(e,t){throw new Error("not implemented")}setTextureArrayData(e){throw new Error("not implemented")}setTextureCubeArrayData(e){throw new Error("not implemented")}setData(e){if(ArrayBuffer.isView(e.data)){let t=new Uint8ClampedArray(e.data.buffer),r=new ImageData(t,this.width,this.height);return this.copyExternalImage({image:r})}throw new Error("Texture.setData: Use CommandEncoder to upload data to texture in WebGPU")}copyExternalImage(e){let t=v.Texture.getExternalImageSize(e.image),r={...v.Texture.defaultCopyExternalImageOptions,...t,...e},{image:i,sourceX:s,sourceY:a,width:l,height:c,depth:d,mipLevel:g,x:u,y:G,z:J,aspect:xe,colorSpace:we,premultipliedAlpha:ye,flipY:ve}=r;return this.device.handle.queue.copyExternalImageToTexture({source:i,origin:[s,a],flipY:ve},{texture:this.handle,origin:[u,G,J],mipLevel:g,aspect:xe,colorSpace:we,premultipliedAlpha:ye},[l,c,d]),{width:l,height:c}}};var ie=h(o(),1);var U=class extends ie.ExternalTexture{device;handle;sampler;constructor(e,t){super(e,t),this.device=e,this.handle=this.props.handle||this.device.handle.importExternalTexture({source:t.source,colorSpace:t.colorSpace}),this.sampler=null}destroy(){this.handle=null}setSampler(e){return this.sampler=e instanceof p?e:new p(this.device,e),this}};var L=h(o(),1),P=class extends L.Shader{device;handle;constructor(e,t){super(e,t),this.device=e;let r=t.source.includes("#version");if(this.props.language==="glsl"||r)throw new Error("GLSL shaders are not supported in WebGPU");this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||this.device.handle.createShaderModule({code:t.source}),this.device.handle.popErrorScope().then(i=>{i&&L.log.error(`${this} creation failed:
"${i.message}"`,this,this.props.source)()}),this.handle.label=this.props.id,this._checkCompilationError()}get asyncCompilationStatus(){return this.getCompilationInfo().then(()=>this.compilationStatus)}async _checkCompilationError(){let e=await this.getCompilationInfo(),t=Boolean(e.find(r=>r.type==="error"));this.compilationStatus=t?"error":"success",this.debugShader(),this.compilationStatus==="error"&&L.log.error("Shader compilation error",e)()}destroy(){this.handle=null}async getCompilationInfo(){return(await this.handle.getCompilationInfo()).messages}};var w=h(o(),1);function m(n){return n.depthStencil=n.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},n.depthStencil}function M(n){return m(n).stencilFront}function k(n){return m(n).stencilBack}var _e={cullMode:(n,e,t)=>{t.primitive=t.primitive||{},t.primitive.cullMode=e},frontFace:(n,e,t)=>{t.primitive=t.primitive||{},t.primitive.frontFace=e},depthWriteEnabled:(n,e,t)=>{let r=m(t);r.depthWriteEnabled=e},depthCompare:(n,e,t)=>{let r=m(t);r.depthCompare=e},depthFormat:(n,e,t)=>{let r=m(t);r.format=e},depthBias:(n,e,t)=>{let r=m(t);r.depthBias=e},depthBiasSlopeScale:(n,e,t)=>{let r=m(t);r.depthBiasSlopeScale=e},depthBiasClamp:(n,e,t)=>{let r=m(t);r.depthBiasClamp=e},stencilReadMask:(n,e,t)=>{let r=m(t);r.stencilReadMask=e},stencilWriteMask:(n,e,t)=>{let r=m(t);r.stencilWriteMask=e},stencilCompare:(n,e,t)=>{let r=M(t),i=k(t);r.compare=e,i.compare=e},stencilPassOperation:(n,e,t)=>{let r=M(t),i=k(t);r.passOp=e,i.passOp=e},stencilFailOperation:(n,e,t)=>{let r=M(t),i=k(t);r.failOp=e,i.failOp=e},stencilDepthFailOperation:(n,e,t)=>{let r=M(t),i=k(t);r.depthFailOp=e,i.depthFailOp=e},sampleCount:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.count=e},sampleMask:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.mask=e},sampleAlphaToCoverageEnabled:(n,e,t)=>{t.multisample=t.multisample||{},t.multisample.alphaToCoverageEnabled=e},colorMask:(n,e,t)=>{let r=se(t);r[0].writeMask=e},blendColorOperation:(n,e,t)=>{se(t)}},Ie={primitive:{cullMode:"back",topology:"triangle-list"},vertex:{module:void 0,entryPoint:"main"},fragment:{module:void 0,entryPoint:"main",targets:[]},layout:"auto"};function ae(n,e={}){Object.assign(n,{...Ie,...n}),Re(n,e)}function Re(n,e){for(let[t,r]of Object.entries(e)){let i=_e[t];if(!i)throw new Error(`Illegal parameter ${t}`);i(t,r,n)}}function se(n){if(n.fragment.targets=n.fragment?.targets||[],!Array.isArray(n.fragment?.targets))throw new Error("colorstate");return n.fragment?.targets?.length===0&&n.fragment.targets?.push({}),n.fragment?.targets}var x=h(o(),1);function V(n,e,t,r){let i=We(r,t);return n.createBindGroup({layout:e,entries:i})}function oe(n,e){let t=n.bindings.find(r=>r.name===e||`${r.name}uniforms`===e.toLocaleLowerCase());return t||x.log.warn(`Binding ${e} not set: Not found in shader layout.`)(),t||null}function We(n,e){let t=[];for(let[r,i]of Object.entries(n)){let s=oe(e,r);s&&t.push(he(i,s.location)),s=oe(e,`${r}Sampler`),s&&t.push(he(i,s.location,{sampler:!0}))}return t}function he(n,e,t){if(n instanceof x.Buffer)return{binding:e,resource:{buffer:n.handle}};if(n instanceof x.Sampler)return{binding:e,resource:n.handle};if(n instanceof x.Texture)return t?.sampler?{binding:e,resource:n.sampler.handle}:{binding:e,resource:n.handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var B=h(o(),1);function Z(n){if(n.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${n}`);return n}function le(n,e){let t=[],r=new Set;for(let i of e){let s=[],a="vertex",l=0,c=i.format;if(i.attributes)for(let d of i.attributes){let g=d.attribute,u=de(n,g,r),G=u?.location;a=u?.stepMode||(u?.name.startsWith("instance")?"instance":"vertex"),s.push({format:Z(d.format||i.format),offset:d.byteOffset,shaderLocation:G}),l+=(0,B.decodeVertexFormat)(c).byteLength}else{let d=de(n,i.name,r);if(!d)continue;l=(0,B.decodeVertexFormat)(c).byteLength,a=d.stepMode||(d.name.startsWith("instance")?"instance":"vertex"),s.push({format:Z(c),offset:0,shaderLocation:d.location})}t.push({arrayStride:i.byteStride||l,stepMode:a,attributes:s})}for(let i of n.attributes)r.has(i.name)||t.push({arrayStride:(0,B.decodeVertexFormat)("float32x3").byteLength,stepMode:i.stepMode||(i.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:Z("float32x3"),offset:0,shaderLocation:i.location}]});return t}function de(n,e,t){let r=n.attributes.find(i=>i.name===e);if(!r)return B.log.warn(`Unknown attribute ${e}`)(),null;if(t.has(e))throw new Error(`Duplicate attribute ${e}`);return t.add(e),r}var $=class extends w.RenderPipeline{device;handle;vs;fs=null;_bindings;_bindGroupLayout=null;_bindGroup=null;constructor(e,t){if(super(e,t),this.device=e,this.handle=this.props.handle,!this.handle){let r=this._getRenderPipelineDescriptor();w.log.groupCollapsed(1,`new WebGPURenderPipeline(${this.id})`)(),w.log.probe(1,JSON.stringify(r,null,2))(),w.log.groupEnd(1)(),this.device.handle.pushErrorScope("validation"),this.handle=this.device.handle.createRenderPipeline(r),this.device.handle.popErrorScope().then(i=>{i&&w.log.error(`${this} creation failed:
"${i.message}"`,this,this.props.vs?.source)()})}this.handle.label=this.props.id,this.vs=t.vs,this.fs=t.fs,this._bindings={...this.props.bindings}}destroy(){this.handle=null}setBindings(e){Object.assign(this._bindings,e)}draw(e){let t=e.renderPass;this.device.handle.pushErrorScope("validation"),t.handle.setPipeline(this.handle),this.device.handle.popErrorScope().then(i=>{i&&w.log.error(`${this} setPipeline failed:
"${i.message}"`,this)()});let r=this._getBindGroup();return r&&t.handle.setBindGroup(0,r),e.vertexArray.bindBeforeRender(e.renderPass),e.indexCount?t.handle.drawIndexed(e.indexCount,e.instanceCount,e.firstIndex,e.baseVertex,e.firstInstance):t.handle.draw(e.vertexCount||0,e.instanceCount||1,e.firstInstance),e.vertexArray.unbindAfterRender(e.renderPass),!0}_getBindGroup(){return this.shaderLayout.bindings.length===0?null:(this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||V(this.device.handle,this._bindGroupLayout,this.shaderLayout,this._bindings),this._bindGroup)}_getRenderPipelineDescriptor(){let e={module:this.props.vs.handle,entryPoint:this.props.vertexEntryPoint||"main",buffers:le(this.shaderLayout,this.props.bufferLayout)},t={module:this.props.fs.handle,entryPoint:this.props.fragmentEntryPoint||"main",targets:[{format:C(this.device.getCanvasContext().format)}]},r={vertex:e,fragment:t,primitive:{topology:this.props.topology},layout:"auto"};return ae(r,this.props.parameters),r}};var pe=h(o(),1),A=class extends pe.Framebuffer{device;colorAttachments=[];depthStencilAttachment=null;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}updateAttachments(){}};var ce=h(o(),1);var q=class extends ce.ComputePipeline{device;handle;_bindGroupLayout=null;_bindGroup=null;_bindings={};constructor(e,t){super(e,t),this.device=e;let r=this.props.shader;this.handle=this.props.handle||this.device.handle.createComputePipeline({label:this.props.id,compute:{module:r.handle,entryPoint:this.props.entryPoint,constants:this.props.constants},layout:"auto"})}setBindings(e){Object.assign(this._bindings,e)}_getBindGroup(){return this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||V(this.device.handle,this._bindGroupLayout,this.shaderLayout,this._bindings),this._bindGroup}};var y=h(o(),1),z=class extends y.RenderPass{device;handle;pipeline=null;constructor(e,t={}){super(e,t),this.device=e;let r=t.framebuffer||e.getCanvasContext().getCurrentFramebuffer(),i=this.getRenderPassDescriptor(r),s=t.timestampQuerySet;if(s&&(i.occlusionQuerySet=s.handle),e.features.has("timestamp-query")){let a=t.timestampQuerySet;i.timestampWrites=a?{querySet:a.handle,beginningOfPassWriteIndex:t.beginTimestampIndex,endOfPassWriteIndex:t.endTimestampIndex}:void 0}if(!e.commandEncoder)throw new Error("commandEncoder not available");this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||e.commandEncoder.beginRenderPass(i),this.device.handle.popErrorScope().then(a=>{a&&y.log.error(`${this} creation failed:
"${a.message}"`,this)()}),this.handle.label=this.props.id,y.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),y.log.probe(3,JSON.stringify(i,null,2))(),y.log.groupEnd(3)()}destroy(){}end(){this.handle.end()}setPipeline(e){this.pipeline=e,this.handle.setPipeline(this.pipeline.handle)}setBindings(e){this.pipeline?.setBindings(e);let t=this.pipeline?._getBindGroup();t&&this.handle.setBindGroup(0,t)}setIndexBuffer(e,t,r=0,i){this.handle.setIndexBuffer(e.handle,t,r,i)}setVertexBuffer(e,t,r=0){this.handle.setVertexBuffer(e,t.handle,r)}draw(e){e.indexCount?this.handle.drawIndexed(e.indexCount,e.instanceCount,e.firstIndex,e.baseVertex,e.firstInstance):this.handle.draw(e.vertexCount||0,e.instanceCount||1,e.firstIndex,e.firstInstance)}drawIndirect(){}setParameters(e){let{blendConstant:t,stencilReference:r,scissorRect:i,viewport:s}=e;t&&this.handle.setBlendConstant(t),r&&this.handle.setStencilReference(r),i&&this.handle.setScissorRect(i[0],i[1],i[2],i[3]),s&&this.handle.setViewport(s[0],s[1],s[2],s[3],s[4],s[5])}pushDebugGroup(e){this.handle.pushDebugGroup(e)}popDebugGroup(){this.handle.popDebugGroup()}insertDebugMarker(e){this.handle.insertDebugMarker(e)}beginOcclusionQuery(e){this.handle.beginOcclusionQuery(e)}endOcclusionQuery(){this.handle.endOcclusionQuery()}getRenderPassDescriptor(e){let t={colorAttachments:[]};if(t.colorAttachments=e.colorAttachments.map((r,i)=>({loadOp:this.props.clearColor!==!1?"clear":"load",colorClearValue:this.props.clearColors?.[i]||this.props.clearColor||y.RenderPass.defaultClearColor,storeOp:this.props.discard?"discard":"store",view:r.handle})),e.depthStencilAttachment){t.depthStencilAttachment={view:e.depthStencilAttachment.handle};let{depthStencilAttachment:r}=t;this.props.depthReadOnly&&(r.depthReadOnly=!0),this.props.clearDepth!==!1&&(r.depthClearValue=this.props.clearDepth),!0&&(r.depthLoadOp=this.props.clearDepth!==!1?"clear":"load",r.depthStoreOp="store"),!1&&(r.stencilLoadOp=this.props.clearStencil!==!1?"clear":"load",r.stencilStoreOp="store")}return t}};var ue=h(o(),1),Q=class extends ue.ComputePass{device;handle;_webgpuPipeline=null;constructor(e,t){super(e,t),this.device=e;let r;if(e.features.has("timestamp-query")){let i=t.timestampQuerySet;i&&(r={querySet:i.handle,beginningOfPassWriteIndex:t.beginTimestampIndex,endOfPassWriteIndex:t.endTimestampIndex})}this.handle=this.props.handle||e.commandEncoder?.beginComputePass({label:this.props.id,timestampWrites:r})}destroy(){}end(){this.handle.end()}setPipeline(e){let t=e;this.handle.setPipeline(t.handle),this._webgpuPipeline=t,this.setBindings([])}setBindings(e){let t=this._webgpuPipeline._getBindGroup();this.handle.setBindGroup(0,t)}dispatch(e,t,r){this.handle.dispatchWorkgroups(e,t,r)}dispatchIndirect(e,t=0){let r=e;this.handle.dispatchWorkgroupsIndirect(r.handle,t)}pushDebugGroup(e){this.handle.pushDebugGroup(e)}popDebugGroup(){this.handle.popDebugGroup()}insertDebugMarker(e){this.handle.insertDebugMarker(e)}};var D=h(o(),1);var ht=globalThis.document||{},dt=globalThis.process||{},lt=globalThis.console,me=globalThis.navigator||{};function N(n){if(typeof window<"u"&&window.process?.type==="renderer"||typeof process<"u"&&Boolean(process.versions?.electron))return!0;let e=typeof navigator<"u"&&navigator.userAgent,t=n||e;return Boolean(t&&t.indexOf("Electron")>=0)}function fe(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process?.browser)||N()}function K(n){return!n&&!fe()?"Node":N(n)?"Electron":(n||me.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown"}var j=class extends D.VertexArray{get[Symbol.toStringTag](){return"WebGPUVertexArray"}device;handle;constructor(e,t){super(e,t),this.device=e}destroy(){}setIndexBuffer(e){this.indexBuffer=e}setBuffer(e,t){this.attributes[e]=t}bindBeforeRender(e,t,r){let i=e,s=this.indexBuffer;s?.handle&&(D.log.info(3,"setting index buffer",s?.handle,s?.indexType)(),i.handle.setIndexBuffer(s?.handle,s?.indexType));for(let a=0;a<this.maxVertexAttributes;a++){let l=this.attributes[a];l?.handle&&(D.log.info(3,`setting vertex buffer ${a}`,l?.handle)(),i.handle.setVertexBuffer(a,l?.handle))}}unbindAfterRender(e){}static isConstantAttributeZeroSupported(e){return K()==="Chrome"}};var Y=h(o(),1);var _=class extends Y.CanvasContext{device;gpuCanvasContext;format=navigator.gpu.getPreferredCanvasFormat();depthStencilFormat="depth24plus";depthStencilAttachment=null;get[Symbol.toStringTag](){return"WebGPUCanvasContext"}constructor(e,t,r){super(r),this.device=e,this.width=-1,this.height=-1,this._setAutoCreatedCanvasId(`${this.device.id}-canvas`),this.gpuCanvasContext=this.canvas.getContext("webgpu"),this.format="bgra8unorm"}destroy(){this.gpuCanvasContext.unconfigure()}getCurrentFramebuffer(){this.update();let e=this.getCurrentTexture();return this.width=e.width,this.height=e.height,this._createDepthStencilAttachment(),new A(this.device,{colorAttachments:[e],depthStencilAttachment:this.depthStencilAttachment})}update(){let e=this.width,t=this.height,[r,i]=this.getPixelSize();(r!==e||i!==t)&&(this.width=r,this.height=i,this.depthStencilAttachment&&(this.depthStencilAttachment.destroy(),this.depthStencilAttachment=null),this.gpuCanvasContext.configure({device:this.device.handle,format:C(this.format),colorSpace:this.props.colorSpace,alphaMode:this.props.alphaMode}),Y.log.log(1,`${this} Resized ${e}x${t} => ${r}x${i}px`)())}resize(e){if(this.update(),!!this.device.handle&&this.canvas){let t=this.getDevicePixelRatio(e?.useDevicePixels);this.setDevicePixelRatio(t,e);return}}getCurrentTexture(){return this.device.createTexture({id:`${this.id}#color-texture`,handle:this.gpuCanvasContext.getCurrentTexture(),format:this.format})}_createDepthStencilAttachment(){return this.depthStencilAttachment||(this.depthStencilAttachment=this.device.createTexture({id:`${this.id}#depth-stencil-texture`,format:this.depthStencilFormat,width:this.width,height:this.height,usage:GPUTextureUsage.RENDER_ATTACHMENT})),this.depthStencilAttachment}};var ge=h(o(),1),H=class extends ge.QuerySet{device;handle;constructor(e,t){super(e,t),this.device=e,this.handle=this.props.handle||this.device.handle.createQuerySet({type:this.props.type,count:this.props.count}),this.handle.label=this.props.id}destroy(){this.handle?.destroy(),this.handle=null}};var S=class extends X.Device{type="webgpu";handle;adapter;adapterInfo;features;info;limits;lost;canvasContext=null;_isLost=!1;commandEncoder=null;renderPass=null;constructor(e,t,r,i){if(super({...e,id:e.id||"webgpu-device"}),this.handle=t,this.adapter=r,this.adapterInfo=i,this.info=this._getInfo(),this.features=this._getFeatures(),this.limits=this.handle.limits,t.addEventListener("uncapturederror",s=>{let a=s instanceof GPUUncapturedErrorEvent?s.error.message:"Unknown WebGPU error";if(this.reportError(new Error(a)),this.props.debug)debugger;s.preventDefault()}),this.lost=new Promise(async s=>{let a=await this.handle.lost;this._isLost=!0,s({reason:"destroyed",message:a.message})}),e.createCanvasContext){let s=e.createCanvasContext===!0?{}:e.createCanvasContext;this.canvasContext=new _(this,this.adapter,s)}}destroy(){this.handle.destroy()}get isLost(){return this._isLost}createBuffer(e){let t=this._normalizeBufferProps(e);return new b(this,t)}createTexture(e){return new E(this,e)}createExternalTexture(e){return new U(this,e)}createShader(e){return new P(this,e)}createSampler(e){return new p(this,e)}createRenderPipeline(e){return new $(this,e)}createFramebuffer(e){return new A(this,e)}createComputePipeline(e){return new q(this,e)}createVertexArray(e){return new j(this,e)}beginRenderPass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new z(this,e)}beginComputePass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new Q(this,e)}createTransformFeedback(e){throw new Error("Transform feedback not supported in WebGPU")}createQuerySet(e){return new H(this,e)}createCanvasContext(e){return new _(this,this.adapter,e)}submit(){let e=this.commandEncoder?.finish();e&&(this.handle.pushErrorScope("validation"),this.handle.queue.submit([e]),this.handle.popErrorScope().then(t=>{t&&this.reportError(new Error(`WebGPU command submission failed: ${t.message}`))})),this.commandEncoder=null}_getInfo(){let[e,t]=(this.adapterInfo.driver||"").split(" Version "),r=this.adapterInfo.vendor||this.adapter.__brand||"unknown",i=e||"",s=t||"",a=r==="apple"?"apple":"unknown",l=this.adapterInfo.architecture||"unknown",c=this.adapterInfo.backend||"unknown",d=(this.adapterInfo.type||"").split(" ")[0].toLowerCase()||"unknown";return{type:"webgpu",vendor:r,renderer:i,version:s,gpu:a,gpuType:d,gpuBackend:c,gpuArchitecture:l,shadingLanguage:"wgsl",shadingLanguageVersion:100}}_getFeatures(){let e=new Set(this.handle.features);e.has("depth-clamping")&&(e.delete("depth-clamping"),e.add("depth-clip-control")),e.has("texture-compression-bc")&&e.add("texture-compression-bc5-webgl");let t=["timer-query-webgl","compilation-status-async-webgl","float32-renderable-webgl","float16-renderable-webgl","norm16-renderable-webgl","texture-filterable-anisotropic-webgl","shader-noperspective-interpolation-webgl"];for(let r of t)e.add(r);return new X.DeviceFeatures(Array.from(e),this.props._disabledFeatures)}_getDeviceSpecificTextureFormatCapabilities(e){let{format:t}=e;return t.includes("webgl")?{format:t,create:!1,render:!1,filter:!1,blend:!1,store:!1}:e}copyExternalImageToTexture(e){let{source:t,sourceX:r=0,sourceY:i=0,texture:s,mipLevel:a=0,aspect:l="all",colorSpace:c="display-p3",premultipliedAlpha:d=!1,width:g=s.width,height:u=s.height,depth:G=1}=e,J=s;this.handle?.queue.copyExternalImageToTexture({source:t,origin:[r,i]},{texture:J.handle,origin:[0,0,0],mipLevel:a,aspect:l,colorSpace:c,premultipliedAlpha:d},[g,u,G])}};var ee=class extends f.Adapter{type="webgpu";constructor(){super(),S.adapter=this}isSupported(){return Boolean(typeof navigator<"u"&&navigator.gpu)}async create(e){if(!navigator.gpu)throw new Error("WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu");f.log.groupCollapsed(1,"WebGPUDevice created")();let t=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!t)throw new Error("Failed to request WebGPU adapter");let r=await t.requestAdapterInfo();f.log.probe(2,"Adapter available",r)();let i=[],s={};if(e._requestMaxLimits){i.push(...Array.from(t.features));let c=Object.keys(t.limits).filter(d=>!["minSubgroupSize","maxSubgroupSize"].includes(d));for(let d of c){let g=d,u=t.limits[g];typeof u=="number"&&(s[g]=u)}}let a=await t.requestDevice({requiredFeatures:i,requiredLimits:s});f.log.probe(1,"GPUDevice available")();let l=new S(e,a,t,r);return f.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),f.log.table(1,l.info)(),f.log.groupEnd(1)(),l}async attach(e){throw new Error("WebGPUAdapter.attach() not implemented")}},be=new ee;return Te(I);})();
return __exports__;
});
{
"name": "@luma.gl/webgpu",
"version": "9.1.0-beta.8",
"version": "9.1.0-beta.9",
"description": "WebGPU adapter for the luma.gl core API",

@@ -46,3 +46,3 @@ "type": "module",

},
"gitHead": "10846580c7a10c4cc48de01a4e5259cc0a00c249"
"gitHead": "ce90c649e27184c399eaeab814ec21a46f45677b"
}

@@ -45,4 +45,3 @@ // luma.gl

shaderLayout: ComputeShaderLayout,
bindingName: string,
options?: {ignoreWarnings?: boolean}
bindingName: string
): BindingDeclaration | null {

@@ -53,3 +52,3 @@ const bindingLayout = shaderLayout.bindings.find(

);
if (!bindingLayout && !options?.ignoreWarnings) {
if (!bindingLayout) {
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();

@@ -77,5 +76,3 @@ }

// TODO - hack to automatically bind samplers to supplied texture default samplers
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
ignoreWarnings: true
});
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`);
if (bindingLayout) {

@@ -82,0 +79,0 @@ entries.push(getBindGroupEntry(value, bindingLayout.location, {sampler: true}));

@@ -155,7 +155,7 @@ // luma.gl

if (!attribute) {
log.warn(`Supplied attribute not present in shader layout: ${name}`)();
log.warn(`Unknown attribute ${name}`)();
return null;
}
if (attributeNames.has(name)) {
throw new Error(`Found multiple entries for attribute: ${name}`);
throw new Error(`Duplicate attribute ${name}`);
}

@@ -162,0 +162,0 @@ attributeNames.add(name);

@@ -33,6 +33,2 @@ // luma.gl MIT license

override get [Symbol.toStringTag]() {
return 'WebGPURenderPipeline';
}
constructor(device: WebGPUDevice, props: RenderPipelineProps) {

@@ -76,8 +72,2 @@ super(device, props);

setBindings(bindings: Record<string, Binding>): void {
// Invalidate the cached bind group if any value has changed
for (const [name, binding] of Object.entries(bindings)) {
if (this._bindings[name] !== binding) {
this._bindGroup = null;
}
}
Object.assign(this._bindings, bindings);

@@ -171,13 +161,2 @@ }

// Populate color targets
// TODO - at the moment blend and write mask are only set on the first target
const targets: (GPUColorTargetState | null)[] = [];
if (this.props.colorAttachmentFormats) {
for (const format of this.props.colorAttachmentFormats) {
targets.push(format ? {format: getWebGPUTextureFormat(format)} : null);
}
} else {
targets.push({format: getWebGPUTextureFormat(this.device.preferredColorFormat)});
}
// Set up the fragment stage

@@ -187,3 +166,8 @@ const fragment: GPUFragmentState = {

entryPoint: this.props.fragmentEntryPoint || 'main',
targets
targets: [
{
// TODO exclamation mark hack!
format: getWebGPUTextureFormat(this.device.getCanvasContext().format)
}
]
};

@@ -201,11 +185,2 @@

// Set depth format if required, defaulting to the preferred depth format
const depthFormat = this.props.depthStencilAttachmentFormat || this.device.preferredDepthFormat;
if (this.props.parameters.depthWriteEnabled) {
descriptor.depthStencil = {
format: getWebGPUTextureFormat(depthFormat)
};
}
// Set parameters on the descriptor

@@ -212,0 +187,0 @@ applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);

@@ -7,4 +7,5 @@ // luma.gl

import type {DepthStencilTextureFormat, CanvasContextProps} from '@luma.gl/core';
import {CanvasContext, Texture, log} from '@luma.gl/core';
import type {Texture, TextureFormat, CanvasContextProps} from '@luma.gl/core';
import {CanvasContext, log} from '@luma.gl/core';
import {getWebGPUTextureFormat} from './helpers/convert-texture-format';
import {WebGPUDevice} from './webgpu-device';

@@ -21,5 +22,9 @@ import {WebGPUFramebuffer} from './resources/webgpu-framebuffer';

readonly device: WebGPUDevice;
readonly handle: GPUCanvasContext;
readonly gpuCanvasContext: GPUCanvasContext;
/** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
readonly format: TextureFormat = navigator.gpu.getPreferredCanvasFormat() as TextureFormat;
/** Default stencil format for depth textures */
readonly depthStencilFormat: TextureFormat = 'depth24plus';
private depthStencilAttachment: WebGPUTexture | null = null;
private depthStencilAttachment: Texture | null = null;

@@ -33,6 +38,12 @@ get [Symbol.toStringTag](): string {

this.device = device;
// TODO - ugly hack to trigger first resize
this.width = -1;
this.height = -1;
// Base class constructor cannot access derived methods/fields, so we need to call these functions in the subclass constructor
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
this.updateSize([this.drawingBufferWidth, this.drawingBufferHeight]);
// @ts-ignore TODO - we don't handle OffscreenRenderingContext.
this.gpuCanvasContext = this.canvas.getContext('webgpu');
// TODO this has been replaced
// this.format = this.gpuCanvasContext.getPreferredFormat(adapter);
this.format = 'bgra8unorm';
}

@@ -42,31 +53,26 @@

destroy(): void {
this.handle.unconfigure();
this.gpuCanvasContext.unconfigure();
}
/** Update framebuffer with properly resized "swap chain" texture views */
getCurrentFramebuffer(
options: {depthStencilFormat?: DepthStencilTextureFormat | false} = {
depthStencilFormat: 'depth24plus'
}
): WebGPUFramebuffer {
getCurrentFramebuffer(): WebGPUFramebuffer {
// Ensure the canvas context size is updated
this.update();
// Wrap the current canvas context texture in a luma.gl texture
// const currentColorAttachment = this.device.createTexture({
// id: 'default-render-target',
// handle: this.gpuCanvasContext.getCurrentTexture(),
// format: this.format,
// width: this.width,
// height: this.height
// });
// Wrap the current canvas context texture in a luma.gl texture
const currentColorAttachment = this.getCurrentTexture();
// TODO - temporary debug code
if (
currentColorAttachment.width !== this.drawingBufferWidth ||
currentColorAttachment.height !== this.drawingBufferHeight
) {
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
this.drawingBufferWidth = currentColorAttachment.width;
this.drawingBufferHeight = currentColorAttachment.height;
log.log(
1,
`${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`
)();
}
this.width = currentColorAttachment.width;
this.height = currentColorAttachment.height;
// Resize the depth stencil attachment
if (options?.depthStencilFormat) {
this._createDepthStencilAttachment(options?.depthStencilFormat);
}
this._createDepthStencilAttachment();

@@ -80,31 +86,42 @@ return new WebGPUFramebuffer(this.device, {

/** Resizes and updates render targets if necessary */
updateSize(size: [newWidth: number, newHeight: number]): void {
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
update() {
const oldWidth = this.width;
const oldHeight = this.height;
const [newWidth, newHeight] = this.getPixelSize();
const sizeChanged = newWidth !== oldWidth || newHeight !== oldHeight;
if (sizeChanged) {
this.width = newWidth;
this.height = newHeight;
if (this.depthStencilAttachment) {
this.depthStencilAttachment.destroy();
this.depthStencilAttachment = null;
}
// Reconfigure the canvas size.
// https://www.w3.org/TR/webgpu/#canvas-configuration
this.gpuCanvasContext.configure({
device: this.device.handle,
format: getWebGPUTextureFormat(this.format),
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
log.log(1, `${this} Resized ${oldWidth}x${oldHeight} => ${newWidth}x${newHeight}px`)();
}
// Reconfigure the canvas size.
// https://www.w3.org/TR/webgpu/#canvas-configuration
this.handle.configure({
device: this.device.handle,
format: this.device.preferredColorFormat,
// Can be used to define e.g. -srgb views
// viewFormats: [...]
colorSpace: this.props.colorSpace,
alphaMode: this.props.alphaMode
});
}
resize(options?: {width?: number; height?: number; useDevicePixels?: boolean | number}): void {
this.update();
if (!this.device.handle) return;
if (this.props.autoResize) {
return;
}
// Resize browser context .
if (this.canvas) {
const devicePixelRatio = this.getDevicePixelRatio(options?.useDevicePixels);
this._setDevicePixelRatio(devicePixelRatio, options);
this.setDevicePixelRatio(devicePixelRatio, options);
return;

@@ -118,4 +135,4 @@ }

id: `${this.id}#color-texture`,
handle: this.handle.getCurrentTexture(),
format: this.device.preferredColorFormat
handle: this.gpuCanvasContext.getCurrentTexture(),
format: this.format
});

@@ -125,10 +142,10 @@ }

/** We build render targets on demand (i.e. not when size changes but when about to render) */
_createDepthStencilAttachment(depthStencilFormat: DepthStencilTextureFormat): WebGPUTexture {
_createDepthStencilAttachment() {
if (!this.depthStencilAttachment) {
this.depthStencilAttachment = this.device.createTexture({
id: `${this.id}#depth-stencil-texture`,
usage: Texture.RENDER_ATTACHMENT,
format: depthStencilFormat,
width: this.drawingBufferWidth,
height: this.drawingBufferHeight
format: this.depthStencilFormat,
width: this.width,
height: this.height,
usage: GPUTextureUsage.RENDER_ATTACHMENT
});

@@ -135,0 +152,0 @@ }

@@ -31,3 +31,3 @@ // luma.gl

QuerySetProps,
DeviceProps,
DeviceProps
} from '@luma.gl/core';

@@ -53,11 +53,11 @@ import {Device, DeviceFeatures} from '@luma.gl/core';

export class WebGPUDevice extends Device {
/** The underlying WebGPU device */
readonly handle: GPUDevice;
/** type of this device */
readonly type = 'webgpu';
readonly preferredColorFormat = navigator.gpu.getPreferredCanvasFormat() as
| 'rgba8unorm'
| 'bgra8unorm';
readonly preferredDepthFormat = 'depth24plus';
/** The underlying WebGPU device */
readonly handle: GPUDevice;
/* The underlying WebGPU adapter */
readonly adapter: GPUAdapter;
/* The underlying WebGPU adapter's info */
readonly adapterInfo: GPUAdapterInfo;

@@ -69,13 +69,7 @@ readonly features: DeviceFeatures;

readonly lost: Promise<{reason: 'destroyed'; message: string}>;
canvasContext: WebGPUCanvasContext | null = null;
renderPass: WebGPURenderPass | null = null;
override canvasContext: WebGPUCanvasContext | null;
private _isLost: boolean = false;
// canvasContext: WebGPUCanvasContext | null = null;
commandEncoder: GPUCommandEncoder | null = null;
/* The underlying WebGPU adapter */
readonly adapter: GPUAdapter;
/* The underlying WebGPU adapter's info */
readonly adapterInfo: GPUAdapterInfo;
renderPass: WebGPURenderPass | null = null;

@@ -82,0 +76,0 @@ constructor(

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc