@luma.gl/webgpu
Advanced tools
Comparing version 9.1.0-alpha.2 to 9.1.0-alpha.9
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { TextureFormat } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ /** Ensure a texture format is WebGPU compatible */ |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { ComputeShaderLayout, BindingDeclaration, Binding } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ /** |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { ShaderLayout, BufferLayout } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ /** |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { Parameters } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ /** |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { Buffer, BufferProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import type { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { CommandEncoder, CommandEncoderProps, Buffer, Texture } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import type { CopyTextureToTextureOptions, CopyTextureToBufferOptions } from '@luma.gl/core'; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { ComputePass, ComputePassProps, ComputePipeline, Buffer, Binding } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { ComputePipeline, ComputePipelineProps, Binding } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { ExternalTexture, ExternalTextureProps, Sampler, SamplerProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import type { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { QuerySet, QuerySetProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { RenderPassProps, RenderPassParameters, Binding } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { Buffer, RenderPass, RenderPipeline } from '@luma.gl/core'; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { Binding, RenderPass, VertexArray } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { RenderPipeline, RenderPipelineProps } from '@luma.gl/core'; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { Sampler, SamplerProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import type { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { ShaderProps, CompilerMessage } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { Shader } from '@luma.gl/core'; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import { TextureView, TextureViewProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import type { WebGPUDevice } from "../webgpu-device.js"; |
@@ -1,3 +0,2 @@ | ||
/// <reference types="dist" /> | ||
import type { TextureProps, TextureViewProps, Sampler, SamplerProps, Texture1DData, Texture2DData, Texture3DData, TextureCubeData, TextureArrayData, TextureCubeArrayData } from '@luma.gl/core'; | ||
import type { TextureProps, TextureViewProps, Sampler, SamplerProps, Texture1DData, Texture2DData, Texture3DData, TextureCubeData, TextureArrayData, TextureCubeArrayData, ExternalImage } from '@luma.gl/core'; | ||
import { Texture } from '@luma.gl/core'; | ||
@@ -40,3 +39,3 @@ import type { WebGPUDevice } from "../webgpu-device.js"; | ||
setImage(options: { | ||
source: ImageBitmap | HTMLCanvasElement | OffscreenCanvas; | ||
source: ExternalImage; | ||
width?: number; | ||
@@ -43,0 +42,0 @@ height?: number; |
@@ -52,3 +52,8 @@ import { Texture } from '@luma.gl/core'; | ||
if (this.props.data) { | ||
this.setData({ data: this.props.data }); | ||
if (Texture.isExternalImage(this.props.data)) { | ||
this.setImage({ source: this.props.data }); | ||
} | ||
else { | ||
this.setData({ data: this.props.data }); | ||
} | ||
} | ||
@@ -134,7 +139,26 @@ this.width = this.handle.width; | ||
setData(options) { | ||
return this.setImage({ source: options.data }); | ||
let source = options.data; | ||
if (ArrayBuffer.isView(options.data)) { | ||
const clampedArray = new Uint8ClampedArray(options.data.buffer); | ||
// TODO - pass through src data color space as ImageData Options? | ||
source = new ImageData(clampedArray, this.width, this.height); | ||
} | ||
return this.setImage({ source }); | ||
} | ||
// setDataFromTypedArray(data): this { | ||
// const textureDataBuffer = this.device.handle.createBuffer({ | ||
// size: data.byteLength, | ||
// usage: Buffer.COPY_DST | Buffer.COPY_SRC, | ||
// mappedAtCreation: true | ||
// }); | ||
// new Uint8Array(textureDataBuffer.getMappedRange()).set(data); | ||
// textureDataBuffer.unmap(); | ||
// this.setBuffer(textureDataBuffer); | ||
// textureDataBuffer.destroy(); | ||
// return this; | ||
// } | ||
/** Set image */ | ||
setImage(options) { | ||
const { source, width = options.source.width, height = options.source.height, depth = 1, sourceX = 0, sourceY = 0, mipLevel = 0, x = 0, y = 0, z = 0, aspect = 'all', colorSpace = 'srgb', premultipliedAlpha = false } = options; | ||
const size = Texture.getExternalImageSize(options.source); | ||
const { source, width = size.width, height = size.height, depth = 1, sourceX = 0, sourceY = 0, mipLevel = 0, x = 0, y = 0, z = 0, aspect = 'all', colorSpace = 'srgb', premultipliedAlpha = false } = options; | ||
// TODO - max out width | ||
@@ -141,0 +165,0 @@ this.device.handle.queue.copyExternalImageToTexture( |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { Texture, TextureFormat, CanvasContextProps } from '@luma.gl/core'; | ||
@@ -3,0 +2,0 @@ import { CanvasContext } from '@luma.gl/core'; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="dist" /> | ||
import type { DeviceProps, DeviceInfo, DeviceLimits, CanvasContextProps, BufferProps, SamplerProps, ShaderProps, Texture, TextureProps, TextureFormat, ExternalTextureProps, FramebufferProps, RenderPipelineProps, ComputePipelineProps, RenderPassProps, ComputePassProps, VertexArrayProps, TransformFeedback, TransformFeedbackProps, QuerySet, QuerySetProps } from '@luma.gl/core'; | ||
@@ -18,3 +17,2 @@ import { Device, DeviceFeatures } from '@luma.gl/core'; | ||
export declare class WebGPUDevice extends Device { | ||
static type: string; | ||
/** type of this device */ | ||
@@ -37,6 +35,3 @@ readonly type = "webgpu"; | ||
renderPass: WebGPURenderPass | null; | ||
/** Check if WebGPU is available */ | ||
static isSupported(): boolean; | ||
static create(props: DeviceProps): Promise<WebGPUDevice>; | ||
constructor(device: GPUDevice, adapter: GPUAdapter, adapterInfo: GPUAdapterInfo, props: DeviceProps); | ||
constructor(props: DeviceProps, device: GPUDevice, adapter: GPUAdapter, adapterInfo: GPUAdapterInfo); | ||
destroy(): void; | ||
@@ -43,0 +38,0 @@ isTextureFormatSupported(format: TextureFormat): boolean; |
// luma.gl | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) vis.gl contributors | ||
import { Device, DeviceFeatures, CanvasContext, log } from '@luma.gl/core'; | ||
import { Device, DeviceFeatures } from '@luma.gl/core'; | ||
import { WebGPUBuffer } from "./resources/webgpu-buffer.js"; | ||
@@ -21,3 +21,2 @@ import { WebGPUTexture } from "./resources/webgpu-texture.js"; | ||
export class WebGPUDevice extends Device { | ||
static type = 'webgpu'; | ||
/** type of this device */ | ||
@@ -39,52 +38,3 @@ type = 'webgpu'; | ||
renderPass = null; | ||
/** Check if WebGPU is available */ | ||
static isSupported() { | ||
return Boolean(typeof navigator !== 'undefined' && navigator.gpu); | ||
} | ||
static async create(props) { | ||
if (!navigator.gpu) { | ||
throw new Error('WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu'); | ||
} | ||
log.groupCollapsed(1, 'WebGPUDevice created')(); | ||
const adapter = await navigator.gpu.requestAdapter({ | ||
powerPreference: 'high-performance' | ||
// forceSoftware: false | ||
}); | ||
if (!adapter) { | ||
throw new Error('Failed to request WebGPU adapter'); | ||
} | ||
const adapterInfo = await adapter.requestAdapterInfo(); | ||
log.probe(2, 'Adapter available', adapterInfo)(); | ||
const requiredFeatures = []; | ||
const requiredLimits = {}; | ||
if (props.requestMaxLimits) { | ||
// Require all features | ||
requiredFeatures.push(...Array.from(adapter.features)); | ||
// Require all limits | ||
// Filter out chrome specific keys (avoid crash) | ||
const limits = Object.keys(adapter.limits).filter(key => !['minSubgroupSize', 'maxSubgroupSize'].includes(key)); | ||
for (const key of limits) { | ||
const limit = key; | ||
const value = adapter.limits[limit]; | ||
if (typeof value === 'number') { | ||
requiredLimits[limit] = value; | ||
} | ||
} | ||
} | ||
const gpuDevice = await adapter.requestDevice({ | ||
requiredFeatures, | ||
requiredLimits | ||
}); | ||
log.probe(1, 'GPUDevice available')(); | ||
if (typeof props.canvas === 'string') { | ||
await CanvasContext.pageLoaded; | ||
log.probe(1, 'DOM is loaded')(); | ||
} | ||
const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props); | ||
log.probe(1, 'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features')(); | ||
log.table(1, device.info)(); | ||
log.groupEnd(1)(); | ||
return device; | ||
} | ||
constructor(device, adapter, adapterInfo, props) { | ||
constructor(props, device, adapter, adapterInfo) { | ||
super({ ...props, id: props.id || 'webgpu-device' }); | ||
@@ -91,0 +41,0 @@ this.handle = device; |
@@ -14,3 +14,2 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __commonJS = (cb, mod) => function __require() { | ||
@@ -41,6 +40,2 @@ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
@@ -61,6 +56,10 @@ // external-global-plugin:@luma.gl/core | ||
WebGPUShader: () => WebGPUShader, | ||
WebGPUTexture: () => WebGPUTexture | ||
WebGPUTexture: () => WebGPUTexture, | ||
webgpuAdapter: () => webgpuAdapter | ||
}); | ||
__reExport(bundle_exports, __toESM(require_core(), 1)); | ||
// src/adapter/webgpu-adapter.ts | ||
var import_core18 = __toESM(require_core(), 1); | ||
// src/adapter/webgpu-device.ts | ||
@@ -247,3 +246,7 @@ var import_core17 = __toESM(require_core(), 1); | ||
if (this.props.data) { | ||
this.setData({ data: this.props.data }); | ||
if (import_core4.Texture.isExternalImage(this.props.data)) { | ||
this.setImage({ source: this.props.data }); | ||
} else { | ||
this.setData({ data: this.props.data }); | ||
} | ||
} | ||
@@ -303,10 +306,28 @@ this.width = this.handle.width; | ||
setData(options) { | ||
return this.setImage({ source: options.data }); | ||
let source = options.data; | ||
if (ArrayBuffer.isView(options.data)) { | ||
const clampedArray = new Uint8ClampedArray(options.data.buffer); | ||
source = new ImageData(clampedArray, this.width, this.height); | ||
} | ||
return this.setImage({ source }); | ||
} | ||
// setDataFromTypedArray(data): this { | ||
// const textureDataBuffer = this.device.handle.createBuffer({ | ||
// size: data.byteLength, | ||
// usage: Buffer.COPY_DST | Buffer.COPY_SRC, | ||
// mappedAtCreation: true | ||
// }); | ||
// new Uint8Array(textureDataBuffer.getMappedRange()).set(data); | ||
// textureDataBuffer.unmap(); | ||
// this.setBuffer(textureDataBuffer); | ||
// textureDataBuffer.destroy(); | ||
// return this; | ||
// } | ||
/** Set image */ | ||
setImage(options) { | ||
const size = import_core4.Texture.getExternalImageSize(options.source); | ||
const { | ||
source, | ||
width = options.source.width, | ||
height = options.source.height, | ||
width = size.width, | ||
height = size.height, | ||
depth = 1, | ||
@@ -389,17 +410,2 @@ sourceX = 0, | ||
setData(data): this { | ||
const textureDataBuffer = this.device.handle.createBuffer({ | ||
size: data.byteLength, | ||
usage: Buffer.COPY_DST | Buffer.COPY_SRC, | ||
mappedAtCreation: true | ||
}); | ||
new Uint8Array(textureDataBuffer.getMappedRange()).set(data); | ||
textureDataBuffer.unmap(); | ||
this.setBuffer(textureDataBuffer); | ||
textureDataBuffer.destroy(); | ||
return this; | ||
} | ||
setBuffer(textureDataBuffer, {bytesPerRow}): this { | ||
@@ -1427,3 +1433,3 @@ const commandEncoder = this.device.handle.createCommandEncoder(); | ||
// src/adapter/webgpu-device.ts | ||
var _WebGPUDevice = class extends import_core17.Device { | ||
var WebGPUDevice = class extends import_core17.Device { | ||
/** type of this device */ | ||
@@ -1445,56 +1451,3 @@ type = "webgpu"; | ||
renderPass = null; | ||
/** Check if WebGPU is available */ | ||
static isSupported() { | ||
return Boolean(typeof navigator !== "undefined" && navigator.gpu); | ||
} | ||
static async create(props) { | ||
if (!navigator.gpu) { | ||
throw new Error( | ||
"WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu" | ||
); | ||
} | ||
import_core17.log.groupCollapsed(1, "WebGPUDevice created")(); | ||
const adapter = await navigator.gpu.requestAdapter({ | ||
powerPreference: "high-performance" | ||
// forceSoftware: false | ||
}); | ||
if (!adapter) { | ||
throw new Error("Failed to request WebGPU adapter"); | ||
} | ||
const adapterInfo = await adapter.requestAdapterInfo(); | ||
import_core17.log.probe(2, "Adapter available", adapterInfo)(); | ||
const requiredFeatures = []; | ||
const requiredLimits = {}; | ||
if (props.requestMaxLimits) { | ||
requiredFeatures.push(...Array.from(adapter.features)); | ||
const limits = Object.keys(adapter.limits).filter( | ||
(key) => !["minSubgroupSize", "maxSubgroupSize"].includes(key) | ||
); | ||
for (const key of limits) { | ||
const limit = key; | ||
const value = adapter.limits[limit]; | ||
if (typeof value === "number") { | ||
requiredLimits[limit] = value; | ||
} | ||
} | ||
} | ||
const gpuDevice = await adapter.requestDevice({ | ||
requiredFeatures, | ||
requiredLimits | ||
}); | ||
import_core17.log.probe(1, "GPUDevice available")(); | ||
if (typeof props.canvas === "string") { | ||
await import_core17.CanvasContext.pageLoaded; | ||
import_core17.log.probe(1, "DOM is loaded")(); | ||
} | ||
const device = new _WebGPUDevice(gpuDevice, adapter, adapterInfo, props); | ||
import_core17.log.probe( | ||
1, | ||
"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features" | ||
)(); | ||
import_core17.log.table(1, device.info)(); | ||
import_core17.log.groupEnd(1)(); | ||
return device; | ||
} | ||
constructor(device, adapter, adapterInfo, props) { | ||
constructor(props, device, adapter, adapterInfo) { | ||
super({ ...props, id: props.id || "webgpu-device" }); | ||
@@ -1689,4 +1642,69 @@ this.handle = device; | ||
}; | ||
var WebGPUDevice = _WebGPUDevice; | ||
__publicField(WebGPUDevice, "type", "webgpu"); | ||
// src/adapter/webgpu-adapter.ts | ||
var WebGPUAdapter = class extends import_core18.Adapter { | ||
/** type of device's created by this adapter */ | ||
type = "webgpu"; | ||
constructor() { | ||
super(); | ||
WebGPUDevice.adapter = this; | ||
} | ||
/** Check if WebGPU is available */ | ||
isSupported() { | ||
return Boolean(typeof navigator !== "undefined" && navigator.gpu); | ||
} | ||
async create(props) { | ||
if (!navigator.gpu) { | ||
throw new Error( | ||
"WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu" | ||
); | ||
} | ||
import_core18.log.groupCollapsed(1, "WebGPUDevice created")(); | ||
const adapter = await navigator.gpu.requestAdapter({ | ||
powerPreference: "high-performance" | ||
// forceSoftware: false | ||
}); | ||
if (!adapter) { | ||
throw new Error("Failed to request WebGPU adapter"); | ||
} | ||
const adapterInfo = await adapter.requestAdapterInfo(); | ||
import_core18.log.probe(2, "Adapter available", adapterInfo)(); | ||
const requiredFeatures = []; | ||
const requiredLimits = {}; | ||
if (props.requestMaxLimits) { | ||
requiredFeatures.push(...Array.from(adapter.features)); | ||
const limits = Object.keys(adapter.limits).filter( | ||
(key) => !["minSubgroupSize", "maxSubgroupSize"].includes(key) | ||
); | ||
for (const key of limits) { | ||
const limit = key; | ||
const value = adapter.limits[limit]; | ||
if (typeof value === "number") { | ||
requiredLimits[limit] = value; | ||
} | ||
} | ||
} | ||
const gpuDevice = await adapter.requestDevice({ | ||
requiredFeatures, | ||
requiredLimits | ||
}); | ||
import_core18.log.probe(1, "GPUDevice available")(); | ||
if (typeof props.canvas === "string") { | ||
await import_core18.CanvasContext.pageLoaded; | ||
import_core18.log.probe(1, "DOM is loaded")(); | ||
} | ||
const device = new WebGPUDevice(props, gpuDevice, adapter, adapterInfo); | ||
import_core18.log.probe( | ||
1, | ||
"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features" | ||
)(); | ||
import_core18.log.table(1, device.info)(); | ||
import_core18.log.groupEnd(1)(); | ||
return device; | ||
} | ||
async attach(handle) { | ||
throw new Error("WebGPUAdapter.attach() not implemented"); | ||
} | ||
}; | ||
var webgpuAdapter = new WebGPUAdapter(); | ||
return __toCommonJS(bundle_exports); | ||
@@ -1693,0 +1711,0 @@ })(); |
@@ -7,4 +7,4 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
else root['luma'] = factory();})(globalThis, function () { | ||
var __exports__=(()=>{var ge=Object.create;var A=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var we=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var ve=(n,e,t)=>e in n?A(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Se=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),Ce=(n,e)=>{for(var t in e)A(n,t,{get:e[t],enumerable:!0})},I=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of xe(e))!ye.call(n,i)&&i!==t&&A(n,i,{get:()=>e[i],enumerable:!(r=be(e,i))||r.enumerable});return n},F=(n,e,t)=>(I(n,e,"default"),t&&I(t,e,"default")),d=(n,e,t)=>(t=n!=null?ge(we(n)):{},I(e||!n||!n.__esModule?A(t,"default",{value:n,enumerable:!0}):t,n)),Pe=n=>I(A({},"__esModule",{value:!0}),n);var ee=(n,e,t)=>(ve(n,typeof e!="symbol"?e+"":e,t),t);var o=Se((Fe,te)=>{te.exports=globalThis.luma});var D={};Ce(D,{WebGPUBuffer:()=>b,WebGPUDevice:()=>_,WebGPUSampler:()=>u,WebGPUShader:()=>v,WebGPUTexture:()=>y});F(D,d(o(),1));var p=d(o(),1);var O=d(o(),1);function Ee(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=Ee(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 R=d(o(),1);function w(n){if(n.includes("webgl"))throw new Error("webgl-only format");return n}var re=d(o(),1),u=class extends re.Sampler{device;handle;constructor(e,t){super(e,t),this.device=e;let r={...this.props};r.type!=="comparison-sampler"&&delete r.compare,this.handle=this.handle||this.device.handle.createSampler(r),this.handle.label=this.props.id}destroy(){this.handle=null}};var ne=d(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 Be={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},y=class extends R.Texture{device;handle;height=1;width=1;sampler;view;constructor(e,t){if(super(e,t),this.device=e,t.data instanceof Promise){t.data.then(r=>{this.props={...this.props,data:r},this.initialize(this.props)});return}this.initialize(t)}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&&this.setData({data:this.props.data}),this.width=this.handle.width,this.height=this.handle.height,this.sampler=e.sampler instanceof u?e.sampler:new u(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||R.Texture.TEXTURE|R.Texture.COPY_DST,dimension:Be[this.dimension],format:w(this.format),mipLevelCount:this.mipLevels,sampleCount:this.props.samples})}createGPUTextureView(){return this.handle.createView({label:this.id})}setSampler(e){return this.sampler=e instanceof u?e:new u(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){return this.setImage({source:e.data})}setImage(e){let{source:t,width:r=e.source.width,height:i=e.source.height,depth:s=1,sourceX:a=0,sourceY:l=0,mipLevel:c=0,x:h=0,y:g=0,z:m=0,aspect:B="all",colorSpace:X="srgb",premultipliedAlpha:fe=!1}=e;return this.device.handle.queue.copyExternalImageToTexture({source:t,origin:[a,l]},{texture:this.handle,origin:[h,g,m],mipLevel:c,aspect:B,colorSpace:X,premultipliedAlpha:fe},[r,i,s]),{width:r,height:i}}};var ie=d(o(),1);var M=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 u?e:new u(this.device,e),this}};var W=d(o(),1),v=class extends W.Shader{device;handle;constructor(e,t){super(e,t),this.device=e,this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||this.createHandle(),this.handle.label=this.props.id,this._checkCompilationError(this.device.handle.popErrorScope())}async _checkCompilationError(e){let t=await e;if(t){this.debugShader();let r=await this.getCompilationInfo();throw W.log.error(`Shader compilation error: ${t.message}`,r)(),new Error(`Shader compilation error: ${t.message}`)}}destroy(){this.handle=null}async getCompilationInfo(){return(await this.handle.getCompilationInfo()).messages}createHandle(){let{source:e}=this.props,t=e.includes("#version");if(this.props.language==="glsl"||t)throw new Error("GLSL shaders are not supported in WebGPU");return this.device.handle.createShaderModule({code:e})}};var C=d(o(),1);function f(n){return n.depthStencil=n.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},n.depthStencil}function k(n){return f(n).stencilFront}function U(n){return f(n).stencilBack}var Ae={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=f(t);r.depthWriteEnabled=e},depthCompare:(n,e,t)=>{let r=f(t);r.depthCompare=e},depthFormat:(n,e,t)=>{let r=f(t);r.format=e},depthBias:(n,e,t)=>{let r=f(t);r.depthBias=e},depthBiasSlopeScale:(n,e,t)=>{let r=f(t);r.depthBiasSlopeScale=e},depthBiasClamp:(n,e,t)=>{let r=f(t);r.depthBiasClamp=e},stencilReadMask:(n,e,t)=>{let r=f(t);r.stencilReadMask=e},stencilWriteMask:(n,e,t)=>{let r=f(t);r.stencilWriteMask=e},stencilCompare:(n,e,t)=>{let r=k(t),i=U(t);r.compare=e,i.compare=e},stencilPassOperation:(n,e,t)=>{let r=k(t),i=U(t);r.passOp=e,i.passOp=e},stencilFailOperation:(n,e,t)=>{let r=k(t),i=U(t);r.failOp=e,i.failOp=e},stencilDepthFailOperation:(n,e,t)=>{let r=k(t),i=U(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)}},Te={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,{...Te,...n}),Ge(n,e)}function Ge(n,e){for(let[t,r]of Object.entries(e)){let i=Ae[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 V(n,e,t,r){let i=_e(r,t);return n.createBindGroup({layout:e,entries:i})}function Le(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 _e(n,e){let t=[];for(let[r,i]of Object.entries(n)){let s=Le(e,r);s&&t.push(De(i,s.location))}return t}function De(n,e){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{binding:e,resource:n.handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var S=d(o(),1);function J(n){if(n.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${n}`);return n}function he(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,m=oe(n,g,r),B=m?.location;a=m?.stepMode||(m?.name.startsWith("instance")?"instance":"vertex"),s.push({format:J(h.format||i.format),offset:h.byteOffset,shaderLocation:B}),l+=(0,S.decodeVertexFormat)(c).byteLength}else{let h=oe(n,i.name,r);if(!h)continue;l=(0,S.decodeVertexFormat)(c).byteLength,a=h.stepMode||(h.name.startsWith("instance")?"instance":"vertex"),s.push({format:J(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,S.decodeVertexFormat)("float32x3").byteLength,stepMode:i.stepMode||(i.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:J("float32x3"),offset:0,shaderLocation:i.location}]});return t}function oe(n,e,t){let r=n.attributes.find(i=>i.name===e);if(!r)return S.log.warn(`Unknown attribute ${e}`)(),null;if(t.has(e))throw new Error(`Duplicate attribute ${e}`);return t.add(e),r}var q=class extends C.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();C.log.groupCollapsed(1,`new WebGPURenderPipeline(${this.id})`)(),C.log.probe(1,JSON.stringify(r,null,2))(),C.log.groupEnd(1)(),this.handle=this.device.handle.createRenderPipeline(r)}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;t.handle.setPipeline(this.handle);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:he(this.shaderLayout,this.props.bufferLayout)},t={module:this.props.fs.handle,entryPoint:this.props.fragmentEntryPoint||"main",targets:[{format:w(this.device.getCanvasContext().format)}]},r={vertex:e,fragment:t,primitive:{topology:this.props.topology},layout:"auto"};return ae(r,this.props.parameters),r}};var de=d(o(),1),P=class extends de.Framebuffer{device;colorAttachments=[];depthStencilAttachment=null;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}};var le=d(o(),1);var $=class extends le.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 E=d(o(),1),z=class extends E.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.handle=this.props.handle||e.commandEncoder.beginRenderPass(i),this.handle.label=this.props.id,E.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),E.log.probe(3,JSON.stringify(i,null,2))(),E.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=>({loadOp:this.props.clearColor!==!1?"clear":"load",colorClearValue:this.props.clearColor||[0,0,0,0],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),r.depthClearValue=this.props.clearDepth||0,!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),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 G=d(o(),1);var st=globalThis.document||{},at=globalThis.process||{},ot=globalThis.console,pe=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 ce(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process?.browser)||N()}function Z(n){return!n&&!ce()?"Node":N(n)?"Electron":(n||pe.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown"}var j=class extends G.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&&(G.log.warn("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&&(G.log.warn(`setting vertex buffer ${a}`,l?.handle)(),i.handle.setVertexBuffer(a,l?.handle))}}unbindAfterRender(e){}static isConstantAttributeZeroSupported(e){return Z()==="Chrome"}};var Y=d(o(),1);var L=class extends Y.CanvasContext{device;gpuCanvasContext;format=navigator.gpu.getPreferredCanvasFormat();depthStencilFormat="depth24plus";depthStencilAttachment=null;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 P(this.device,{colorAttachments:[e],depthStencilAttachment:this.depthStencilAttachment})}update(){let[e,t]=this.getPixelSize();(e!==this.width||t!==this.height)&&(this.width=e,this.height=t,this.depthStencilAttachment&&(this.depthStencilAttachment.destroy(),this.depthStencilAttachment=null),this.gpuCanvasContext.configure({device:this.device.handle,format:w(this.format),colorSpace:this.props.colorSpace,alphaMode:this.props.alphaMode}),Y.log.log(1,`Resized to ${this.width}x${this.height}px`)())}resize(e){this.update()}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 me=d(o(),1),H=class extends me.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 K=class extends p.Device{type="webgpu";handle;adapter;adapterInfo;features;info;limits;lost;canvasContext=null;_isLost=!1;commandEncoder=null;renderPass=null;static isSupported(){return Boolean(typeof navigator<"u"&&navigator.gpu)}static async create(e){if(!navigator.gpu)throw new Error("WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu");p.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();p.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,m=t.limits[g];typeof m=="number"&&(s[g]=m)}}let a=await t.requestDevice({requiredFeatures:i,requiredLimits:s});p.log.probe(1,"GPUDevice available")(),typeof e.canvas=="string"&&(await p.CanvasContext.pageLoaded,p.log.probe(1,"DOM is loaded")());let l=new K(a,t,r,e);return p.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),p.log.table(1,l.info)(),p.log.groupEnd(1)(),l}constructor(e,t,r,i){super({...i,id:i.id||"webgpu-device"}),this.handle=e,this.adapter=t,this.adapterInfo=r,this.info=this._getInfo(),this.features=this._getFeatures(),this.limits=this.handle.limits,e.addEventListener("uncapturederror",s=>{let a=s instanceof GPUUncapturedErrorEvent?s.error.message:"Unknown error";this.error(new Error(a))}),this.lost=new Promise(async s=>{let a=await this.handle.lost;this._isLost=!0,s({reason:"destroyed",message:a.message})}),this.canvasContext=new L(this,this.adapter,{canvas:i.canvas,height:i.height,width:i.width,container:i.container})}destroy(){this.handle.destroy()}isTextureFormatSupported(e){return!e.includes("webgl")}isTextureFormatFilterable(e){return this.isTextureFormatSupported(e)&&!e.startsWith("depth")&&!e.startsWith("stencil")}isTextureFormatRenderable(e){return this.isTextureFormatSupported(e)}get isLost(){return this._isLost}createBuffer(e){let t=this._getBufferProps(e);return new b(this,t)}_createTexture(e){return new y(this,e)}createExternalTexture(e){return new M(this,e)}createShader(e){return new v(this,e)}createSampler(e){return new u(this,e)}createRenderPipeline(e){return new q(this,e)}createFramebuffer(e){return new P(this,e)}createComputePipeline(e){return new $(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 L(this,this.adapter,e)}submit(){let e=this.commandEncoder?.finish();e&&this.handle.queue.submit([e]),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 p.DeviceFeatures(Array.from(e),this.props.disabledFeatures)}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:m=s.height,depth:B=1}=e,X=s;this.handle?.queue.copyExternalImageToTexture({source:t,origin:[r,i]},{texture:X.handle,origin:[0,0,0],mipLevel:a,aspect:l,colorSpace:c,premultipliedAlpha:h},[g,m,B])}},_=K;ee(_,"type","webgpu");return Pe(D);})(); | ||
var __exports__=(()=>{var xe=Object.create;var F=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Ce=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),Pe=(n,e)=>{for(var t in e)F(n,t,{get:e[t],enumerable:!0})},I=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ye(e))!Se.call(n,i)&&i!==t&&F(n,i,{get:()=>e[i],enumerable:!(r=we(e,i))||r.enumerable});return n},O=(n,e,t)=>(I(n,e,"default"),t&&I(t,e,"default")),h=(n,e,t)=>(t=n!=null?xe(ve(n)):{},I(e||!n||!n.__esModule?F(t,"default",{value:n,enumerable:!0}):t,n)),Ee=n=>I(F({},"__esModule",{value:!0}),n);var o=Ce((Oe,te)=>{te.exports=globalThis.luma});var D={};Pe(D,{WebGPUBuffer:()=>b,WebGPUDevice:()=>w,WebGPUSampler:()=>p,WebGPUShader:()=>C,WebGPUTexture:()=>S,webgpuAdapter:()=>fe});O(D,h(o(),1));var u=h(o(),1);var X=h(o(),1);var R=h(o(),1);function Be(n){return n.byteLength||n.data?.byteLength||0}var b=class extends R.Buffer{device;handle;byteLength;constructor(e,t){super(e,t),this.device=e,this.byteLength=Be(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:R.Buffer.MAP_READ|R.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 y(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};r.type!=="comparison-sampler"&&delete r.compare,this.handle=this.handle||this.device.handle.createSampler(r),this.handle.label=this.props.id}destroy(){this.handle=null}};var ne=h(o(),1),G=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 Ae={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},S=class extends v.Texture{device;handle;height=1;width=1;sampler;view;constructor(e,t){if(super(e,t),this.device=e,t.data instanceof Promise){t.data.then(r=>{this.props={...this.props,data:r},this.initialize(this.props)});return}this.initialize(t)}destroy(){this.handle?.destroy(),this.handle=null}createView(e){return new G(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.setImage({source: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 G(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:Ae[this.dimension],format:y(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){let t=e.data;if(ArrayBuffer.isView(e.data)){let r=new Uint8ClampedArray(e.data.buffer);t=new ImageData(r,this.width,this.height)}return this.setImage({source:t})}setImage(e){let t=v.Texture.getExternalImageSize(e.source),{source:r,width:i=t.width,height:s=t.height,depth:a=1,sourceX:l=0,sourceY:c=0,mipLevel:d=0,x:g=0,y:m=0,z:T=0,aspect:J="all",colorSpace:ge="srgb",premultipliedAlpha:be=!1}=e;return this.device.handle.queue.copyExternalImageToTexture({source:r,origin:[l,c]},{texture:this.handle,origin:[g,m,T],mipLevel:d,aspect:J,colorSpace:ge,premultipliedAlpha:be},[i,s,a]),{width:i,height:s}}};var ie=h(o(),1);var M=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 W=h(o(),1),C=class extends W.Shader{device;handle;constructor(e,t){super(e,t),this.device=e,this.device.handle.pushErrorScope("validation"),this.handle=this.props.handle||this.createHandle(),this.handle.label=this.props.id,this._checkCompilationError(this.device.handle.popErrorScope())}async _checkCompilationError(e){let t=await e;if(t){this.debugShader();let r=await this.getCompilationInfo();throw W.log.error(`Shader compilation error: ${t.message}`,r)(),new Error(`Shader compilation error: ${t.message}`)}}destroy(){this.handle=null}async getCompilationInfo(){return(await this.handle.getCompilationInfo()).messages}createHandle(){let{source:e}=this.props,t=e.includes("#version");if(this.props.language==="glsl"||t)throw new Error("GLSL shaders are not supported in WebGPU");return this.device.handle.createShaderModule({code:e})}};var E=h(o(),1);function f(n){return n.depthStencil=n.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},n.depthStencil}function U(n){return f(n).stencilFront}function k(n){return f(n).stencilBack}var Te={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=f(t);r.depthWriteEnabled=e},depthCompare:(n,e,t)=>{let r=f(t);r.depthCompare=e},depthFormat:(n,e,t)=>{let r=f(t);r.format=e},depthBias:(n,e,t)=>{let r=f(t);r.depthBias=e},depthBiasSlopeScale:(n,e,t)=>{let r=f(t);r.depthBiasSlopeScale=e},depthBiasClamp:(n,e,t)=>{let r=f(t);r.depthBiasClamp=e},stencilReadMask:(n,e,t)=>{let r=f(t);r.stencilReadMask=e},stencilWriteMask:(n,e,t)=>{let r=f(t);r.stencilWriteMask=e},stencilCompare:(n,e,t)=>{let r=U(t),i=k(t);r.compare=e,i.compare=e},stencilPassOperation:(n,e,t)=>{let r=U(t),i=k(t);r.passOp=e,i.passOp=e},stencilFailOperation:(n,e,t)=>{let r=U(t),i=k(t);r.failOp=e,i.failOp=e},stencilDepthFailOperation:(n,e,t)=>{let r=U(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)}},Ge={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,{...Ge,...n}),Le(n,e)}function Le(n,e){for(let[t,r]of Object.entries(e)){let i=Te[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=De(r,t);return n.createBindGroup({layout:e,entries:i})}function _e(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 De(n,e){let t=[];for(let[r,i]of Object.entries(n)){let s=_e(e,r);s&&t.push(Ie(i,s.location))}return t}function Ie(n,e){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{binding:e,resource:n.handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var P=h(o(),1);function Z(n){if(n.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${n}`);return n}function he(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,m=oe(n,g,r),T=m?.location;a=m?.stepMode||(m?.name.startsWith("instance")?"instance":"vertex"),s.push({format:Z(d.format||i.format),offset:d.byteOffset,shaderLocation:T}),l+=(0,P.decodeVertexFormat)(c).byteLength}else{let d=oe(n,i.name,r);if(!d)continue;l=(0,P.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,P.decodeVertexFormat)("float32x3").byteLength,stepMode:i.stepMode||(i.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:Z("float32x3"),offset:0,shaderLocation:i.location}]});return t}function oe(n,e,t){let r=n.attributes.find(i=>i.name===e);if(!r)return P.log.warn(`Unknown attribute ${e}`)(),null;if(t.has(e))throw new Error(`Duplicate attribute ${e}`);return t.add(e),r}var q=class extends E.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();E.log.groupCollapsed(1,`new WebGPURenderPipeline(${this.id})`)(),E.log.probe(1,JSON.stringify(r,null,2))(),E.log.groupEnd(1)(),this.handle=this.device.handle.createRenderPipeline(r)}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;t.handle.setPipeline(this.handle);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:he(this.shaderLayout,this.props.bufferLayout)},t={module:this.props.fs.handle,entryPoint:this.props.fragmentEntryPoint||"main",targets:[{format:y(this.device.getCanvasContext().format)}]},r={vertex:e,fragment:t,primitive:{topology:this.props.topology},layout:"auto"};return ae(r,this.props.parameters),r}};var de=h(o(),1),B=class extends de.Framebuffer{device;colorAttachments=[];depthStencilAttachment=null;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}};var le=h(o(),1);var z=class extends le.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 A=h(o(),1),$=class extends A.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.handle=this.props.handle||e.commandEncoder.beginRenderPass(i),this.handle.label=this.props.id,A.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),A.log.probe(3,JSON.stringify(i,null,2))(),A.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=>({loadOp:this.props.clearColor!==!1?"clear":"load",colorClearValue:this.props.clearColor||[0,0,0,0],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),r.depthClearValue=this.props.clearDepth||0,!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 pe=h(o(),1),Q=class extends pe.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=h(o(),1);var at=globalThis.document||{},ot=globalThis.process||{},ht=globalThis.console,ue=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 ce(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process?.browser)||N()}function K(n){return!n&&!ce()?"Node":N(n)?"Electron":(n||ue.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown"}var j=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.warn("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.warn(`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;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 B(this.device,{colorAttachments:[e],depthStencilAttachment:this.depthStencilAttachment})}update(){let[e,t]=this.getPixelSize();(e!==this.width||t!==this.height)&&(this.width=e,this.height=t,this.depthStencilAttachment&&(this.depthStencilAttachment.destroy(),this.depthStencilAttachment=null),this.gpuCanvasContext.configure({device:this.device.handle,format:y(this.format),colorSpace:this.props.colorSpace,alphaMode:this.props.alphaMode}),Y.log.log(1,`Resized to ${this.width}x${this.height}px`)())}resize(e){this.update()}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 me=h(o(),1),H=class extends me.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 w=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){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 error";this.error(new Error(a))}),this.lost=new Promise(async s=>{let a=await this.handle.lost;this._isLost=!0,s({reason:"destroyed",message:a.message})}),this.canvasContext=new _(this,this.adapter,{canvas:e.canvas,height:e.height,width:e.width,container:e.container})}destroy(){this.handle.destroy()}isTextureFormatSupported(e){return!e.includes("webgl")}isTextureFormatFilterable(e){return this.isTextureFormatSupported(e)&&!e.startsWith("depth")&&!e.startsWith("stencil")}isTextureFormatRenderable(e){return this.isTextureFormatSupported(e)}get isLost(){return this._isLost}createBuffer(e){let t=this._getBufferProps(e);return new b(this,t)}_createTexture(e){return new S(this,e)}createExternalTexture(e){return new M(this,e)}createShader(e){return new C(this,e)}createSampler(e){return new p(this,e)}createRenderPipeline(e){return new q(this,e)}createFramebuffer(e){return new B(this,e)}createComputePipeline(e){return new z(this,e)}createVertexArray(e){return new j(this,e)}beginRenderPass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new $(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.queue.submit([e]),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)}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:m=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:d},[g,m,T])}};var ee=class extends u.Adapter{type="webgpu";constructor(){super(),w.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");u.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();u.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,m=t.limits[g];typeof m=="number"&&(s[g]=m)}}let a=await t.requestDevice({requiredFeatures:i,requiredLimits:s});u.log.probe(1,"GPUDevice available")(),typeof e.canvas=="string"&&(await u.CanvasContext.pageLoaded,u.log.probe(1,"DOM is loaded")());let l=new w(e,a,t,r);return u.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),u.log.table(1,l.info)(),u.log.groupEnd(1)(),l}async attach(e){throw new Error("WebGPUAdapter.attach() not implemented")}},fe=new ee;return Ee(D);})(); | ||
return __exports__; | ||
}); |
@@ -0,1 +1,3 @@ | ||
export type { WebGPUAdapter } from "./adapter/webgpu-adapter.js"; | ||
export { webgpuAdapter } from "./adapter/webgpu-adapter.js"; | ||
export { WebGPUDevice } from "./adapter/webgpu-device.js"; | ||
@@ -2,0 +4,0 @@ export { WebGPUBuffer } from "./adapter/resources/webgpu-buffer.js"; |
// luma.gl | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) vis.gl contributors | ||
// WEBGPU ADAPTER | ||
export { webgpuAdapter } from "./adapter/webgpu-adapter.js"; | ||
// WEBGPU CLASSES (typically not accessed directly) | ||
export { WebGPUDevice } from "./adapter/webgpu-device.js"; | ||
// WEBGPU CLASSES (typically not accessed directly) | ||
export { WebGPUBuffer } from "./adapter/resources/webgpu-buffer.js"; | ||
@@ -8,0 +8,0 @@ export { WebGPUTexture } from "./adapter/resources/webgpu-texture.js"; |
{ | ||
"name": "@luma.gl/webgpu", | ||
"version": "9.1.0-alpha.2", | ||
"version": "9.1.0-alpha.9", | ||
"description": "WebGPU adapter for the luma.gl core API", | ||
@@ -46,3 +46,3 @@ "type": "module", | ||
}, | ||
"gitHead": "cb258afdefd2d5712d2decca35c746dd9d77a03e" | ||
"gitHead": "ff05b21269181dbb782ba7c8c1546900288ee6a1" | ||
} |
@@ -17,3 +17,4 @@ // luma.gl, MIT license | ||
TextureArrayData, | ||
TextureCubeArrayData | ||
TextureCubeArrayData, | ||
ExternalImage | ||
} from '@luma.gl/core'; | ||
@@ -86,3 +87,7 @@ import {Texture} from '@luma.gl/core'; | ||
if (this.props.data) { | ||
this.setData({data: this.props.data}); | ||
if (Texture.isExternalImage(this.props.data)) { | ||
this.setImage({source: this.props.data}); | ||
} else { | ||
this.setData({data: this.props.data}); | ||
} | ||
} | ||
@@ -182,9 +187,32 @@ | ||
setData(options: {data: any}) { | ||
return this.setImage({source: options.data}); | ||
setData(options: {data: any}): {width: number; height: number} { | ||
let source = options.data; | ||
if (ArrayBuffer.isView(options.data)) { | ||
const clampedArray = new Uint8ClampedArray(options.data.buffer); | ||
// TODO - pass through src data color space as ImageData Options? | ||
source = new ImageData(clampedArray, this.width, this.height); | ||
} | ||
return this.setImage({source}); | ||
} | ||
// setDataFromTypedArray(data): this { | ||
// const textureDataBuffer = this.device.handle.createBuffer({ | ||
// size: data.byteLength, | ||
// usage: Buffer.COPY_DST | Buffer.COPY_SRC, | ||
// mappedAtCreation: true | ||
// }); | ||
// new Uint8Array(textureDataBuffer.getMappedRange()).set(data); | ||
// textureDataBuffer.unmap(); | ||
// this.setBuffer(textureDataBuffer); | ||
// textureDataBuffer.destroy(); | ||
// return this; | ||
// } | ||
/** Set image */ | ||
setImage(options: { | ||
source: ImageBitmap | HTMLCanvasElement | OffscreenCanvas; | ||
source: ExternalImage; | ||
width?: number; | ||
@@ -203,6 +231,7 @@ height?: number; | ||
}): {width: number; height: number} { | ||
const size = Texture.getExternalImageSize(options.source); | ||
const { | ||
source, | ||
width = options.source.width, | ||
height = options.source.height, | ||
width = size.width, | ||
height = size.height, | ||
depth = 1, | ||
@@ -290,17 +319,2 @@ sourceX = 0, | ||
setData(data): this { | ||
const textureDataBuffer = this.device.handle.createBuffer({ | ||
size: data.byteLength, | ||
usage: Buffer.COPY_DST | Buffer.COPY_SRC, | ||
mappedAtCreation: true | ||
}); | ||
new Uint8Array(textureDataBuffer.getMappedRange()).set(data); | ||
textureDataBuffer.unmap(); | ||
this.setBuffer(textureDataBuffer); | ||
textureDataBuffer.destroy(); | ||
return this; | ||
} | ||
setBuffer(textureDataBuffer, {bytesPerRow}): this { | ||
@@ -307,0 +321,0 @@ const commandEncoder = this.device.handle.createCommandEncoder(); |
@@ -33,3 +33,3 @@ // luma.gl | ||
} from '@luma.gl/core'; | ||
import {Device, DeviceFeatures, CanvasContext, log} from '@luma.gl/core'; | ||
import {Device, DeviceFeatures} from '@luma.gl/core'; | ||
import {WebGPUBuffer} from './resources/webgpu-buffer'; | ||
@@ -53,4 +53,2 @@ import {WebGPUTexture} from './resources/webgpu-texture'; | ||
export class WebGPUDevice extends Device { | ||
static type: string = 'webgpu'; | ||
/** type of this device */ | ||
@@ -77,74 +75,7 @@ readonly type = 'webgpu'; | ||
/** Check if WebGPU is available */ | ||
static isSupported(): boolean { | ||
return Boolean(typeof navigator !== 'undefined' && navigator.gpu); | ||
} | ||
static async create(props: DeviceProps): Promise<WebGPUDevice> { | ||
if (!navigator.gpu) { | ||
throw new Error( | ||
'WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu' | ||
); | ||
} | ||
log.groupCollapsed(1, 'WebGPUDevice created')(); | ||
const adapter = await navigator.gpu.requestAdapter({ | ||
powerPreference: 'high-performance' | ||
// forceSoftware: false | ||
}); | ||
if (!adapter) { | ||
throw new Error('Failed to request WebGPU adapter'); | ||
} | ||
const adapterInfo = await adapter.requestAdapterInfo(); | ||
log.probe(2, 'Adapter available', adapterInfo)(); | ||
const requiredFeatures: GPUFeatureName[] = []; | ||
const requiredLimits: Record<string, number> = {}; | ||
if (props.requestMaxLimits) { | ||
// Require all features | ||
requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[])); | ||
// Require all limits | ||
// Filter out chrome specific keys (avoid crash) | ||
const limits = Object.keys(adapter.limits).filter( | ||
key => !['minSubgroupSize', 'maxSubgroupSize'].includes(key) | ||
); | ||
for (const key of limits) { | ||
const limit = key as keyof GPUSupportedLimits; | ||
const value = adapter.limits[limit]; | ||
if (typeof value === 'number') { | ||
requiredLimits[limit] = value; | ||
} | ||
} | ||
} | ||
const gpuDevice = await adapter.requestDevice({ | ||
requiredFeatures, | ||
requiredLimits | ||
}); | ||
log.probe(1, 'GPUDevice available')(); | ||
if (typeof props.canvas === 'string') { | ||
await CanvasContext.pageLoaded; | ||
log.probe(1, 'DOM is loaded')(); | ||
} | ||
const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props); | ||
log.probe( | ||
1, | ||
'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features' | ||
)(); | ||
log.table(1, device.info)(); | ||
log.groupEnd(1)(); | ||
return device; | ||
} | ||
constructor( | ||
props: DeviceProps, | ||
device: GPUDevice, | ||
adapter: GPUAdapter, | ||
adapterInfo: GPUAdapterInfo, | ||
props: DeviceProps | ||
adapterInfo: GPUAdapterInfo | ||
) { | ||
@@ -151,0 +82,0 @@ super({...props, id: props.id || 'webgpu-device'}); |
@@ -6,5 +6,7 @@ // luma.gl | ||
// WEBGPU ADAPTER | ||
export {WebGPUDevice} from './adapter/webgpu-device'; | ||
export type {WebGPUAdapter} from './adapter/webgpu-adapter'; | ||
export {webgpuAdapter} from './adapter/webgpu-adapter'; | ||
// WEBGPU CLASSES (typically not accessed directly) | ||
export {WebGPUDevice} from './adapter/webgpu-device'; | ||
export {WebGPUBuffer} from './adapter/resources/webgpu-buffer'; | ||
@@ -11,0 +13,0 @@ export {WebGPUTexture} from './adapter/resources/webgpu-texture'; |
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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
449344
99
8322