@luma.gl/webgpu 9.0.0-beta.5 → 9.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/helpers/accessor-to-format.js +4 -1
- package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
- package/dist/adapter/helpers/convert-texture-format.js +3 -0
- package/dist/adapter/helpers/get-bind-group.d.ts +3 -3
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +3 -0
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +9 -2
- package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.js +3 -0
- package/dist/adapter/resources/webgpu-buffer.d.ts +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +19 -10
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +7 -1
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +8 -0
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +15 -9
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +39 -17
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +14 -4
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +37 -15
- package/dist/adapter/resources/webgpu-external-texture.d.ts +2 -2
- package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-external-texture.js +14 -7
- package/dist/adapter/resources/webgpu-framebuffer.d.ts +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.js +3 -0
- package/dist/adapter/resources/webgpu-query-set.d.ts +17 -0
- package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-query-set.js +27 -0
- package/dist/adapter/resources/webgpu-render-pass.d.ts +4 -2
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +27 -9
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts +52 -5
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +76 -66
- package/dist/adapter/resources/webgpu-sampler.d.ts +1 -1
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +3 -0
- package/dist/adapter/resources/webgpu-shader.d.ts +2 -5
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +10 -20
- package/dist/adapter/resources/webgpu-texture-view.d.ts +20 -0
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-texture-view.js +35 -0
- package/dist/adapter/resources/webgpu-texture.d.ts +8 -8
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +25 -22
- package/dist/adapter/resources/webgpu-vertex-array.d.ts +7 -9
- package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +11 -13
- package/dist/adapter/webgpu-canvas-context.d.ts +3 -3
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +8 -5
- package/dist/adapter/webgpu-device.d.ts +26 -28
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +81 -74
- package/dist/dist.dev.js +339 -305
- package/dist/index.cjs +313 -250
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist.min.js +1 -1
- package/package.json +2 -2
- package/src/adapter/helpers/accessor-to-format.ts +5 -1
- package/src/adapter/helpers/convert-texture-format.ts +4 -1
- package/src/adapter/helpers/get-bind-group.ts +12 -6
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +12 -4
- package/src/adapter/helpers/webgpu-parameters.ts +79 -15
- package/src/adapter/resources/webgpu-buffer.ts +24 -11
- package/src/adapter/resources/webgpu-command-encoder.ts +24 -9
- package/src/adapter/resources/webgpu-compute-pass.ts +45 -22
- package/src/adapter/resources/webgpu-compute-pipeline.ts +48 -16
- package/src/adapter/resources/webgpu-external-texture.ts +14 -6
- package/src/adapter/resources/webgpu-framebuffer.ts +4 -0
- package/src/adapter/resources/webgpu-query-set.ts +37 -0
- package/src/adapter/resources/webgpu-render-pass.ts +37 -14
- package/src/adapter/resources/webgpu-render-pipeline.ts +75 -115
- package/src/adapter/resources/webgpu-sampler.ts +4 -1
- package/src/adapter/resources/webgpu-shader.ts +11 -25
- package/src/adapter/resources/webgpu-texture-view.ts +46 -0
- package/src/adapter/resources/webgpu-texture.ts +33 -28
- package/src/adapter/resources/webgpu-vertex-array.ts +25 -20
- package/src/adapter/webgpu-canvas-context.ts +10 -5
- package/src/adapter/webgpu-device.ts +99 -76
- package/src/index.ts +2 -1
- package/dist/adapter/helpers/generate-mipmaps.d.ts +0 -10
- package/dist/adapter/helpers/generate-mipmaps.d.ts.map +0 -1
- package/dist/adapter/helpers/generate-mipmaps.js +0 -94
- package/dist/adapter/resources/webgpu-query.d.ts +0 -1
- package/dist/adapter/resources/webgpu-query.d.ts.map +0 -1
- package/dist/adapter/resources/webgpu-query.js +0 -43
- package/dist/adapter/webgpu-types.d.ts +0 -1
- package/dist/adapter/webgpu-types.d.ts.map +0 -1
- package/dist/adapter/webgpu-types.js +0 -0
- package/dist/glsl/glsllang.d.ts +0 -3
- package/dist/glsl/glsllang.d.ts.map +0 -1
- package/dist/glsl/glsllang.js +0 -12
- package/src/adapter/helpers/generate-mipmaps.ts +0 -107
- package/src/adapter/resources/webgpu-query.ts +0 -43
- package/src/adapter/webgpu-types.ts +0 -0
- package/src/glsl/glsllang.ts +0 -14
package/dist.min.js
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
5
|
else if (typeof exports === 'object') exports['luma'] = factory();
|
|
6
6
|
else root['luma'] = factory();})(globalThis, function () {
|
|
7
|
-
var __exports__=(()=>{var le=Object.create;var D=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var fe=(i,e,t)=>e in i?D(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var Pe=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),be=(i,e)=>{for(var t in e)D(i,t,{get:e[t],enumerable:!0})},Y=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ce(e))!me.call(i,n)&&n!==t&&D(i,n,{get:()=>e[n],enumerable:!(r=ue(e,n))||r.enumerable});return i};var d=(i,e,t)=>(t=i!=null?le(he(i)):{},Y(e||!i||!i.__esModule?D(t,"default",{value:i,enumerable:!0}):t,i)),ge=i=>Y(D({},"__esModule",{value:!0}),i);var X=(i,e,t)=>(fe(i,typeof e!="symbol"?e+"":e,t),t);var a=Pe((We,J)=>{J.exports=globalThis.luma});var Ce={};be(Ce,{WebGPUBuffer:()=>g,WebGPUDevice:()=>R,WebGPUSampler:()=>u,WebGPUShader:()=>G,WebGPUTexture:()=>x});var h=d(a(),1);var E=d(a(),1);function ve(i){return i.byteLength||i.data?.byteLength||0}var g=class extends E.Buffer{device;handle;byteLength;constructor(e,t){super(e,t),this.device=e,this.byteLength=ve(t);let r=Boolean(t.data),n=Math.ceil(this.byteLength/4)*4;this.handle=this.props.handle||this.device.handle.createBuffer({size:n,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()}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 g(this.device,{usage:E.Buffer.MAP_READ|E.Buffer.COPY_DST,byteLength:t}),n=this.device.handle.createCommandEncoder();n.copyBufferToBuffer(this.handle,e,r.handle,0,t),this.device.handle.queue.submit([n.finish()]),await r.handle.mapAsync(GPUMapMode.READ,e,t);let o=r.handle.getMappedRange().slice(0);return r.handle.unmap(),r.destroy(),new Uint8Array(o)}_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 K=d(a(),1);function y(i){if(i.includes("webgl"))throw new Error("webgl-only format");return i}var Z=d(a(),1),u=class extends Z.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(){}};var ye={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},x=class extends K.Texture{device;handle;view;sampler;height=1;width=1;constructor(e,t){if(super(e,t),this.device=e,t.data instanceof Promise){t.data.then(r=>{this.props={...t,data:r},this.initialize(this.props)});return}this.initialize(t)}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=this.createView()}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.props.depth},dimension:ye[this.props.dimension],format:y(this.props.format),usage:this.props.usage,mipLevelCount:this.props.mipLevels,sampleCount:this.props.samples})}destroy(){this.handle.destroy()}setSampler(e){return this.sampler=e instanceof u?e:new u(this.device,e),this}setData(e){return this.setImage({source:e.data})}setImage(e){let{source:t,width:r=e.source.width,height:n=e.source.height,depth:o=1,sourceX:s=0,sourceY:p=0,mipLevel:l=0,x:v=0,y:b=0,z:S=0,aspect:B="all",colorSpace:C="srgb",premultipliedAlpha:z=!1}=e;return this.device.handle.queue.copyExternalImageToTexture({source:t,origin:[s,p]},{texture:this.handle,origin:[v,b,S],mipLevel:l,aspect:B,colorSpace:C,premultipliedAlpha:z},[r,n,o]),{width:r,height:n}}createView(){return this.handle.createView({label:this.id})}};var Q=d(a(),1);var A=class extends Q.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(){}setSampler(e){return this.sampler=e instanceof u?e:new u(this.device,e),this}};var L=d(a(),1),G=class extends L.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 L.log.error(`Shader compilation error: ${t.message}`,r)(),new Error(`Shader compilation error: ${t.message}`)}}destroy(){}async getCompilationInfo(){return(await this.handle.getCompilationInfo()).messages}createHandle(){let{source:e,stage:t}=this.props,r=this.props.language;switch(r==="auto"&&(r=e.includes("->")?"wgsl":"glsl"),r){case"wgsl":return this.device.handle.createShaderModule({code:e});case"glsl":return this.device.handle.createShaderModule({code:e,transform:n=>this.device.glslang.compileGLSL(n,t)});default:throw new Error(r)}}};var c=d(a(),1);function m(i){return i.depthStencil=i.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},i.depthStencil}var xe={cullMode:(i,e,t)=>{t.primitive=t.primitive||{},t.primitive.cullMode=e},frontFace:(i,e,t)=>{t.primitive=t.primitive||{},t.primitive.frontFace=e},depthWriteEnabled:(i,e,t)=>{let r=m(t);r.depthWriteEnabled=e},depthCompare:(i,e,t)=>{let r=m(t);r.depthCompare=e},depthFormat:(i,e,t)=>{let r=m(t);r.format=e},depthBias:(i,e,t)=>{let r=m(t);r.depthBias=e},depthBiasSlopeScale:(i,e,t)=>{let r=m(t);r.depthBiasSlopeScale=e},depthBiasClamp:(i,e,t)=>{let r=m(t);r.depthBiasClamp=e},stencilReadMask:(i,e,t)=>{let r=m(t);r.stencilReadMask=e},stencilWriteMask:(i,e,t)=>{let r=m(t);r.stencilWriteMask=e},stencilCompare:(i,e,t)=>{let r=m(t);r.stencilFront.compare=e,r.stencilBack.compare=e},stencilPassOperation:(i,e,t)=>{let r=m(t);r.stencilFront.passOp=e,r.stencilBack.passOp=e},stencilFailOperation:(i,e,t)=>{let r=m(t);r.stencilFront.failOp=e,r.stencilBack.failOp=e},stencilDepthFailOperation:(i,e,t)=>{let r=m(t);r.stencilFront.depthFailOp=e,r.stencilBack.depthFailOp=e},sampleCount:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.count=e},sampleMask:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.mask=e},sampleAlphaToCoverageEnabled:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.alphaToCoverageEnabled=e},colorMask:(i,e,t)=>{let r=ee(t);r[0].writeMask=e},blendColorOperation:(i,e,t)=>{ee(t)}},Ge={primitive:{cullMode:"back",topology:"triangle-list"},vertex:{module:void 0,entryPoint:"main"},fragment:{module:void 0,entryPoint:"main",targets:[]},layout:"auto"};function te(i,e={}){Object.assign(i,{...Ge,...i}),Ue(i,e)}function Ue(i,e){for(let[t,r]of Object.entries(e)){let n=xe[t];if(!n)throw new Error(`Illegal parameter ${t}`);n(t,r,i)}}function ee(i){if(i.fragment.targets=i.fragment?.targets||[],!Array.isArray(i.fragment?.targets))throw new Error("colorstate");return i.fragment?.targets?.length===0&&i.fragment.targets?.push({}),i.fragment?.targets}var f=d(a(),1);function re(i,e,t,r){let n=Se(r,t);return i.createBindGroup({layout:e,entries:n})}function we(i,e){let t=i.bindings.find(r=>r.name===e||`${r.name}uniforms`===e.toLocaleLowerCase());return t||f.log.warn(`Binding ${e} not set: Not found in shader layout.`)(),t}function Se(i,e){let t=[];for(let[r,n]of Object.entries(i)){let o=we(e,r);o&&t.push(Be(n,o.location))}return t}function Be(i,e){if(i instanceof f.Buffer)return{binding:e,resource:{buffer:(0,f.cast)(i).handle}};if(i instanceof f.Sampler)return{binding:e,resource:(0,f.cast)(i).handle};if(i instanceof f.Texture)return{binding:e,resource:(0,f.cast)(i).handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var U=d(a(),1);function N(i){if(i.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${i}`);return i}function ne(i,e){let t=[],r=new Set;for(let n of e){let o=[],s="vertex",p=0;if(n.attributes)for(let l of n.attributes){let v=l.attribute,b=ie(i,v,r);s=b.stepMode||(b.name.startsWith("instance")?"instance":"vertex"),o.push({format:N(l.format||n.format),offset:l.byteOffset,shaderLocation:b.location}),p+=(0,U.decodeVertexFormat)(n.format).byteLength}else{let l=ie(i,n.name,r);if(!l)continue;p=(0,U.decodeVertexFormat)(n.format).byteLength,s=l.stepMode||(l.name.startsWith("instance")?"instance":"vertex"),o.push({format:N(n.format),offset:0,shaderLocation:l.location})}t.push({arrayStride:n.byteStride||p,stepMode:s,attributes:o})}for(let n of i.attributes)r.has(n.name)||t.push({arrayStride:(0,U.decodeVertexFormat)("float32x3").byteLength,stepMode:n.stepMode||(n.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:N("float32x3"),offset:0,shaderLocation:n.location}]});return t}function ie(i,e,t){let r=i.attributes.find(n=>n.name===e);if(!r)return U.log.warn(`Unknown attribute ${e}`)(),null;if(t.has(e))throw new Error(`Duplicate attribute ${e}`);return t.add(e),r}var F=class extends c.RenderPipeline{device;handle;vs;fs=null;_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=(0,c.cast)(t.vs),this.fs=(0,c.cast)(t.fs)}destroy(){}setBindings(e){Object.assign(this.props.bindings,e)}setUniforms(e){if(!(0,c.isObjectEmpty)(e))throw new Error("WebGPU does not support uniforms")}draw(e){let t=(0,c.cast)(e.renderPass)||this.device.getDefaultRenderPass();t.handle.setPipeline(this.handle);let r=this._getBindGroup();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)}_getBindGroup(){return this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||re(this.device.handle,this._bindGroupLayout,this.props.shaderLayout,this.props.bindings),this._bindGroup}_getRenderPipelineDescriptor(){let e={module:(0,c.cast)(this.props.vs).handle,entryPoint:this.props.vsEntryPoint||"main",buffers:ne(this.props.shaderLayout,this.props.bufferLayout)},t;switch(this.props.fs&&(t={module:(0,c.cast)(this.props.fs).handle,entryPoint:this.props.fsEntryPoint||"main",targets:[{format:y(this.device?.canvasContext?.format)}]}),this.props.topology){case"triangle-fan-webgl":case"line-loop-webgl":throw new Error(`WebGPU does not support primitive topology ${this.props.topology}`);default:}let r={vertex:e,fragment:t,primitive:{topology:this.props.topology},layout:"auto"};return te(r,this.props.parameters),r}};var oe=d(a(),1),k=class extends oe.ComputePipeline{device;handle;constructor(e,t){super(e,t),this.device=e;let r=this.props.cs;this.handle=this.props.handle||this.device.handle.createComputePipeline({label:this.props.id,compute:{module:r.handle,entryPoint:this.props.csEntryPoint},layout:"auto"})}_getBindGroupLayout(){return this.handle.getBindGroupLayout(0)}};var P=d(a(),1),V=class extends P.RenderPass{device;handle;pipeline=null;constructor(e,t={}){super(e,t),this.device=e;let r=t.framebuffer||e.canvasContext.getCurrentFramebuffer(),n=this.getRenderPassDescriptor(r);P.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),P.log.probe(3,JSON.stringify(n,null,2))(),P.log.groupEnd(3)(),this.handle=this.props.handle||e.commandEncoder.beginRenderPass(n),this.handle.label=this.props.id}destroy(){}end(){this.handle.end()}setPipeline(e){this.pipeline=(0,P.cast)(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,n){this.handle.setIndexBuffer((0,P.cast)(e).handle,t,r,n)}setVertexBuffer(e,t,r=0){this.handle.setVertexBuffer(e,(0,P.cast)(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:n,viewport:o}=e;t&&this.handle.setBlendConstant(t),r&&this.handle.setStencilReference(r),n&&this.handle.setScissorRect(n[0],n[1],n[2],n[3]),o&&this.handle.setViewport(o[0],o[1],o[2],o[3],o[4],o[5])}pushDebugGroup(e){this.handle.pushDebugGroup(e)}popDebugGroup(){this.handle.popDebugGroup()}insertDebugMarker(e){this.handle.insertDebugMarker(e)}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.createView()})),e.depthStencilAttachment){t.depthStencilAttachment={view:e.depthStencilAttachment.createView()};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 ae=d(a(),1),M=class extends ae.ComputePass{device;handle;_bindGroupLayout=null;constructor(e,t){super(e,t),this.device=e,this.handle=this.props.handle||e.commandEncoder?.beginComputePass({label:this.props.id})}destroy(){}end(){this.handle.end()}setPipeline(e){let t=e;this.handle.setPipeline(t.handle),this._bindGroupLayout=t._getBindGroupLayout()}setBindings(e){throw new Error("fix me")}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 w=d(a(),1);function W(i){if(typeof window<"u"&&typeof window.process=="object"&&window.process.type==="renderer"||typeof process<"u"&&typeof process.versions=="object"&&Boolean(process.versions.electron))return!0;let e=typeof navigator=="object"&&typeof navigator.userAgent=="string"&&navigator.userAgent,t=i||e;return!!(t&&t.indexOf("Electron")>=0)}function q(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process.browser)||W()}var ft=globalThis.self||globalThis.window||globalThis.global,Pt=globalThis.window||globalThis.self||globalThis.global,bt=globalThis.document||{},gt=globalThis.process||{},vt=globalThis.console,se=globalThis.navigator||{};var j=globalThis;function _(i){if(!i&&!q())return"Node";if(W(i))return"Electron";let e=i||se.userAgent||"";if(e.indexOf("Edge")>-1)return"Edge";let t=e.indexOf("MSIE ")!==-1,r=e.indexOf("Trident/")!==-1;return t||r?"IE":j.chrome?"Chrome":j.safari?"Safari":j.mozInnerScreenX?"Firefox":"Unknown"}var I=class extends w.VertexArray{get[Symbol.toStringTag](){return"WebGPUVertexArray"}device;handle;static isConstantAttributeZeroSupported(e){return _()==="Chrome"}constructor(e,t){super(e,t),this.device=e}destroy(){}setIndexBuffer(e){this.indexBuffer=e}setBuffer(e,t){this.attributes[e]=t}setConstant(e,t){w.log.warn(`${this.id} constant attributes not supported on WebGPU`)}bindBeforeRender(e,t,r){let n=e,o=this.indexBuffer;o?.handle&&(w.log.warn("setting index buffer",o?.handle,o?.indexType)(),n.handle.setIndexBuffer(o?.handle,o?.indexType));for(let s=0;s<this.maxVertexAttributes;s++){let p=this.attributes[s];p?.handle&&(w.log.warn(`setting vertex buffer ${s}`,p?.handle)(),n.handle.setVertexBuffer(s,p?.handle))}}unbindAfterRender(e){}};var $=d(a(),1);var de=d(a(),1),O=class extends de.Framebuffer{device;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}};var T=class extends $.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 O(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}),$.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()})}_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 H=class extends h.Device{handle;adapter;lost;canvasContext=null;commandEncoder=null;renderPass=null;_info;_isLost=!1;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");h.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();h.log.probe(2,"Adapter available",r)();let n=await t.requestDevice({requiredFeatures:t.features});h.log.probe(1,"GPUDevice available")(),typeof e.canvas=="string"&&(await h.CanvasContext.pageLoaded,h.log.probe(1,"DOM is loaded")());let o=new H(n,t,r,e);return h.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),h.log.table(1,o.info)(),h.log.groupEnd(1)(),o}constructor(e,t,r,n){super({...n,id:n.id||(0,h.uid)("webgpu-device")}),this.handle=e,this.adapter=t;let[o,s]=(r.driver||"").split(" Version "),p=r.vendor||this.adapter.__brand||"unknown",l=o||"",v=s||"",b=p==="apple"?"apple":"unknown",S=r.architecture||"unknown",B=r.backend||"unknown",C=(r.type||"").split(" ")[0].toLowerCase()||"unknown";this._info={type:"webgpu",vendor:p,renderer:l,version:v,gpu:b,gpuType:C,gpuBackend:B,gpuArchitecture:S,shadingLanguage:"wgsl",shadingLanguageVersion:100},this.lost=new Promise(async z=>{let pe=await this.handle.lost;this._isLost=!0,z({reason:"destroyed",message:pe.message})}),this.canvasContext=new T(this,this.adapter,{canvas:n.canvas,height:n.height,width:n.width,container:n.container}),this.features=this._getFeatures()}destroy(){this.handle.destroy()}get info(){return this._info}features;get limits(){return this.handle.limits}isTextureFormatSupported(e){return!e.includes("webgl")}isTextureFormatFilterable(e){return this.isTextureFormatSupported(e)}isTextureFormatRenderable(e){return this.isTextureFormatSupported(e)}get isLost(){return this._isLost}createBuffer(e){let t=this._getBufferProps(e);return new g(this,t)}_createTexture(e){return new x(this,e)}createExternalTexture(e){return new A(this,e)}createShader(e){return new G(this,e)}createSampler(e){return new u(this,e)}createRenderPipeline(e){return new F(this,e)}createFramebuffer(e){throw new Error("Not implemented")}createComputePipeline(e){return new k(this,e)}createVertexArray(e){return new I(this,e)}beginRenderPass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new V(this,e)}beginComputePass(e){return this.commandEncoder=this.commandEncoder||this.handle.createCommandEncoder(),new M(this,e)}createTransformFeedback(e){throw new Error("Transform feedback not supported in WebGPU")}createCanvasContext(e){return new T(this,this.adapter,e)}getDefaultRenderPass(){throw new Error("a")}submit(){let e=this.commandEncoder?.finish();e&&this.handle.queue.submit([e]),this.commandEncoder=null}_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=["webgpu","wgsl","timer-query-webgl","float32-filterable-linear-webgl","float16-filterable-linear-webgl","texture-filterable-anisotropic-webgl","float32-renderable-webgl","float16-renderable-webgl"];for(let r of t)e.add(r);return e}copyExternalImageToTexture(e){let{source:t,sourceX:r=0,sourceY:n=0,texture:o,mipLevel:s=0,aspect:p="all",colorSpace:l="display-p3",premultipliedAlpha:v=!1,width:b=o.width,height:S=o.height,depth:B=1}=e,C=o;this.handle?.queue.copyExternalImageToTexture({source:t,origin:[r,n]},{texture:C.handle,origin:[0,0,0],mipLevel:s,aspect:p,colorSpace:l,premultipliedAlpha:v},[b,S,B])}},R=H;X(R,"type","webgpu");return ge(Ce);})();
|
|
7
|
+
var __exports__=(()=>{var ce=Object.create;var S=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var Pe=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var ge=(i,e,t)=>e in i?S(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var ye=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),ve=(i,e)=>{for(var t in e)S(i,t,{get:e[t],enumerable:!0})},X=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of fe(e))!be.call(i,n)&&n!==t&&S(i,n,{get:()=>e[n],enumerable:!(r=me(e,n))||r.enumerable});return i};var p=(i,e,t)=>(t=i!=null?ce(Pe(i)):{},X(e||!i||!i.__esModule?S(t,"default",{value:i,enumerable:!0}):t,i)),xe=i=>X(S({},"__esModule",{value:!0}),i);var J=(i,e,t)=>(ge(i,typeof e!="symbol"?e+"":e,t),t);var a=ye((Ae,Z)=>{Z.exports=globalThis.luma});var Te={};ve(Te,{WebGPUBuffer:()=>b,WebGPUDevice:()=>T,WebGPUSampler:()=>h,WebGPUShader:()=>G,WebGPUTexture:()=>x});var l=p(a(),1);var R=p(a(),1);function Ge(i){return i.byteLength||i.data?.byteLength||0}var b=class extends R.Buffer{device;handle;byteLength;constructor(e,t){super(e,t),this.device=e,this.byteLength=Ge(t);let r=Boolean(t.data),n=Math.ceil(this.byteLength/4)*4;this.handle=this.props.handle||this.device.handle.createBuffer({size:n,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}),n=this.device.handle.createCommandEncoder();n.copyBufferToBuffer(this.handle,e,r.handle,0,t),this.device.handle.queue.submit([n.finish()]),await r.handle.mapAsync(GPUMapMode.READ,e,t);let o=r.handle.getMappedRange().slice(0);return r.handle.unmap(),r.destroy(),new Uint8Array(o)}_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 te=p(a(),1);function v(i){if(i.includes("webgl"))throw new Error("webgl-only format");return i}var K=p(a(),1),h=class extends K.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 ee=p(a(),1),W=class extends ee.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 Ue={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},x=class extends te.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={...t,data:r},this.initialize(this.props)});return}this.initialize(t)}destroy(){this.handle?.destroy(),this.handle=null}createView(e){return new W(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 h?e.sampler:new h(this.device,e.sampler),this.view=new W(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.props.depth},dimension:Ue[this.props.dimension],format:v(this.props.format),usage:this.props.usage,mipLevelCount:this.props.mipLevels,sampleCount:this.props.samples})}setSampler(e){return this.sampler=e instanceof h?e:new h(this.device,e),this}setData(e){return this.setImage({source:e.data})}setImage(e){let{source:t,width:r=e.source.width,height:n=e.source.height,depth:o=1,sourceX:s=0,sourceY:u=0,mipLevel:d=0,x:g=0,y=0,z:q=0,aspect:$="all",colorSpace:z="srgb",premultipliedAlpha:he=!1}=e;return this.device.handle.queue.copyExternalImageToTexture({source:t,origin:[s,u]},{texture:this.handle,origin:[g,y,q],mipLevel:d,aspect:$,colorSpace:z,premultipliedAlpha:he},[r,n,o]),{width:r,height:n}}};var re=p(a(),1);var A=class extends re.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 h?e:new h(this.device,e),this}};var E=p(a(),1),G=class extends E.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 E.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 f=p(a(),1);function c(i){return i.depthStencil=i.depthStencil||{format:"depth24plus",stencilFront:{},stencilBack:{},depthWriteEnabled:!1,depthCompare:"less-equal"},i.depthStencil}var we={cullMode:(i,e,t)=>{t.primitive=t.primitive||{},t.primitive.cullMode=e},frontFace:(i,e,t)=>{t.primitive=t.primitive||{},t.primitive.frontFace=e},depthWriteEnabled:(i,e,t)=>{let r=c(t);r.depthWriteEnabled=e},depthCompare:(i,e,t)=>{let r=c(t);r.depthCompare=e},depthFormat:(i,e,t)=>{let r=c(t);r.format=e},depthBias:(i,e,t)=>{let r=c(t);r.depthBias=e},depthBiasSlopeScale:(i,e,t)=>{let r=c(t);r.depthBiasSlopeScale=e},depthBiasClamp:(i,e,t)=>{let r=c(t);r.depthBiasClamp=e},stencilReadMask:(i,e,t)=>{let r=c(t);r.stencilReadMask=e},stencilWriteMask:(i,e,t)=>{let r=c(t);r.stencilWriteMask=e},stencilCompare:(i,e,t)=>{let r=c(t);r.stencilFront.compare=e,r.stencilBack.compare=e},stencilPassOperation:(i,e,t)=>{let r=c(t);r.stencilFront.passOp=e,r.stencilBack.passOp=e},stencilFailOperation:(i,e,t)=>{let r=c(t);r.stencilFront.failOp=e,r.stencilBack.failOp=e},stencilDepthFailOperation:(i,e,t)=>{let r=c(t);r.stencilFront.depthFailOp=e,r.stencilBack.depthFailOp=e},sampleCount:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.count=e},sampleMask:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.mask=e},sampleAlphaToCoverageEnabled:(i,e,t)=>{t.multisample=t.multisample||{},t.multisample.alphaToCoverageEnabled=e},colorMask:(i,e,t)=>{let r=ie(t);r[0].writeMask=e},blendColorOperation:(i,e,t)=>{ie(t)}},Se={primitive:{cullMode:"back",topology:"triangle-list"},vertex:{module:void 0,entryPoint:"main"},fragment:{module:void 0,entryPoint:"main",targets:[]},layout:"auto"};function ne(i,e={}){Object.assign(i,{...Se,...i}),We(i,e)}function We(i,e){for(let[t,r]of Object.entries(e)){let n=we[t];if(!n)throw new Error(`Illegal parameter ${t}`);n(t,r,i)}}function ie(i){if(i.fragment.targets=i.fragment?.targets||[],!Array.isArray(i.fragment?.targets))throw new Error("colorstate");return i.fragment?.targets?.length===0&&i.fragment.targets?.push({}),i.fragment?.targets}var m=p(a(),1);function L(i,e,t,r){let n=Ce(r,t);return i.createBindGroup({layout:e,entries:n})}function Be(i,e){let t=i.bindings.find(r=>r.name===e||`${r.name}uniforms`===e.toLocaleLowerCase());return t||m.log.warn(`Binding ${e} not set: Not found in shader layout.`)(),t}function Ce(i,e){let t=[];for(let[r,n]of Object.entries(i)){let o=Be(e,r);o&&t.push(De(n,o.location))}return t}function De(i,e){if(i instanceof m.Buffer)return{binding:e,resource:{buffer:(0,m.cast)(i).handle}};if(i instanceof m.Sampler)return{binding:e,resource:(0,m.cast)(i).handle};if(i instanceof m.Texture)return{binding:e,resource:(0,m.cast)(i).handle.createView({label:"bind-group-auto-created"})};throw new Error("invalid binding")}var U=p(a(),1);function N(i){if(i.endsWith("-webgl"))throw new Error(`WebGPU does not support vertex format ${i}`);return i}function se(i,e){let t=[],r=new Set;for(let n of e){let o=[],s="vertex",u=0;if(n.attributes)for(let d of n.attributes){let g=d.attribute,y=oe(i,g,r);s=y.stepMode||(y.name.startsWith("instance")?"instance":"vertex"),o.push({format:N(d.format||n.format),offset:d.byteOffset,shaderLocation:y.location}),u+=(0,U.decodeVertexFormat)(n.format).byteLength}else{let d=oe(i,n.name,r);if(!d)continue;u=(0,U.decodeVertexFormat)(n.format).byteLength,s=d.stepMode||(d.name.startsWith("instance")?"instance":"vertex"),o.push({format:N(n.format),offset:0,shaderLocation:d.location})}t.push({arrayStride:n.byteStride||u,stepMode:s,attributes:o})}for(let n of i.attributes)r.has(n.name)||t.push({arrayStride:(0,U.decodeVertexFormat)("float32x3").byteLength,stepMode:n.stepMode||(n.name.startsWith("instance")?"instance":"vertex"),attributes:[{format:N("float32x3"),offset:0,shaderLocation:n.location}]});return t}function oe(i,e,t){let r=i.attributes.find(n=>n.name===e);if(!r)return U.log.warn(`Unknown attribute ${e}`)(),null;if(t.has(e))throw new Error(`Duplicate attribute ${e}`);return t.add(e),r}var F=class extends f.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();f.log.groupCollapsed(1,`new WebGPURenderPipeline(${this.id})`)(),f.log.probe(1,JSON.stringify(r,null,2))(),f.log.groupEnd(1)(),this.handle=this.device.handle.createRenderPipeline(r)}this.handle.label=this.props.id,this.vs=(0,f.cast)(t.vs),this.fs=(0,f.cast)(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.props.shaderLayout.bindings.length===0?null:(this._bindGroupLayout=this._bindGroupLayout||this.handle.getBindGroupLayout(0),this._bindGroup=this._bindGroup||L(this.device.handle,this._bindGroupLayout,this.props.shaderLayout,this._bindings),this._bindGroup)}_getRenderPipelineDescriptor(){let e={module:(0,f.cast)(this.props.vs).handle,entryPoint:this.props.vertexEntryPoint||"main",buffers:se(this.props.shaderLayout,this.props.bufferLayout)},t={module:(0,f.cast)(this.props.fs).handle,entryPoint:this.props.fragmentEntryPoint||"main",targets:[{format:v(this.device?.canvasContext?.format)}]};switch(this.props.topology){case"triangle-fan-webgl":case"line-loop-webgl":throw new Error(`WebGPU does not support primitive topology ${this.props.topology}`);default:}let r={vertex:e,fragment:t,primitive:{topology:this.props.topology},layout:"auto"};return ne(r,this.props.parameters),r}};var ae=p(a(),1),w=class extends ae.Framebuffer{device;constructor(e,t){super(e,t),this.device=e,this.autoCreateAttachmentTextures()}};var de=p(a(),1);var I=class extends de.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||L(this.device.handle,this._bindGroupLayout,this.props.shaderLayout,this._bindings),this._bindGroup}};var P=p(a(),1),_=class extends P.RenderPass{device;handle;pipeline=null;constructor(e,t={}){super(e,t),this.device=e;let r=t.framebuffer||e.canvasContext.getCurrentFramebuffer(),n=this.getRenderPassDescriptor(r),o=t.timestampQuerySet;if(o&&(n.occlusionQuerySet=o.handle),e.features.has("timestamp-query")){let s=t.timestampQuerySet;n.timestampWrites=s?{querySet:s.handle,beginningOfPassWriteIndex:t.beginTimestampIndex,endOfPassWriteIndex:t.endTimestampIndex}:void 0}this.handle=this.props.handle||e.commandEncoder.beginRenderPass(n),this.handle.label=this.props.id,P.log.groupCollapsed(3,`new WebGPURenderPass(${this.id})`)(),P.log.probe(3,JSON.stringify(n,null,2))(),P.log.groupEnd(3)()}destroy(){}end(){this.handle.end()}setPipeline(e){this.pipeline=(0,P.cast)(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,n){this.handle.setIndexBuffer((0,P.cast)(e).handle,t,r,n)}setVertexBuffer(e,t,r=0){this.handle.setVertexBuffer(e,(0,P.cast)(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:n,viewport:o}=e;t&&this.handle.setBlendConstant(t),r&&this.handle.setStencilReference(r),n&&this.handle.setScissorRect(n[0],n[1],n[2],n[3]),o&&this.handle.setViewport(o[0],o[1],o[2],o[3],o[4],o[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=p(a(),1),V=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 n=t.timestampQuerySet;n&&(r={querySet:n.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 C=p(a(),1);function B(i){if(typeof window<"u"&&typeof window.process=="object"&&window.process.type==="renderer"||typeof process<"u"&&typeof process.versions=="object"&&Boolean(process.versions.electron))return!0;let e=typeof navigator=="object"&&typeof navigator.userAgent=="string"&&navigator.userAgent,t=i||e;return!!(t&&t.indexOf("Electron")>=0)}function j(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process.browser)||B()}var St=globalThis.self||globalThis.window||globalThis.global,Wt=globalThis.window||globalThis.self||globalThis.global,Bt=globalThis.document||{},Ct=globalThis.process||{},Dt=globalThis.console,ue=globalThis.navigator||{};var H=globalThis;function k(i){if(!i&&!j())return"Node";if(B(i))return"Electron";let e=i||ue.userAgent||"";if(e.indexOf("Edge")>-1)return"Edge";let t=e.indexOf("MSIE ")!==-1,r=e.indexOf("Trident/")!==-1;return t||r?"IE":H.chrome?"Chrome":H.safari?"Safari":H.mozInnerScreenX?"Firefox":"Unknown"}var M=class extends C.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 n=e,o=this.indexBuffer;o?.handle&&(C.log.warn("setting index buffer",o?.handle,o?.indexType)(),n.handle.setIndexBuffer(o?.handle,o?.indexType));for(let s=0;s<this.maxVertexAttributes;s++){let u=this.attributes[s];u?.handle&&(C.log.warn(`setting vertex buffer ${s}`,u?.handle)(),n.handle.setVertexBuffer(s,u?.handle))}}unbindAfterRender(e){}static isConstantAttributeZeroSupported(e){return k()==="Chrome"}};var O=p(a(),1);var D=class extends O.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 w(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:v(this.format),colorSpace:this.props.colorSpace,alphaMode:this.props.alphaMode}),O.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 le=p(a(),1),Q=class extends le.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 Y=class extends l.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");l.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();l.log.probe(2,"Adapter available",r)();let n=[],o={};if(e.requestMaxLimits){n.push(...Array.from(t.features));for(let d in t.limits)o[d]=t.limits[d];delete o.minSubgroupSize,delete o.maxSubgroupSize}let s=await t.requestDevice({requiredFeatures:n,requiredLimits:o});l.log.probe(1,"GPUDevice available")(),typeof e.canvas=="string"&&(await l.CanvasContext.pageLoaded,l.log.probe(1,"DOM is loaded")());let u=new Y(s,t,r,e);return l.log.probe(1,"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")(),l.log.table(1,u.info)(),l.log.groupEnd(1)(),u}constructor(e,t,r,n){super({...n,id:n.id||(0,l.uid)("webgpu-device")}),this.handle=e,this.adapter=t,this.adapterInfo=r,this.info=this._getInfo(),this.features=this._getFeatures(),this.limits=this.handle.limits,this.lost=new Promise(async o=>{let s=await this.handle.lost;this._isLost=!0,o({reason:"destroyed",message:s.message})}),this.canvasContext=new D(this,this.adapter,{canvas:n.canvas,height:n.height,width:n.width,container:n.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 x(this,e)}createExternalTexture(e){return new A(this,e)}createShader(e){return new G(this,e)}createSampler(e){return new h(this,e)}createRenderPipeline(e){return new F(this,e)}createFramebuffer(e){return new w(this,e)}createComputePipeline(e){return new I(this,e)}createVertexArray(e){return new M(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 V(this,e)}createTransformFeedback(e){throw new Error("Transform feedback not supported in WebGPU")}createQuerySet(e){return new Q(this,e)}createCanvasContext(e){return new D(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",n=e||"",o=t||"",s=r==="apple"?"apple":"unknown",u=this.adapterInfo.architecture||"unknown",d=this.adapterInfo.backend||"unknown",g=(this.adapterInfo.type||"").split(" ")[0].toLowerCase()||"unknown";return{type:"webgpu",vendor:r,renderer:n,version:o,gpu:s,gpuType:g,gpuBackend:d,gpuArchitecture:u,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 l.DeviceFeatures(Array.from(e),this.props.disabledFeatures)}copyExternalImageToTexture(e){let{source:t,sourceX:r=0,sourceY:n=0,texture:o,mipLevel:s=0,aspect:u="all",colorSpace:d="display-p3",premultipliedAlpha:g=!1,width:y=o.width,height:q=o.height,depth:$=1}=e,z=o;this.handle?.queue.copyExternalImageToTexture({source:t,origin:[r,n]},{texture:z.handle,origin:[0,0,0],mipLevel:s,aspect:u,colorSpace:d,premultipliedAlpha:g},[y,q,$])}},T=Y;J(T,"type","webgpu");return xe(Te);})();
|
|
8
8
|
return __exports__;
|
|
9
9
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/webgpu",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.7",
|
|
4
4
|
"description": "WebGPU adapter for the luma.gl core API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"@probe.gl/env": "^4.0.2",
|
|
44
44
|
"@webgpu/types": "^0.1.34"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "e9606a88e0aab3dc27c87020cac89040ea1a8a02"
|
|
47
47
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
/*
|
|
2
6
|
import {assert} from '@luma.gl/core';
|
|
3
7
|
|
|
@@ -97,4 +101,4 @@ export function mapAccessorToWebGPUFormat(accessor) {
|
|
|
97
101
|
}
|
|
98
102
|
throw new Error('illegal accessor');
|
|
99
103
|
}
|
|
100
|
-
*/
|
|
104
|
+
*/
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
// luma.gl
|
|
2
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {ComputeShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';
|
|
3
6
|
import {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';
|
|
4
7
|
import type {WebGPUBuffer} from '../resources/webgpu-buffer';
|
|
5
8
|
import type {WebGPUSampler} from '../resources/webgpu-sampler';
|
|
@@ -27,7 +30,7 @@ export function makeBindGroupLayout(
|
|
|
27
30
|
export function getBindGroup(
|
|
28
31
|
device: GPUDevice,
|
|
29
32
|
bindGroupLayout: GPUBindGroupLayout,
|
|
30
|
-
shaderLayout:
|
|
33
|
+
shaderLayout: ComputeShaderLayout,
|
|
31
34
|
bindings: Record<string, Binding>
|
|
32
35
|
): GPUBindGroup {
|
|
33
36
|
const entries = getBindGroupEntries(bindings, shaderLayout);
|
|
@@ -38,10 +41,13 @@ export function getBindGroup(
|
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
export function getShaderLayoutBinding(
|
|
41
|
-
shaderLayout:
|
|
44
|
+
shaderLayout: ComputeShaderLayout,
|
|
42
45
|
bindingName: string
|
|
43
46
|
): BindingDeclaration {
|
|
44
|
-
const bindingLayout = shaderLayout.bindings.find(
|
|
47
|
+
const bindingLayout = shaderLayout.bindings.find(
|
|
48
|
+
binding =>
|
|
49
|
+
binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase()
|
|
50
|
+
);
|
|
45
51
|
if (!bindingLayout) {
|
|
46
52
|
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
|
|
47
53
|
}
|
|
@@ -54,7 +60,7 @@ export function getShaderLayoutBinding(
|
|
|
54
60
|
*/
|
|
55
61
|
function getBindGroupEntries(
|
|
56
62
|
bindings: Record<string, Binding>,
|
|
57
|
-
shaderLayout:
|
|
63
|
+
shaderLayout: ComputeShaderLayout
|
|
58
64
|
): GPUBindGroupEntry[] {
|
|
59
65
|
const entries: GPUBindGroupEntry[] = [];
|
|
60
66
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';
|
|
3
6
|
import {log, decodeVertexFormat} from '@luma.gl/core';
|
|
4
7
|
// import {getAttributeInfosFromLayouts} from '@luma.gl/core';
|
|
@@ -40,7 +43,9 @@ export function getVertexBufferLayout(
|
|
|
40
43
|
const attributeName = attributeMapping.attribute;
|
|
41
44
|
const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
|
|
42
45
|
|
|
43
|
-
stepMode =
|
|
46
|
+
stepMode =
|
|
47
|
+
attributeLayout.stepMode ||
|
|
48
|
+
(attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');
|
|
44
49
|
vertexAttributes.push({
|
|
45
50
|
format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
|
|
46
51
|
offset: attributeMapping.byteOffset,
|
|
@@ -57,7 +62,9 @@ export function getVertexBufferLayout(
|
|
|
57
62
|
}
|
|
58
63
|
byteStride = decodeVertexFormat(mapping.format).byteLength;
|
|
59
64
|
|
|
60
|
-
stepMode =
|
|
65
|
+
stepMode =
|
|
66
|
+
attributeLayout.stepMode ||
|
|
67
|
+
(attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');
|
|
61
68
|
vertexAttributes.push({
|
|
62
69
|
format: getWebGPUVertexFormat(mapping.format),
|
|
63
70
|
// We only support 0 offset for non-interleaved buffer layouts
|
|
@@ -79,7 +86,8 @@ export function getVertexBufferLayout(
|
|
|
79
86
|
if (!usedAttributes.has(attribute.name)) {
|
|
80
87
|
vertexBufferLayouts.push({
|
|
81
88
|
arrayStride: decodeVertexFormat('float32x3').byteLength,
|
|
82
|
-
stepMode:
|
|
89
|
+
stepMode:
|
|
90
|
+
attribute.stepMode || (attribute.name.startsWith('instance') ? 'instance' : 'vertex'),
|
|
83
91
|
attributes: [
|
|
84
92
|
{
|
|
85
93
|
format: getWebGPUVertexFormat('float32x3'),
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import {Parameters} from '@luma.gl/core';
|
|
2
6
|
|
|
3
7
|
function addDepthStencil(descriptor: GPURenderPipelineDescriptor): GPUDepthStencilState {
|
|
@@ -33,17 +37,29 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
|
|
|
33
37
|
|
|
34
38
|
// DEPTH
|
|
35
39
|
|
|
36
|
-
depthWriteEnabled: (
|
|
40
|
+
depthWriteEnabled: (
|
|
41
|
+
parameter: keyof Parameters,
|
|
42
|
+
value: any,
|
|
43
|
+
descriptor: GPURenderPipelineDescriptor
|
|
44
|
+
) => {
|
|
37
45
|
const depthStencil = addDepthStencil(descriptor);
|
|
38
46
|
depthStencil.depthWriteEnabled = value;
|
|
39
47
|
},
|
|
40
48
|
|
|
41
|
-
depthCompare: (
|
|
49
|
+
depthCompare: (
|
|
50
|
+
parameter: keyof Parameters,
|
|
51
|
+
value: any,
|
|
52
|
+
descriptor: GPURenderPipelineDescriptor
|
|
53
|
+
) => {
|
|
42
54
|
const depthStencil = addDepthStencil(descriptor);
|
|
43
55
|
depthStencil.depthCompare = value;
|
|
44
56
|
},
|
|
45
57
|
|
|
46
|
-
depthFormat: (
|
|
58
|
+
depthFormat: (
|
|
59
|
+
parameter: keyof Parameters,
|
|
60
|
+
value: any,
|
|
61
|
+
descriptor: GPURenderPipelineDescriptor
|
|
62
|
+
) => {
|
|
47
63
|
const depthStencil = addDepthStencil(descriptor);
|
|
48
64
|
depthStencil.format = value;
|
|
49
65
|
},
|
|
@@ -53,47 +69,79 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
|
|
|
53
69
|
depthStencil.depthBias = value;
|
|
54
70
|
},
|
|
55
71
|
|
|
56
|
-
depthBiasSlopeScale: (
|
|
72
|
+
depthBiasSlopeScale: (
|
|
73
|
+
parameter: keyof Parameters,
|
|
74
|
+
value: any,
|
|
75
|
+
descriptor: GPURenderPipelineDescriptor
|
|
76
|
+
) => {
|
|
57
77
|
const depthStencil = addDepthStencil(descriptor);
|
|
58
78
|
depthStencil.depthBiasSlopeScale = value;
|
|
59
79
|
},
|
|
60
80
|
|
|
61
|
-
depthBiasClamp: (
|
|
81
|
+
depthBiasClamp: (
|
|
82
|
+
parameter: keyof Parameters,
|
|
83
|
+
value: any,
|
|
84
|
+
descriptor: GPURenderPipelineDescriptor
|
|
85
|
+
) => {
|
|
62
86
|
const depthStencil = addDepthStencil(descriptor);
|
|
63
87
|
depthStencil.depthBiasClamp = value;
|
|
64
88
|
},
|
|
65
89
|
|
|
66
90
|
// STENCIL
|
|
67
91
|
|
|
68
|
-
stencilReadMask: (
|
|
92
|
+
stencilReadMask: (
|
|
93
|
+
parameter: keyof Parameters,
|
|
94
|
+
value: any,
|
|
95
|
+
descriptor: GPURenderPipelineDescriptor
|
|
96
|
+
) => {
|
|
69
97
|
const depthStencil = addDepthStencil(descriptor);
|
|
70
98
|
depthStencil.stencilReadMask = value;
|
|
71
99
|
},
|
|
72
100
|
|
|
73
|
-
stencilWriteMask: (
|
|
101
|
+
stencilWriteMask: (
|
|
102
|
+
parameter: keyof Parameters,
|
|
103
|
+
value: any,
|
|
104
|
+
descriptor: GPURenderPipelineDescriptor
|
|
105
|
+
) => {
|
|
74
106
|
const depthStencil = addDepthStencil(descriptor);
|
|
75
107
|
depthStencil.stencilWriteMask = value;
|
|
76
108
|
},
|
|
77
109
|
|
|
78
|
-
stencilCompare: (
|
|
110
|
+
stencilCompare: (
|
|
111
|
+
parameter: keyof Parameters,
|
|
112
|
+
value: any,
|
|
113
|
+
descriptor: GPURenderPipelineDescriptor
|
|
114
|
+
) => {
|
|
79
115
|
const depthStencil = addDepthStencil(descriptor);
|
|
80
116
|
depthStencil.stencilFront.compare = value;
|
|
81
117
|
depthStencil.stencilBack.compare = value;
|
|
82
118
|
},
|
|
83
119
|
|
|
84
|
-
stencilPassOperation: (
|
|
120
|
+
stencilPassOperation: (
|
|
121
|
+
parameter: keyof Parameters,
|
|
122
|
+
value: any,
|
|
123
|
+
descriptor: GPURenderPipelineDescriptor
|
|
124
|
+
) => {
|
|
85
125
|
const depthStencil = addDepthStencil(descriptor);
|
|
86
126
|
depthStencil.stencilFront.passOp = value;
|
|
87
127
|
depthStencil.stencilBack.passOp = value;
|
|
88
128
|
},
|
|
89
129
|
|
|
90
|
-
stencilFailOperation: (
|
|
130
|
+
stencilFailOperation: (
|
|
131
|
+
parameter: keyof Parameters,
|
|
132
|
+
value: any,
|
|
133
|
+
descriptor: GPURenderPipelineDescriptor
|
|
134
|
+
) => {
|
|
91
135
|
const depthStencil = addDepthStencil(descriptor);
|
|
92
136
|
depthStencil.stencilFront.failOp = value;
|
|
93
137
|
depthStencil.stencilBack.failOp = value;
|
|
94
138
|
},
|
|
95
139
|
|
|
96
|
-
stencilDepthFailOperation: (
|
|
140
|
+
stencilDepthFailOperation: (
|
|
141
|
+
parameter: keyof Parameters,
|
|
142
|
+
value: any,
|
|
143
|
+
descriptor: GPURenderPipelineDescriptor
|
|
144
|
+
) => {
|
|
97
145
|
const depthStencil = addDepthStencil(descriptor);
|
|
98
146
|
depthStencil.stencilFront.depthFailOp = value;
|
|
99
147
|
depthStencil.stencilBack.depthFailOp = value;
|
|
@@ -101,17 +149,29 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
|
|
|
101
149
|
|
|
102
150
|
// MULTISAMPLE
|
|
103
151
|
|
|
104
|
-
sampleCount: (
|
|
152
|
+
sampleCount: (
|
|
153
|
+
parameter: keyof Parameters,
|
|
154
|
+
value: any,
|
|
155
|
+
descriptor: GPURenderPipelineDescriptor
|
|
156
|
+
) => {
|
|
105
157
|
descriptor.multisample = descriptor.multisample || {};
|
|
106
158
|
descriptor.multisample.count = value;
|
|
107
159
|
},
|
|
108
160
|
|
|
109
|
-
sampleMask: (
|
|
161
|
+
sampleMask: (
|
|
162
|
+
parameter: keyof Parameters,
|
|
163
|
+
value: any,
|
|
164
|
+
descriptor: GPURenderPipelineDescriptor
|
|
165
|
+
) => {
|
|
110
166
|
descriptor.multisample = descriptor.multisample || {};
|
|
111
167
|
descriptor.multisample.mask = value;
|
|
112
168
|
},
|
|
113
169
|
|
|
114
|
-
sampleAlphaToCoverageEnabled: (
|
|
170
|
+
sampleAlphaToCoverageEnabled: (
|
|
171
|
+
parameter: keyof Parameters,
|
|
172
|
+
value: any,
|
|
173
|
+
descriptor: GPURenderPipelineDescriptor
|
|
174
|
+
) => {
|
|
115
175
|
descriptor.multisample = descriptor.multisample || {};
|
|
116
176
|
descriptor.multisample.alphaToCoverageEnabled = value;
|
|
117
177
|
},
|
|
@@ -123,7 +183,11 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
|
|
|
123
183
|
targets[0].writeMask = value;
|
|
124
184
|
},
|
|
125
185
|
|
|
126
|
-
blendColorOperation: (
|
|
186
|
+
blendColorOperation: (
|
|
187
|
+
parameter: keyof Parameters,
|
|
188
|
+
value: any,
|
|
189
|
+
descriptor: GPURenderPipelineDescriptor
|
|
190
|
+
) => {
|
|
127
191
|
addColorState(descriptor);
|
|
128
192
|
// const targets = addColorState(descriptor);
|
|
129
193
|
// const target = targets[0];
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
//
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {Buffer, BufferProps} from '@luma.gl/core';
|
|
3
6
|
import type {WebGPUDevice} from '../webgpu-device';
|
|
4
7
|
|
|
@@ -21,13 +24,15 @@ export class WebGPUBuffer extends Buffer {
|
|
|
21
24
|
// WebGPU buffers must be aligned to 4 bytes
|
|
22
25
|
const size = Math.ceil(this.byteLength / 4) * 4;
|
|
23
26
|
|
|
24
|
-
this.handle =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
this.handle =
|
|
28
|
+
this.props.handle ||
|
|
29
|
+
this.device.handle.createBuffer({
|
|
30
|
+
size,
|
|
31
|
+
// usage defaults to vertex
|
|
32
|
+
usage: this.props.usage || GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
33
|
+
mappedAtCreation: this.props.mappedAtCreation || mapBuffer,
|
|
34
|
+
label: this.props.id
|
|
35
|
+
});
|
|
31
36
|
|
|
32
37
|
if (props.data) {
|
|
33
38
|
this._writeMapped(props.data);
|
|
@@ -40,7 +45,9 @@ export class WebGPUBuffer extends Buffer {
|
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
override destroy(): void {
|
|
43
|
-
this.handle
|
|
48
|
+
this.handle?.destroy();
|
|
49
|
+
// @ts-expect-error readonly
|
|
50
|
+
this.handle = null;
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
// WebGPU provides multiple ways to write a buffer...
|
|
@@ -54,9 +61,15 @@ export class WebGPUBuffer extends Buffer {
|
|
|
54
61
|
);
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
override async readAsync(
|
|
64
|
+
override async readAsync(
|
|
65
|
+
byteOffset: number = 0,
|
|
66
|
+
byteLength: number = this.byteLength
|
|
67
|
+
): Promise<Uint8Array> {
|
|
58
68
|
// We need MAP_READ flag, but only COPY_DST buffers can have MAP_READ flag, so we need to create a temp buffer
|
|
59
|
-
const tempBuffer = new WebGPUBuffer(this.device, {
|
|
69
|
+
const tempBuffer = new WebGPUBuffer(this.device, {
|
|
70
|
+
usage: Buffer.MAP_READ | Buffer.COPY_DST,
|
|
71
|
+
byteLength
|
|
72
|
+
});
|
|
60
73
|
|
|
61
74
|
// Now do a GPU-side copy into the temp buffer we can actually read.
|
|
62
75
|
// TODO - we are spinning up an independent command queue here, what does this mean
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import {CommandEncoder, CommandEncoderProps, Buffer, Texture} from '@luma.gl/core';
|
|
2
6
|
import type {CopyTextureToTextureOptions, CopyTextureToBufferOptions} from '@luma.gl/core';
|
|
3
7
|
import {WebGPUDevice} from '../webgpu-device';
|
|
4
8
|
import {WebGPUBuffer} from './webgpu-buffer';
|
|
5
9
|
import {WebGPUTexture} from './webgpu-texture';
|
|
10
|
+
import {WebGPUQuerySet} from './webgpu-query-set';
|
|
6
11
|
|
|
7
12
|
export class WebGPUCommandEncoder extends CommandEncoder {
|
|
8
13
|
readonly device: WebGPUDevice;
|
|
@@ -120,13 +125,23 @@ export class WebGPUCommandEncoder extends CommandEncoder {
|
|
|
120
125
|
this.handle.insertDebugMarker(markerLabel);
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
128
|
+
override resolveQuerySet(
|
|
129
|
+
querySet: WebGPUQuerySet,
|
|
130
|
+
destination: Buffer,
|
|
131
|
+
options?: {
|
|
132
|
+
firstQuery?: number;
|
|
133
|
+
queryCount?: number;
|
|
134
|
+
destinationOffset?: number;
|
|
135
|
+
}
|
|
136
|
+
): void {
|
|
137
|
+
const webgpuQuerySet = querySet;
|
|
138
|
+
const webgpuBuffer = destination as WebGPUBuffer;
|
|
139
|
+
this.handle.resolveQuerySet(
|
|
140
|
+
webgpuQuerySet.handle,
|
|
141
|
+
options.firstQuery || 0,
|
|
142
|
+
options.queryCount || querySet.props.count - (options.firstQuery || 0),
|
|
143
|
+
webgpuBuffer.handle,
|
|
144
|
+
options.destinationOffset || 0
|
|
145
|
+
);
|
|
146
|
+
}
|
|
132
147
|
}
|
|
@@ -1,22 +1,42 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import {ComputePass, ComputePassProps, ComputePipeline, Buffer, Binding} from '@luma.gl/core';
|
|
2
6
|
import {WebGPUDevice} from '../webgpu-device';
|
|
3
7
|
import {WebGPUBuffer} from './webgpu-buffer';
|
|
4
|
-
// import {WebGPUCommandEncoder} from './webgpu-command-encoder';
|
|
5
8
|
import {WebGPUComputePipeline} from './webgpu-compute-pipeline';
|
|
9
|
+
import {WebGPUQuerySet} from './webgpu-query-set';
|
|
6
10
|
|
|
7
11
|
export class WebGPUComputePass extends ComputePass {
|
|
8
12
|
readonly device: WebGPUDevice;
|
|
9
13
|
readonly handle: GPUComputePassEncoder;
|
|
10
|
-
|
|
14
|
+
|
|
15
|
+
_webgpuPipeline: WebGPUComputePipeline | null = null;
|
|
11
16
|
|
|
12
17
|
constructor(device: WebGPUDevice, props: ComputePassProps) {
|
|
13
18
|
super(device, props);
|
|
14
19
|
this.device = device;
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
// Set up queries
|
|
22
|
+
let timestampWrites: GPUComputePassTimestampWrites | undefined;
|
|
23
|
+
if (device.features.has('timestamp-query')) {
|
|
24
|
+
const webgpuQuerySet = props.timestampQuerySet as WebGPUQuerySet;
|
|
25
|
+
if (webgpuQuerySet) {
|
|
26
|
+
timestampWrites = {
|
|
27
|
+
querySet: webgpuQuerySet.handle,
|
|
28
|
+
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
29
|
+
endOfPassWriteIndex: props.endTimestampIndex
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.handle =
|
|
35
|
+
this.props.handle ||
|
|
36
|
+
device.commandEncoder?.beginComputePass({
|
|
37
|
+
label: this.props.id,
|
|
38
|
+
timestampWrites
|
|
39
|
+
});
|
|
20
40
|
}
|
|
21
41
|
|
|
22
42
|
/** @note no WebGPU destroy method, just gc */
|
|
@@ -29,21 +49,24 @@ export class WebGPUComputePass extends ComputePass {
|
|
|
29
49
|
setPipeline(pipeline: ComputePipeline): void {
|
|
30
50
|
const wgpuPipeline = pipeline as WebGPUComputePipeline;
|
|
31
51
|
this.handle.setPipeline(wgpuPipeline.handle);
|
|
32
|
-
this.
|
|
52
|
+
this._webgpuPipeline = wgpuPipeline;
|
|
53
|
+
this.setBindings([]);
|
|
33
54
|
}
|
|
34
55
|
|
|
35
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Sets an array of bindings (uniform buffers, samplers, textures, ...)
|
|
58
|
+
* TODO - still some API confusion - does this method go here or on the pipeline?
|
|
59
|
+
*/
|
|
36
60
|
setBindings(bindings: Binding[]): void {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// this.handle.setBindGroup(0, bindGroup);
|
|
61
|
+
const bindGroup = this._webgpuPipeline._getBindGroup();
|
|
62
|
+
this.handle.setBindGroup(0, bindGroup);
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
/**
|
|
43
66
|
* Dispatch work to be performed with the current ComputePipeline.
|
|
44
|
-
* @param x X dimension of the grid of
|
|
45
|
-
* @param y Y dimension of the grid of
|
|
46
|
-
* @param z Z dimension of the grid of
|
|
67
|
+
* @param x X dimension of the grid of work groups to dispatch.
|
|
68
|
+
* @param y Y dimension of the grid of work groups to dispatch.
|
|
69
|
+
* @param z Z dimension of the grid of work groups to dispatch.
|
|
47
70
|
*/
|
|
48
71
|
dispatch(x: number, y?: number, z?: number): void {
|
|
49
72
|
this.handle.dispatchWorkgroups(x, y, z);
|
|
@@ -51,25 +74,25 @@ export class WebGPUComputePass extends ComputePass {
|
|
|
51
74
|
|
|
52
75
|
/**
|
|
53
76
|
* Dispatch work to be performed with the current ComputePipeline.
|
|
54
|
-
*
|
|
55
|
-
*
|
|
77
|
+
*
|
|
78
|
+
* Buffer must be a tightly packed block of three 32-bit unsigned integer values (12 bytes total), given in the same order as the arguments for dispatch()
|
|
79
|
+
* @param indirectBuffer
|
|
80
|
+
* @param indirectOffset offset in buffer to the beginning of the dispatch data.
|
|
56
81
|
*/
|
|
57
|
-
dispatchIndirect(indirectBuffer: Buffer,
|
|
82
|
+
dispatchIndirect(indirectBuffer: Buffer, indirectByteOffset: number = 0): void {
|
|
58
83
|
const webgpuBuffer = indirectBuffer as WebGPUBuffer;
|
|
59
|
-
this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle,
|
|
84
|
+
this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle, indirectByteOffset);
|
|
60
85
|
}
|
|
61
86
|
|
|
62
87
|
pushDebugGroup(groupLabel: string): void {
|
|
63
88
|
this.handle.pushDebugGroup(groupLabel);
|
|
64
89
|
}
|
|
90
|
+
|
|
65
91
|
popDebugGroup(): void {
|
|
66
92
|
this.handle.popDebugGroup();
|
|
67
93
|
}
|
|
94
|
+
|
|
68
95
|
insertDebugMarker(markerLabel: string): void {
|
|
69
96
|
this.handle.insertDebugMarker(markerLabel);
|
|
70
97
|
}
|
|
71
|
-
|
|
72
|
-
// writeTimestamp(querySet: GPUQuerySet, queryIndex: number): void;
|
|
73
|
-
// beginPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
|
|
74
|
-
// endPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
|
|
75
98
|
}
|