@luma.gl/webgpu 9.0.0-beta.1 → 9.0.0-beta.2

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.
@@ -10,7 +10,7 @@ export function getBindGroup(device, bindGroupLayout, shaderLayout, bindings) {
10
10
  });
11
11
  }
12
12
  export function getShaderLayoutBinding(shaderLayout, bindingName) {
13
- const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName);
13
+ const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());
14
14
  if (!bindingLayout) {
15
15
  log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-bind-group.js","names":["Buffer","Sampler","Texture","log","cast","makeBindGroupLayout","device","layout","bindings","Error","getBindGroup","bindGroupLayout","shaderLayout","entries","getBindGroupEntries","createBindGroup","getShaderLayoutBinding","bindingName","bindingLayout","find","binding","name","warn","value","Object","push","getBindGroupEntry","location","index","resource","buffer","handle","createView","label"],"sources":["../../../src/adapter/helpers/get-bind-group.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';\nimport {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';\nimport type {WebGPUBuffer} from '../resources/webgpu-buffer';\nimport type {WebGPUSampler} from '../resources/webgpu-sampler';\nimport type {WebGPUTexture} from '../resources/webgpu-texture';\n\n/**\n * Create a WebGPU \"bind group layout\" from an array of luma.gl bindings\n * @note bind groups can be automatically generated by WebGPU.\n */\nexport function makeBindGroupLayout(\n device: GPUDevice,\n layout: GPUBindGroupLayout,\n bindings: Binding[]\n): GPUBindGroupLayout {\n throw new Error('not implemented');\n // return device.createBindGroupLayout({\n // layout,\n // entries: getBindGroupEntries(bindings)\n // })\n}\n\n/**\n * Create a WebGPU \"bind group\" from an array of luma.gl bindings\n */\nexport function getBindGroup(\n device: GPUDevice,\n bindGroupLayout: GPUBindGroupLayout,\n shaderLayout: ShaderLayout,\n bindings: Record<string, Binding>\n): GPUBindGroup {\n const entries = getBindGroupEntries(bindings, shaderLayout);\n return device.createBindGroup({\n layout: bindGroupLayout,\n entries\n });\n}\n\nexport function getShaderLayoutBinding(\n shaderLayout: ShaderLayout,\n bindingName: string\n): BindingDeclaration {\n const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName);\n if (!bindingLayout) {\n log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();\n }\n return bindingLayout;\n}\n\n/**\n * @param bindings\n * @returns\n */\nfunction getBindGroupEntries(\n bindings: Record<string, Binding>,\n shaderLayout: ShaderLayout\n): GPUBindGroupEntry[] {\n const entries: GPUBindGroupEntry[] = [];\n\n for (const [bindingName, value] of Object.entries(bindings)) {\n const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);\n if (bindingLayout) {\n entries.push(getBindGroupEntry(value, bindingLayout.location));\n }\n }\n\n return entries;\n}\n\nfunction getBindGroupEntry(binding: Binding, index: number): GPUBindGroupEntry {\n if (binding instanceof Buffer) {\n return {\n binding: index,\n resource: {\n buffer: cast<WebGPUBuffer>(binding).handle\n }\n };\n }\n if (binding instanceof Sampler) {\n return {\n binding: index,\n resource: cast<WebGPUSampler>(binding).handle\n };\n } else if (binding instanceof Texture) {\n return {\n binding: index,\n resource: cast<WebGPUTexture>(binding).handle.createView({label: 'bind-group-auto-created'})\n };\n }\n throw new Error('invalid binding');\n}\n"],"mappings":"AAEA,SAAQA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,QAAO,eAAe;AASjE,OAAO,SAASC,mBAAmBA,CACjCC,MAAiB,EACjBC,MAA0B,EAC1BC,QAAmB,EACC;EACpB,MAAM,IAAIC,KAAK,CAAC,iBAAiB,CAAC;AAKpC;AAKA,OAAO,SAASC,YAAYA,CAC1BJ,MAAiB,EACjBK,eAAmC,EACnCC,YAA0B,EAC1BJ,QAAiC,EACnB;EACd,MAAMK,OAAO,GAAGC,mBAAmB,CAACN,QAAQ,EAAEI,YAAY,CAAC;EAC3D,OAAON,MAAM,CAACS,eAAe,CAAC;IAC5BR,MAAM,EAAEI,eAAe;IACvBE;EACF,CAAC,CAAC;AACJ;AAEA,OAAO,SAASG,sBAAsBA,CACpCJ,YAA0B,EAC1BK,WAAmB,EACC;EACpB,MAAMC,aAAa,GAAGN,YAAY,CAACJ,QAAQ,CAACW,IAAI,CAACC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAKJ,WAAW,CAAC;EACzF,IAAI,CAACC,aAAa,EAAE;IAClBf,GAAG,CAACmB,IAAI,CAAE,WAAUL,WAAY,uCAAsC,CAAC,CAAC,CAAC;EAC3E;EACA,OAAOC,aAAa;AACtB;AAMA,SAASJ,mBAAmBA,CAC1BN,QAAiC,EACjCI,YAA0B,EACL;EACrB,MAAMC,OAA4B,GAAG,EAAE;EAEvC,KAAK,MAAM,CAACI,WAAW,EAAEM,KAAK,CAAC,IAAIC,MAAM,CAACX,OAAO,CAACL,QAAQ,CAAC,EAAE;IAC3D,MAAMU,aAAa,GAAGF,sBAAsB,CAACJ,YAAY,EAAEK,WAAW,CAAC;IACvE,IAAIC,aAAa,EAAE;MACjBL,OAAO,CAACY,IAAI,CAACC,iBAAiB,CAACH,KAAK,EAAEL,aAAa,CAACS,QAAQ,CAAC,CAAC;IAChE;EACF;EAEA,OAAOd,OAAO;AAChB;AAEA,SAASa,iBAAiBA,CAACN,OAAgB,EAAEQ,KAAa,EAAqB;EAC7E,IAAIR,OAAO,YAAYpB,MAAM,EAAE;IAC7B,OAAO;MACLoB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAE;QACRC,MAAM,EAAE1B,IAAI,CAAegB,OAAO,CAAC,CAACW;MACtC;IACF,CAAC;EACH;EACA,IAAIX,OAAO,YAAYnB,OAAO,EAAE;IAC9B,OAAO;MACLmB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW;IACzC,CAAC;EACH,CAAC,MAAM,IAAIX,OAAO,YAAYlB,OAAO,EAAE;IACrC,OAAO;MACLkB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW,MAAM,CAACC,UAAU,CAAC;QAACC,KAAK,EAAE;MAAyB,CAAC;IAC7F,CAAC;EACH;EACA,MAAM,IAAIxB,KAAK,CAAC,iBAAiB,CAAC;AACpC"}
1
+ {"version":3,"file":"get-bind-group.js","names":["Buffer","Sampler","Texture","log","cast","makeBindGroupLayout","device","layout","bindings","Error","getBindGroup","bindGroupLayout","shaderLayout","entries","getBindGroupEntries","createBindGroup","getShaderLayoutBinding","bindingName","bindingLayout","find","binding","name","toLocaleLowerCase","warn","value","Object","push","getBindGroupEntry","location","index","resource","buffer","handle","createView","label"],"sources":["../../../src/adapter/helpers/get-bind-group.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';\nimport {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';\nimport type {WebGPUBuffer} from '../resources/webgpu-buffer';\nimport type {WebGPUSampler} from '../resources/webgpu-sampler';\nimport type {WebGPUTexture} from '../resources/webgpu-texture';\n\n/**\n * Create a WebGPU \"bind group layout\" from an array of luma.gl bindings\n * @note bind groups can be automatically generated by WebGPU.\n */\nexport function makeBindGroupLayout(\n device: GPUDevice,\n layout: GPUBindGroupLayout,\n bindings: Binding[]\n): GPUBindGroupLayout {\n throw new Error('not implemented');\n // return device.createBindGroupLayout({\n // layout,\n // entries: getBindGroupEntries(bindings)\n // })\n}\n\n/**\n * Create a WebGPU \"bind group\" from an array of luma.gl bindings\n */\nexport function getBindGroup(\n device: GPUDevice,\n bindGroupLayout: GPUBindGroupLayout,\n shaderLayout: ShaderLayout,\n bindings: Record<string, Binding>\n): GPUBindGroup {\n const entries = getBindGroupEntries(bindings, shaderLayout);\n return device.createBindGroup({\n layout: bindGroupLayout,\n entries\n });\n}\n\nexport function getShaderLayoutBinding(\n shaderLayout: ShaderLayout,\n bindingName: string\n): BindingDeclaration {\n const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());\n if (!bindingLayout) {\n log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();\n }\n return bindingLayout;\n}\n\n/**\n * @param bindings\n * @returns\n */\nfunction getBindGroupEntries(\n bindings: Record<string, Binding>,\n shaderLayout: ShaderLayout\n): GPUBindGroupEntry[] {\n const entries: GPUBindGroupEntry[] = [];\n\n for (const [bindingName, value] of Object.entries(bindings)) {\n const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);\n if (bindingLayout) {\n entries.push(getBindGroupEntry(value, bindingLayout.location));\n }\n }\n\n return entries;\n}\n\nfunction getBindGroupEntry(binding: Binding, index: number): GPUBindGroupEntry {\n if (binding instanceof Buffer) {\n return {\n binding: index,\n resource: {\n buffer: cast<WebGPUBuffer>(binding).handle\n }\n };\n }\n if (binding instanceof Sampler) {\n return {\n binding: index,\n resource: cast<WebGPUSampler>(binding).handle\n };\n } else if (binding instanceof Texture) {\n return {\n binding: index,\n resource: cast<WebGPUTexture>(binding).handle.createView({label: 'bind-group-auto-created'})\n };\n }\n throw new Error('invalid binding');\n}\n"],"mappings":"AAEA,SAAQA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,QAAO,eAAe;AASjE,OAAO,SAASC,mBAAmBA,CACjCC,MAAiB,EACjBC,MAA0B,EAC1BC,QAAmB,EACC;EACpB,MAAM,IAAIC,KAAK,CAAC,iBAAiB,CAAC;AAKpC;AAKA,OAAO,SAASC,YAAYA,CAC1BJ,MAAiB,EACjBK,eAAmC,EACnCC,YAA0B,EAC1BJ,QAAiC,EACnB;EACd,MAAMK,OAAO,GAAGC,mBAAmB,CAACN,QAAQ,EAAEI,YAAY,CAAC;EAC3D,OAAON,MAAM,CAACS,eAAe,CAAC;IAC5BR,MAAM,EAAEI,eAAe;IACvBE;EACF,CAAC,CAAC;AACJ;AAEA,OAAO,SAASG,sBAAsBA,CACpCJ,YAA0B,EAC1BK,WAAmB,EACC;EACpB,MAAMC,aAAa,GAAGN,YAAY,CAACJ,QAAQ,CAACW,IAAI,CAACC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAKJ,WAAW,IAAK,GAAEG,OAAO,CAACC,IAAK,UAAS,KAAKJ,WAAW,CAACK,iBAAiB,CAAC,CAAC,CAAC;EAC1J,IAAI,CAACJ,aAAa,EAAE;IAClBf,GAAG,CAACoB,IAAI,CAAE,WAAUN,WAAY,uCAAsC,CAAC,CAAC,CAAC;EAC3E;EACA,OAAOC,aAAa;AACtB;AAMA,SAASJ,mBAAmBA,CAC1BN,QAAiC,EACjCI,YAA0B,EACL;EACrB,MAAMC,OAA4B,GAAG,EAAE;EAEvC,KAAK,MAAM,CAACI,WAAW,EAAEO,KAAK,CAAC,IAAIC,MAAM,CAACZ,OAAO,CAACL,QAAQ,CAAC,EAAE;IAC3D,MAAMU,aAAa,GAAGF,sBAAsB,CAACJ,YAAY,EAAEK,WAAW,CAAC;IACvE,IAAIC,aAAa,EAAE;MACjBL,OAAO,CAACa,IAAI,CAACC,iBAAiB,CAACH,KAAK,EAAEN,aAAa,CAACU,QAAQ,CAAC,CAAC;IAChE;EACF;EAEA,OAAOf,OAAO;AAChB;AAEA,SAASc,iBAAiBA,CAACP,OAAgB,EAAES,KAAa,EAAqB;EAC7E,IAAIT,OAAO,YAAYpB,MAAM,EAAE;IAC7B,OAAO;MACLoB,OAAO,EAAES,KAAK;MACdC,QAAQ,EAAE;QACRC,MAAM,EAAE3B,IAAI,CAAegB,OAAO,CAAC,CAACY;MACtC;IACF,CAAC;EACH;EACA,IAAIZ,OAAO,YAAYnB,OAAO,EAAE;IAC9B,OAAO;MACLmB,OAAO,EAAES,KAAK;MACdC,QAAQ,EAAE1B,IAAI,CAAgBgB,OAAO,CAAC,CAACY;IACzC,CAAC;EACH,CAAC,MAAM,IAAIZ,OAAO,YAAYlB,OAAO,EAAE;IACrC,OAAO;MACLkB,OAAO,EAAES,KAAK;MACdC,QAAQ,EAAE1B,IAAI,CAAgBgB,OAAO,CAAC,CAACY,MAAM,CAACC,UAAU,CAAC;QAACC,KAAK,EAAE;MAAyB,CAAC;IAC7F,CAAC;EACH;EACA,MAAM,IAAIzB,KAAK,CAAC,iBAAiB,CAAC;AACpC"}
@@ -16,7 +16,7 @@ export function getVertexBufferLayout(shaderLayout, bufferLayout) {
16
16
  for (const attributeMapping of mapping.attributes) {
17
17
  const attributeName = attributeMapping.attribute;
18
18
  const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
19
- stepMode = attributeLayout.stepMode || 'vertex';
19
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');
20
20
  vertexAttributes.push({
21
21
  format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
22
22
  offset: attributeMapping.byteOffset,
@@ -30,7 +30,7 @@ export function getVertexBufferLayout(shaderLayout, bufferLayout) {
30
30
  continue;
31
31
  }
32
32
  byteStride = decodeVertexFormat(mapping.format).byteLength;
33
- stepMode = attributeLayout.stepMode || 'vertex';
33
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');
34
34
  vertexAttributes.push({
35
35
  format: getWebGPUVertexFormat(mapping.format),
36
36
  offset: 0,
@@ -39,7 +39,7 @@ export function getVertexBufferLayout(shaderLayout, bufferLayout) {
39
39
  }
40
40
  vertexBufferLayouts.push({
41
41
  arrayStride: mapping.byteStride || byteStride,
42
- stepMode: stepMode || 'vertex',
42
+ stepMode,
43
43
  attributes: vertexAttributes
44
44
  });
45
45
  }
@@ -47,7 +47,7 @@ export function getVertexBufferLayout(shaderLayout, bufferLayout) {
47
47
  if (!usedAttributes.has(attribute.name)) {
48
48
  vertexBufferLayouts.push({
49
49
  arrayStride: decodeVertexFormat('float32x3').byteLength,
50
- stepMode: attribute.stepMode || 'vertex',
50
+ stepMode: attribute.stepMode || (attribute.name.startsWith('instance') ? 'instance' : 'vertex'),
51
51
  attributes: [{
52
52
  format: getWebGPUVertexFormat('float32x3'),
53
53
  offset: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"get-vertex-buffer-layout.js","names":["log","decodeVertexFormat","getWebGPUVertexFormat","format","endsWith","Error","getVertexBufferLayout","shaderLayout","bufferLayout","vertexBufferLayouts","usedAttributes","Set","mapping","vertexAttributes","stepMode","byteStride","attributes","attributeMapping","attributeName","attribute","attributeLayout","findAttributeLayout","push","offset","byteOffset","shaderLocation","location","byteLength","name","arrayStride","has","getBufferSlots","bufferSlot","bufferSlots","interleaved","add","attributeNames","find","warn"],"sources":["../../../src/adapter/helpers/get-vertex-buffer-layout.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';\nimport {log, decodeVertexFormat} from '@luma.gl/core';\n// import {getAttributeInfosFromLayouts} from '@luma.gl/core';\n\n/** Throw error on any WebGL-only vertex formats */\nfunction getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {\n if (format.endsWith('-webgl')) {\n throw new Error(`WebGPU does not support vertex format ${format}`);\n }\n return format as GPUVertexFormat;\n}\n\n/**\n * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.\n * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array\n * @param layout\n * @param bufferLayout The buffer map is optional\n * @returns WebGPU layout intended for a GPURenderPassDescriptor.\n */\nexport function getVertexBufferLayout(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): GPUVertexBufferLayout[] {\n const vertexBufferLayouts: GPUVertexBufferLayout[] = [];\n const usedAttributes = new Set<string>();\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // Build vertex attributes for one buffer\n const vertexAttributes: GPUVertexAttribute[] = [];\n\n // TODO verify that all stepModes for one buffer are the same\n let stepMode: 'vertex' | 'instance' = 'vertex';\n let byteStride = 0;\n // interleaved mapping {..., attributes: [{...}, ...]}\n if (mapping.attributes) {\n // const arrayStride = mapping.byteStride; TODO\n for (const attributeMapping of mapping.attributes) {\n const attributeName = attributeMapping.attribute;\n const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),\n offset: attributeMapping.byteOffset,\n shaderLocation: attributeLayout.location\n });\n\n byteStride += decodeVertexFormat(mapping.format).byteLength;\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);\n if (!attributeLayout) {\n continue; // eslint-disable-line no-continue\n }\n byteStride = decodeVertexFormat(mapping.format).byteLength;\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(mapping.format),\n // We only support 0 offset for non-interleaved buffer layouts\n offset: 0,\n shaderLocation: attributeLayout.location\n });\n }\n\n // Store all the attribute bindings for one buffer\n vertexBufferLayouts.push({\n arrayStride: mapping.byteStride || byteStride,\n stepMode: stepMode || 'vertex',\n attributes: vertexAttributes\n });\n }\n\n // Add any non-mapped attributes - TODO - avoid hardcoded types\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n vertexBufferLayouts.push({\n arrayStride: decodeVertexFormat('float32x3').byteLength,\n stepMode: attribute.stepMode || 'vertex',\n attributes: [\n {\n format: getWebGPUVertexFormat('float32x3'),\n offset: 0,\n shaderLocation: attribute.location\n }\n ]\n });\n }\n }\n\n return vertexBufferLayouts;\n}\n\nexport function getBufferSlots(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): Record<string, number> {\n const usedAttributes = new Set<string>();\n let bufferSlot = 0;\n const bufferSlots: Record<string, number> = {};\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // interleaved mapping {..., attributes: [{...}, ...]}\n if ('attributes' in mapping) {\n for (const interleaved of mapping.attributes) {\n usedAttributes.add(interleaved.attribute);\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n usedAttributes.add(mapping.name);\n }\n bufferSlots[mapping.name] = bufferSlot++;\n }\n\n // Add any non-mapped attributes\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n bufferSlots[attribute.name] = bufferSlot++;\n }\n }\n\n return bufferSlots;\n}\n\n/**\n * Looks up an attribute in the ShaderLayout.\n * @throws if name is not in ShaderLayout\n * @throws if name has already been referenced\n */\nfunction findAttributeLayout(\n shaderLayout: ShaderLayout,\n name: string,\n attributeNames: Set<string>\n): AttributeDeclaration {\n const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);\n if (!attribute) {\n log.warn(`Unknown attribute ${name}`)();\n return null;\n }\n if (attributeNames.has(name)) {\n throw new Error(`Duplicate attribute ${name}`);\n }\n attributeNames.add(name);\n return attribute;\n}\n"],"mappings":"AAEA,SAAQA,GAAG,EAAEC,kBAAkB,QAAO,eAAe;AAIrD,SAASC,qBAAqBA,CAACC,MAAoB,EAAmB;EACpE,IAAIA,MAAM,CAACC,QAAQ,CAAC,QAAQ,CAAC,EAAE;IAC7B,MAAM,IAAIC,KAAK,CAAE,yCAAwCF,MAAO,EAAC,CAAC;EACpE;EACA,OAAOA,MAAM;AACf;AASA,OAAO,SAASG,qBAAqBA,CACnCC,YAA0B,EAC1BC,YAA4B,EACH;EACzB,MAAMC,mBAA4C,GAAG,EAAE;EACvD,MAAMC,cAAc,GAAG,IAAIC,GAAG,CAAS,CAAC;EAGxC,KAAK,MAAMC,OAAO,IAAIJ,YAAY,EAAE;IAElC,MAAMK,gBAAsC,GAAG,EAAE;IAGjD,IAAIC,QAA+B,GAAG,QAAQ;IAC9C,IAAIC,UAAU,GAAG,CAAC;IAElB,IAAIH,OAAO,CAACI,UAAU,EAAE;MAEtB,KAAK,MAAMC,gBAAgB,IAAIL,OAAO,CAACI,UAAU,EAAE;QACjD,MAAME,aAAa,GAAGD,gBAAgB,CAACE,SAAS;QAChD,MAAMC,eAAe,GAAGC,mBAAmB,CAACd,YAAY,EAAEW,aAAa,EAAER,cAAc,CAAC;QAExFI,QAAQ,GAAGM,eAAe,CAACN,QAAQ,IAAI,QAAQ;QAC/CD,gBAAgB,CAACS,IAAI,CAAC;UACpBnB,MAAM,EAAED,qBAAqB,CAACe,gBAAgB,CAACd,MAAM,IAAIS,OAAO,CAACT,MAAM,CAAC;UACxEoB,MAAM,EAAEN,gBAAgB,CAACO,UAAU;UACnCC,cAAc,EAAEL,eAAe,CAACM;QAClC,CAAC,CAAC;QAEFX,UAAU,IAAId,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAACwB,UAAU;MAC7D;IAEF,CAAC,MAAM;MACL,MAAMP,eAAe,GAAGC,mBAAmB,CAACd,YAAY,EAAEK,OAAO,CAACgB,IAAI,EAAElB,cAAc,CAAC;MACvF,IAAI,CAACU,eAAe,EAAE;QACpB;MACF;MACAL,UAAU,GAAGd,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAACwB,UAAU;MAE1Db,QAAQ,GAAGM,eAAe,CAACN,QAAQ,IAAI,QAAQ;MAC/CD,gBAAgB,CAACS,IAAI,CAAC;QACpBnB,MAAM,EAAED,qBAAqB,CAACU,OAAO,CAACT,MAAM,CAAC;QAE7CoB,MAAM,EAAE,CAAC;QACTE,cAAc,EAAEL,eAAe,CAACM;MAClC,CAAC,CAAC;IACJ;IAGAjB,mBAAmB,CAACa,IAAI,CAAC;MACvBO,WAAW,EAAEjB,OAAO,CAACG,UAAU,IAAIA,UAAU;MAC7CD,QAAQ,EAAEA,QAAQ,IAAI,QAAQ;MAC9BE,UAAU,EAAEH;IACd,CAAC,CAAC;EACJ;EAGA,KAAK,MAAMM,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACoB,GAAG,CAACX,SAAS,CAACS,IAAI,CAAC,EAAE;MACvCnB,mBAAmB,CAACa,IAAI,CAAC;QACvBO,WAAW,EAAE5B,kBAAkB,CAAC,WAAW,CAAC,CAAC0B,UAAU;QACvDb,QAAQ,EAAEK,SAAS,CAACL,QAAQ,IAAI,QAAQ;QACxCE,UAAU,EAAE,CACV;UACEb,MAAM,EAAED,qBAAqB,CAAC,WAAW,CAAC;UAC1CqB,MAAM,EAAE,CAAC;UACTE,cAAc,EAAEN,SAAS,CAACO;QAC5B,CAAC;MAEL,CAAC,CAAC;IACJ;EACF;EAEA,OAAOjB,mBAAmB;AAC5B;AAEA,OAAO,SAASsB,cAAcA,CAC5BxB,YAA0B,EAC1BC,YAA4B,EACJ;EACxB,MAAME,cAAc,GAAG,IAAIC,GAAG,CAAS,CAAC;EACxC,IAAIqB,UAAU,GAAG,CAAC;EAClB,MAAMC,WAAmC,GAAG,CAAC,CAAC;EAG9C,KAAK,MAAMrB,OAAO,IAAIJ,YAAY,EAAE;IAElC,IAAI,YAAY,IAAII,OAAO,EAAE;MAC3B,KAAK,MAAMsB,WAAW,IAAItB,OAAO,CAACI,UAAU,EAAE;QAC5CN,cAAc,CAACyB,GAAG,CAACD,WAAW,CAACf,SAAS,CAAC;MAC3C;IAEF,CAAC,MAAM;MACLT,cAAc,CAACyB,GAAG,CAACvB,OAAO,CAACgB,IAAI,CAAC;IAClC;IACAK,WAAW,CAACrB,OAAO,CAACgB,IAAI,CAAC,GAAGI,UAAU,EAAE;EAC1C;EAGA,KAAK,MAAMb,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACoB,GAAG,CAACX,SAAS,CAACS,IAAI,CAAC,EAAE;MACvCK,WAAW,CAACd,SAAS,CAACS,IAAI,CAAC,GAAGI,UAAU,EAAE;IAC5C;EACF;EAEA,OAAOC,WAAW;AACpB;AAOA,SAASZ,mBAAmBA,CAC1Bd,YAA0B,EAC1BqB,IAAY,EACZQ,cAA2B,EACL;EACtB,MAAMjB,SAAS,GAAGZ,YAAY,CAACS,UAAU,CAACqB,IAAI,CAAClB,SAAS,IAAIA,SAAS,CAACS,IAAI,KAAKA,IAAI,CAAC;EACpF,IAAI,CAACT,SAAS,EAAE;IACdnB,GAAG,CAACsC,IAAI,CAAE,qBAAoBV,IAAK,EAAC,CAAC,CAAC,CAAC;IACvC,OAAO,IAAI;EACb;EACA,IAAIQ,cAAc,CAACN,GAAG,CAACF,IAAI,CAAC,EAAE;IAC5B,MAAM,IAAIvB,KAAK,CAAE,uBAAsBuB,IAAK,EAAC,CAAC;EAChD;EACAQ,cAAc,CAACD,GAAG,CAACP,IAAI,CAAC;EACxB,OAAOT,SAAS;AAClB"}
1
+ {"version":3,"file":"get-vertex-buffer-layout.js","names":["log","decodeVertexFormat","getWebGPUVertexFormat","format","endsWith","Error","getVertexBufferLayout","shaderLayout","bufferLayout","vertexBufferLayouts","usedAttributes","Set","mapping","vertexAttributes","stepMode","byteStride","attributes","attributeMapping","attributeName","attribute","attributeLayout","findAttributeLayout","name","startsWith","push","offset","byteOffset","shaderLocation","location","byteLength","arrayStride","has","getBufferSlots","bufferSlot","bufferSlots","interleaved","add","attributeNames","find","warn"],"sources":["../../../src/adapter/helpers/get-vertex-buffer-layout.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';\nimport {log, decodeVertexFormat} from '@luma.gl/core';\n// import {getAttributeInfosFromLayouts} from '@luma.gl/core';\n\n/** Throw error on any WebGL-only vertex formats */\nfunction getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {\n if (format.endsWith('-webgl')) {\n throw new Error(`WebGPU does not support vertex format ${format}`);\n }\n return format as GPUVertexFormat;\n}\n\n/**\n * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.\n * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array\n * @param layout\n * @param bufferLayout The buffer map is optional\n * @returns WebGPU layout intended for a GPURenderPassDescriptor.\n */\nexport function getVertexBufferLayout(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): GPUVertexBufferLayout[] {\n const vertexBufferLayouts: GPUVertexBufferLayout[] = [];\n const usedAttributes = new Set<string>();\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // Build vertex attributes for one buffer\n const vertexAttributes: GPUVertexAttribute[] = [];\n\n // TODO verify that all stepModes for one buffer are the same\n let stepMode: 'vertex' | 'instance' = 'vertex';\n let byteStride = 0;\n // interleaved mapping {..., attributes: [{...}, ...]}\n if (mapping.attributes) {\n // const arrayStride = mapping.byteStride; TODO\n for (const attributeMapping of mapping.attributes) {\n const attributeName = attributeMapping.attribute;\n const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);\n\n stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');\n vertexAttributes.push({\n format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),\n offset: attributeMapping.byteOffset,\n shaderLocation: attributeLayout.location\n });\n\n byteStride += decodeVertexFormat(mapping.format).byteLength;\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);\n if (!attributeLayout) {\n continue; // eslint-disable-line no-continue\n }\n byteStride = decodeVertexFormat(mapping.format).byteLength;\n\n stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith('instance') ? 'instance' : 'vertex');\n vertexAttributes.push({\n format: getWebGPUVertexFormat(mapping.format),\n // We only support 0 offset for non-interleaved buffer layouts\n offset: 0,\n shaderLocation: attributeLayout.location\n });\n }\n\n // Store all the attribute bindings for one buffer\n vertexBufferLayouts.push({\n arrayStride: mapping.byteStride || byteStride,\n stepMode,\n attributes: vertexAttributes\n });\n }\n\n // Add any non-mapped attributes - TODO - avoid hardcoded types\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n vertexBufferLayouts.push({\n arrayStride: decodeVertexFormat('float32x3').byteLength,\n stepMode: attribute.stepMode || (attribute.name.startsWith('instance') ? 'instance' : 'vertex'),\n attributes: [\n {\n format: getWebGPUVertexFormat('float32x3'),\n offset: 0,\n shaderLocation: attribute.location\n }\n ]\n });\n }\n }\n\n return vertexBufferLayouts;\n}\n\nexport function getBufferSlots(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): Record<string, number> {\n const usedAttributes = new Set<string>();\n let bufferSlot = 0;\n const bufferSlots: Record<string, number> = {};\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // interleaved mapping {..., attributes: [{...}, ...]}\n if ('attributes' in mapping) {\n for (const interleaved of mapping.attributes) {\n usedAttributes.add(interleaved.attribute);\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n usedAttributes.add(mapping.name);\n }\n bufferSlots[mapping.name] = bufferSlot++;\n }\n\n // Add any non-mapped attributes\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n bufferSlots[attribute.name] = bufferSlot++;\n }\n }\n\n return bufferSlots;\n}\n\n/**\n * Looks up an attribute in the ShaderLayout.\n * @throws if name is not in ShaderLayout\n * @throws if name has already been referenced\n */\nfunction findAttributeLayout(\n shaderLayout: ShaderLayout,\n name: string,\n attributeNames: Set<string>\n): AttributeDeclaration {\n const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);\n if (!attribute) {\n log.warn(`Unknown attribute ${name}`)();\n return null;\n }\n if (attributeNames.has(name)) {\n throw new Error(`Duplicate attribute ${name}`);\n }\n attributeNames.add(name);\n return attribute;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-render-pipeline.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-render-pipeline.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AAClF,OAAO,EAAC,cAAc,EAAE,mBAAmB,EAA2B,MAAM,eAAe,CAAC;AAS5F,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAKlD,2DAA2D;AAC3D,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAE1B,EAAE,EAAE,YAAY,CAAC;IACjB,EAAE,EAAE,YAAY,GAAG,IAAI,CAAQ;IAO/B,4CAA4C;IAC5C,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,UAAU,CAA6B;gBAEnC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,mBAAmB;IAoBnD,OAAO,IAAI,IAAI;IAiCxB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAkBpD,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,IAAI;IAMzD,IAAI,CAAC,OAAO,EAAE;QACZ,UAAU,EAAE,UAAU,CAAC;QACvB,WAAW,EAAE,WAAW,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI;IA2CR,iDAAiD;IACjD,aAAa;IAKb;;OAEG;IACH,SAAS,CAAC,4BAA4B;CAyFvC"}
1
+ {"version":3,"file":"webgpu-render-pipeline.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-render-pipeline.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AAClF,OAAO,EAAC,cAAc,EAAE,mBAAmB,EAA2B,MAAM,eAAe,CAAC;AAS5F,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAKlD,2DAA2D;AAC3D,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAE1B,EAAE,EAAE,YAAY,CAAC;IACjB,EAAE,EAAE,YAAY,GAAG,IAAI,CAAQ;IAO/B,4CAA4C;IAC5C,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,UAAU,CAA6B;gBAEnC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,mBAAmB;IAoBnD,OAAO,IAAI,IAAI;IAiCxB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IASpD,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,IAAI;IAMzD,IAAI,CAAC,OAAO,EAAE;QACZ,UAAU,EAAE,UAAU,CAAC;QACvB,WAAW,EAAE,WAAW,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI;IA2CR,iDAAiD;IACjD,aAAa;IAeb;;OAEG;IACH,SAAS,CAAC,4BAA4B;CAyFvC"}
@@ -27,11 +27,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
27
27
  }
28
28
  destroy() {}
29
29
  setBindings(bindings) {
30
- if (!isObjectEmpty(this.props.bindings)) {
31
- Object.assign(this.props.bindings, bindings);
32
- this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
33
- this._bindGroup = getBindGroup(this.device.handle, this._bindGroupLayout, this.props.shaderLayout, this.props.bindings);
34
- }
30
+ Object.assign(this.props.bindings, bindings);
35
31
  }
36
32
  setUniforms(uniforms) {
37
33
  if (!isObjectEmpty(uniforms)) {
@@ -54,6 +50,8 @@ export class WebGPURenderPipeline extends RenderPipeline {
54
50
  options.vertexArray.unbindAfterRender(options.renderPass);
55
51
  }
56
52
  _getBindGroup() {
53
+ this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
54
+ this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.props.shaderLayout, this.props.bindings);
57
55
  return this._bindGroup;
58
56
  }
59
57
  _getRenderPipelineDescriptor() {
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-render-pipeline.js","names":["RenderPipeline","cast","log","isObjectEmpty","applyParametersToRenderPipelineDescriptor","getWebGPUTextureFormat","getBindGroup","getVertexBufferLayout","WebGPURenderPipeline","constructor","device","props","handle","vs","fs","_bindGroupLayout","_bindGroup","descriptor","_getRenderPipelineDescriptor","groupCollapsed","id","probe","JSON","stringify","groupEnd","createRenderPipeline","label","destroy","setBindings","bindings","Object","assign","getBindGroupLayout","shaderLayout","setUniforms","uniforms","Error","draw","options","webgpuRenderPass","renderPass","getDefaultRenderPass","setPipeline","bindGroup","_getBindGroup","setBindGroup","vertexArray","bindBeforeRender","indexCount","drawIndexed","instanceCount","firstIndex","baseVertex","firstInstance","vertexCount","unbindAfterRender","vertex","module","entryPoint","vsEntryPoint","buffers","bufferLayout","fragment","_this$device","fsEntryPoint","targets","format","canvasContext","topology","primitive","layout","parameters"],"sources":["../../../src/adapter/resources/webgpu-render-pipeline.ts"],"sourcesContent":["// luma.gl MIT license\n\nimport type {Binding, UniformValue, RenderPass, VertexArray} from '@luma.gl/core';\nimport {RenderPipeline, RenderPipelineProps, cast, log, isObjectEmpty} from '@luma.gl/core';\nimport {applyParametersToRenderPipelineDescriptor} from '../helpers/webgpu-parameters';\nimport {getWebGPUTextureFormat} from '../helpers/convert-texture-format';\nimport {getBindGroup} from '../helpers/get-bind-group';\nimport {getVertexBufferLayout} from '../helpers/get-vertex-buffer-layout';\n// import {convertAttributesVertexBufferToLayout} from '../helpers/get-vertex-buffer-layout';\n// import {mapAccessorToWebGPUFormat} from './helpers/accessor-to-format';\n// import type {BufferAccessors} from './webgpu-pipeline';\n\nimport type {WebGPUDevice} from '../webgpu-device';\n// import type {WebGPUBuffer} from './webgpu-buffer';\nimport type {WebGPUShader} from './webgpu-shader';\nimport type {WebGPURenderPass} from './webgpu-render-pass';\n\n// RENDER PIPELINE\n\n/** Creates a new render pipeline when parameters change */\nexport class WebGPURenderPipeline extends RenderPipeline {\n device: WebGPUDevice;\n handle: GPURenderPipeline;\n\n vs: WebGPUShader;\n fs: WebGPUShader | null = null;\n\n // private _bufferSlots: Record<string, number>;\n // private _buffers: Buffer[];\n // private _firstIndex: number;\n // private _lastIndex: number;\n\n /** For internal use to create BindGroups */\n private _bindGroupLayout: GPUBindGroupLayout | null = null;\n private _bindGroup: GPUBindGroup | null = null;\n\n constructor(device: WebGPUDevice, props: RenderPipelineProps) {\n super(device, props);\n this.device = device;\n this.handle = this.props.handle as GPURenderPipeline;\n if (!this.handle) {\n const descriptor = this._getRenderPipelineDescriptor();\n log.groupCollapsed(1, `new WebGPURenderPipeline(${this.id})`)();\n log.probe(1, JSON.stringify(descriptor, null, 2))();\n log.groupEnd(1)();\n this.handle = this.device.handle.createRenderPipeline(descriptor); \n }\n this.handle.label = this.props.id;\n\n this.vs = cast<WebGPUShader>(props.vs);\n this.fs = cast<WebGPUShader>(props.fs);\n\n // this._bufferSlots = getBufferSlots(this.props.shaderLayout, this.props.bufferLayout);\n // this._buffers = new Array<Buffer>(Object.keys(this._bufferSlots).length).fill(null);\n }\n\n override destroy(): void {\n // WebGPURenderPipeline has no destroy method.\n }\n\n // setIndexBuffer(indexBuffer: Buffer): void {\n // this._indexBuffer = cast<WebGPUBuffer>(indexBuffer);\n // }\n\n /*\n setAttributes(attributes: Record<string, Buffer>): void {\n for (const [name, buffer] of Object.entries(attributes)) {\n const bufferIndex = this._bufferSlots[name];\n if (bufferIndex >= 0) {\n this._buffers[bufferIndex] = buffer;\n } else {\n throw new Error(\n `Setting attribute '${name}' not listed in shader layout for program ${this.id}`\n );\n }\n }\n // for (let i = 0; i < this._bufferSlots.length; ++i) {\n // const bufferName = this._bufferSlots[i];\n // if (attributes[bufferName]) {\n // this.handle\n // }\n // }\n }\n */\n\n // setConstantAttributes(attributes: Record<string, TypedArray>): void {\n // throw new Error('not implemented');\n // }\n\n setBindings(bindings: Record<string, Binding>): void {\n if (!isObjectEmpty(this.props.bindings)) {\n // Do we want to save things on CPU side?\n Object.assign(this.props.bindings, bindings);\n\n // Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group\n this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);\n\n // Set up the bindings\n this._bindGroup = getBindGroup(\n this.device.handle,\n this._bindGroupLayout,\n this.props.shaderLayout,\n this.props.bindings\n );\n }\n }\n\n setUniforms(uniforms: Record<string, UniformValue>): void {\n if (!isObjectEmpty(uniforms)) {\n throw new Error('WebGPU does not support uniforms');\n }\n }\n\n draw(options: {\n renderPass: RenderPass;\n vertexArray: VertexArray;\n vertexCount?: number;\n indexCount?: number;\n instanceCount?: number;\n firstVertex?: number;\n firstIndex?: number;\n firstInstance?: number;\n baseVertex?: number;\n }): void {\n const webgpuRenderPass: WebGPURenderPass =\n cast<WebGPURenderPass>(options.renderPass) || this.device.getDefaultRenderPass();\n\n // Set pipeline\n webgpuRenderPass.handle.setPipeline(this.handle);\n\n // Set bindings (uniform buffers, textures etc)\n const bindGroup = this._getBindGroup();\n if (bindGroup) {\n webgpuRenderPass.handle.setBindGroup(0, bindGroup);\n }\n\n\n // Set attributes\n // Note: Rebinds constant attributes before each draw call\n options.vertexArray.bindBeforeRender(options.renderPass);\n\n // Draw\n if (options.indexCount) {\n webgpuRenderPass.handle.drawIndexed(\n options.indexCount,\n options.instanceCount,\n options.firstIndex,\n options.baseVertex,\n options.firstInstance\n );\n } else {\n webgpuRenderPass.handle.draw(\n options.vertexCount || 0,\n options.instanceCount || 1, // If 0, nothing will be drawn\n options.firstInstance\n );\n }\n\n // Note: Rebinds constant attributes before each draw call\n options.vertexArray.unbindAfterRender(options.renderPass);\n }\n\n // _getBuffers() {\n // return this._buffers;\n // }\n\n /** Return a bind group created by setBindings */\n _getBindGroup() {\n // assert(this._bindGroup);\n return this._bindGroup;\n }\n\n /** \n * Populate the complex WebGPU GPURenderPipelineDescriptor \n */\n protected _getRenderPipelineDescriptor() {\n // Set up the vertex stage\n const vertex: GPUVertexState = {\n module: cast<WebGPUShader>(this.props.vs).handle,\n entryPoint: this.props.vsEntryPoint || 'main',\n buffers: getVertexBufferLayout(this.props.shaderLayout, this.props.bufferLayout)\n };\n\n // Set up the fragment stage\n let fragment: GPUFragmentState | undefined;\n if (this.props.fs) {\n fragment = {\n module: cast<WebGPUShader>(this.props.fs).handle,\n entryPoint: this.props.fsEntryPoint || 'main',\n targets: [\n {\n // TODO exclamation mark hack!\n format: getWebGPUTextureFormat(this.device?.canvasContext?.format)\n }\n ]\n };\n }\n\n // WebGPU has more restrictive topology support than WebGL\n switch (this.props.topology) {\n case 'triangle-fan-webgl':\n case 'line-loop-webgl':\n throw new Error(`WebGPU does not support primitive topology ${this.props.topology}`);\n default:\n }\n\n // Create a partially populated descriptor\n const descriptor: GPURenderPipelineDescriptor = {\n vertex,\n fragment,\n primitive: {\n topology: this.props.topology\n },\n layout: 'auto'\n };\n\n // Set parameters on the descriptor\n applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);\n\n return descriptor;\n }\n\n /**\n _setAttributeBuffers(webgpuRenderPass: WebGPURenderPass) {\n if (this._indexBuffer) {\n webgpuRenderPass.handle.setIndexBuffer(this._indexBuffer.handle, this._indexBuffer.props.indexType);\n }\n\n const buffers = this._getBuffers();\n for (let i = 0; i < buffers.length; ++i) {\n const buffer = cast<WebGPUBuffer>(buffers[i]);\n if (!buffer) {\n const attribute = this.props.shaderLayout.attributes.find(\n (attribute) => attribute.location === i\n );\n throw new Error(\n `No buffer provided for attribute '${attribute?.name || ''}' in Model '${this.props.id}'`\n );\n }\n webgpuRenderPass.handle.setVertexBuffer(i, buffer.handle);\n }\n\n // TODO - HANDLE buffer maps\n /*\n for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {\n const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);\n if (!buffer) {\n log.warn(`Missing buffer for buffer map ${bufferName}`)();\n continue;\n }\n\n if ('location' in attributeMapping) {\n // @ts-expect-error TODO model must not depend on webgpu\n renderPass.handle.setVertexBuffer(layout.location, buffer.handle);\n } else {\n for (const [bufferName, mapping] of Object.entries(attributeMapping)) {\n // @ts-expect-error TODO model must not depend on webgpu\n renderPass.handle.setVertexBuffer(field.location, buffer.handle);\n }\n }\n }\n *\n }\n */\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"webgpu-render-pipeline.js","names":["RenderPipeline","cast","log","isObjectEmpty","applyParametersToRenderPipelineDescriptor","getWebGPUTextureFormat","getBindGroup","getVertexBufferLayout","WebGPURenderPipeline","constructor","device","props","handle","vs","fs","_bindGroupLayout","_bindGroup","descriptor","_getRenderPipelineDescriptor","groupCollapsed","id","probe","JSON","stringify","groupEnd","createRenderPipeline","label","destroy","setBindings","bindings","Object","assign","setUniforms","uniforms","Error","draw","options","webgpuRenderPass","renderPass","getDefaultRenderPass","setPipeline","bindGroup","_getBindGroup","setBindGroup","vertexArray","bindBeforeRender","indexCount","drawIndexed","instanceCount","firstIndex","baseVertex","firstInstance","vertexCount","unbindAfterRender","getBindGroupLayout","shaderLayout","vertex","module","entryPoint","vsEntryPoint","buffers","bufferLayout","fragment","_this$device","fsEntryPoint","targets","format","canvasContext","topology","primitive","layout","parameters"],"sources":["../../../src/adapter/resources/webgpu-render-pipeline.ts"],"sourcesContent":["// luma.gl MIT license\n\nimport type {Binding, UniformValue, RenderPass, VertexArray} from '@luma.gl/core';\nimport {RenderPipeline, RenderPipelineProps, cast, log, isObjectEmpty} from '@luma.gl/core';\nimport {applyParametersToRenderPipelineDescriptor} from '../helpers/webgpu-parameters';\nimport {getWebGPUTextureFormat} from '../helpers/convert-texture-format';\nimport {getBindGroup} from '../helpers/get-bind-group';\nimport {getVertexBufferLayout} from '../helpers/get-vertex-buffer-layout';\n// import {convertAttributesVertexBufferToLayout} from '../helpers/get-vertex-buffer-layout';\n// import {mapAccessorToWebGPUFormat} from './helpers/accessor-to-format';\n// import type {BufferAccessors} from './webgpu-pipeline';\n\nimport type {WebGPUDevice} from '../webgpu-device';\n// import type {WebGPUBuffer} from './webgpu-buffer';\nimport type {WebGPUShader} from './webgpu-shader';\nimport type {WebGPURenderPass} from './webgpu-render-pass';\n\n// RENDER PIPELINE\n\n/** Creates a new render pipeline when parameters change */\nexport class WebGPURenderPipeline extends RenderPipeline {\n device: WebGPUDevice;\n handle: GPURenderPipeline;\n\n vs: WebGPUShader;\n fs: WebGPUShader | null = null;\n\n // private _bufferSlots: Record<string, number>;\n // private _buffers: Buffer[];\n // private _firstIndex: number;\n // private _lastIndex: number;\n\n /** For internal use to create BindGroups */\n private _bindGroupLayout: GPUBindGroupLayout | null = null;\n private _bindGroup: GPUBindGroup | null = null;\n\n constructor(device: WebGPUDevice, props: RenderPipelineProps) {\n super(device, props);\n this.device = device;\n this.handle = this.props.handle as GPURenderPipeline;\n if (!this.handle) {\n const descriptor = this._getRenderPipelineDescriptor();\n log.groupCollapsed(1, `new WebGPURenderPipeline(${this.id})`)();\n log.probe(1, JSON.stringify(descriptor, null, 2))();\n log.groupEnd(1)();\n this.handle = this.device.handle.createRenderPipeline(descriptor); \n }\n this.handle.label = this.props.id;\n\n this.vs = cast<WebGPUShader>(props.vs);\n this.fs = cast<WebGPUShader>(props.fs);\n\n // this._bufferSlots = getBufferSlots(this.props.shaderLayout, this.props.bufferLayout);\n // this._buffers = new Array<Buffer>(Object.keys(this._bufferSlots).length).fill(null);\n }\n\n override destroy(): void {\n // WebGPURenderPipeline has no destroy method.\n }\n\n // setIndexBuffer(indexBuffer: Buffer): void {\n // this._indexBuffer = cast<WebGPUBuffer>(indexBuffer);\n // }\n\n /*\n setAttributes(attributes: Record<string, Buffer>): void {\n for (const [name, buffer] of Object.entries(attributes)) {\n const bufferIndex = this._bufferSlots[name];\n if (bufferIndex >= 0) {\n this._buffers[bufferIndex] = buffer;\n } else {\n throw new Error(\n `Setting attribute '${name}' not listed in shader layout for program ${this.id}`\n );\n }\n }\n // for (let i = 0; i < this._bufferSlots.length; ++i) {\n // const bufferName = this._bufferSlots[i];\n // if (attributes[bufferName]) {\n // this.handle\n // }\n // }\n }\n */\n\n // setConstantAttributes(attributes: Record<string, TypedArray>): void {\n // throw new Error('not implemented');\n // }\n\n setBindings(bindings: Record<string, Binding>): void {\n // if (isObjectEmpty(bindings)) {\n // return;\n // }\n\n // Do we want to save things on CPU side?\n Object.assign(this.props.bindings, bindings);\n }\n\n setUniforms(uniforms: Record<string, UniformValue>): void {\n if (!isObjectEmpty(uniforms)) {\n throw new Error('WebGPU does not support uniforms');\n }\n }\n\n draw(options: {\n renderPass: RenderPass;\n vertexArray: VertexArray;\n vertexCount?: number;\n indexCount?: number;\n instanceCount?: number;\n firstVertex?: number;\n firstIndex?: number;\n firstInstance?: number;\n baseVertex?: number;\n }): void {\n const webgpuRenderPass: WebGPURenderPass =\n cast<WebGPURenderPass>(options.renderPass) || this.device.getDefaultRenderPass();\n\n // Set pipeline\n webgpuRenderPass.handle.setPipeline(this.handle);\n\n // Set bindings (uniform buffers, textures etc)\n const bindGroup = this._getBindGroup();\n if (bindGroup) {\n webgpuRenderPass.handle.setBindGroup(0, bindGroup);\n }\n\n\n // Set attributes\n // Note: Rebinds constant attributes before each draw call\n options.vertexArray.bindBeforeRender(options.renderPass);\n\n // Draw\n if (options.indexCount) {\n webgpuRenderPass.handle.drawIndexed(\n options.indexCount,\n options.instanceCount,\n options.firstIndex,\n options.baseVertex,\n options.firstInstance\n );\n } else {\n webgpuRenderPass.handle.draw(\n options.vertexCount || 0,\n options.instanceCount || 1, // If 0, nothing will be drawn\n options.firstInstance\n );\n }\n\n // Note: Rebinds constant attributes before each draw call\n options.vertexArray.unbindAfterRender(options.renderPass);\n }\n\n // _getBuffers() {\n // return this._buffers;\n // }\n\n /** Return a bind group created by setBindings */\n _getBindGroup() {\n // Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group\n this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);\n\n // Set up the bindings\n this._bindGroup = this._bindGroup || getBindGroup(\n this.device.handle,\n this._bindGroupLayout,\n this.props.shaderLayout,\n this.props.bindings\n );\n\n return this._bindGroup;\n }\n\n /** \n * Populate the complex WebGPU GPURenderPipelineDescriptor \n */\n protected _getRenderPipelineDescriptor() {\n // Set up the vertex stage\n const vertex: GPUVertexState = {\n module: cast<WebGPUShader>(this.props.vs).handle,\n entryPoint: this.props.vsEntryPoint || 'main',\n buffers: getVertexBufferLayout(this.props.shaderLayout, this.props.bufferLayout)\n };\n\n // Set up the fragment stage\n let fragment: GPUFragmentState | undefined;\n if (this.props.fs) {\n fragment = {\n module: cast<WebGPUShader>(this.props.fs).handle,\n entryPoint: this.props.fsEntryPoint || 'main',\n targets: [\n {\n // TODO exclamation mark hack!\n format: getWebGPUTextureFormat(this.device?.canvasContext?.format)\n }\n ]\n };\n }\n\n // WebGPU has more restrictive topology support than WebGL\n switch (this.props.topology) {\n case 'triangle-fan-webgl':\n case 'line-loop-webgl':\n throw new Error(`WebGPU does not support primitive topology ${this.props.topology}`);\n default:\n }\n\n // Create a partially populated descriptor\n const descriptor: GPURenderPipelineDescriptor = {\n vertex,\n fragment,\n primitive: {\n topology: this.props.topology\n },\n layout: 'auto'\n };\n\n // Set parameters on the descriptor\n applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);\n\n return descriptor;\n }\n\n /**\n _setAttributeBuffers(webgpuRenderPass: WebGPURenderPass) {\n if (this._indexBuffer) {\n webgpuRenderPass.handle.setIndexBuffer(this._indexBuffer.handle, this._indexBuffer.props.indexType);\n }\n\n const buffers = this._getBuffers();\n for (let i = 0; i < buffers.length; ++i) {\n const buffer = cast<WebGPUBuffer>(buffers[i]);\n if (!buffer) {\n const attribute = this.props.shaderLayout.attributes.find(\n (attribute) => attribute.location === i\n );\n throw new Error(\n `No buffer provided for attribute '${attribute?.name || ''}' in Model '${this.props.id}'`\n );\n }\n webgpuRenderPass.handle.setVertexBuffer(i, buffer.handle);\n }\n\n // TODO - HANDLE buffer maps\n /*\n for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {\n const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);\n if (!buffer) {\n log.warn(`Missing buffer for buffer map ${bufferName}`)();\n continue;\n }\n\n if ('location' in attributeMapping) {\n // @ts-expect-error TODO model must not depend on webgpu\n renderPass.handle.setVertexBuffer(layout.location, buffer.handle);\n } else {\n for (const [bufferName, mapping] of Object.entries(attributeMapping)) {\n // @ts-expect-error TODO model must not depend on webgpu\n renderPass.handle.setVertexBuffer(field.location, buffer.handle);\n }\n }\n }\n *\n }\n */\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-shader.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-shader.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,EAAC,MAAM,EAAM,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;gBAErB,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB;IAYpD,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxE,OAAO,IAAI,IAAI;IAKxB,+CAA+C;IACzC,kBAAkB,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAO/D,SAAS,CAAC,YAAY,IAAI,eAAe;CAuB1C"}
1
+ {"version":3,"file":"webgpu-shader.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-shader.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,EAAC,MAAM,EAAM,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;gBAErB,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB;IAYpD,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxE,OAAO,IAAI,IAAI;IAKxB,+CAA+C;IACzC,kBAAkB,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAO/D,SAAS,CAAC,YAAY,IAAI,eAAe;CAuB1C"}
@@ -13,6 +13,7 @@ export class WebGPUShader extends Shader {
13
13
  async _checkCompilationError(errorScope) {
14
14
  const error = await errorScope;
15
15
  if (error) {
16
+ this.debugShader();
16
17
  const shaderLog = await this.getCompilationInfo();
17
18
  log.error(`Shader compilation error: ${error.message}`, shaderLog)();
18
19
  throw new Error(`Shader compilation error: ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-shader.js","names":["Shader","log","WebGPUShader","constructor","device","props","handle","pushErrorScope","createHandle","label","id","_checkCompilationError","popErrorScope","errorScope","error","shaderLog","getCompilationInfo","message","Error","destroy","compilationInfo","messages","source","stage","language","includes","createShaderModule","code","transform","glsl","glslang","compileGLSL"],"sources":["../../../src/adapter/resources/webgpu-shader.ts"],"sourcesContent":["// luma.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderProps, CompilerMessage} from '@luma.gl/core';\nimport {Shader, log} from '@luma.gl/core';\nimport type {WebGPUDevice} from '../webgpu-device';\n\nexport type WebGPUShaderProps = ShaderProps & {\n handle?: GPUShaderModule;\n};\n\n/**\n * Immutable shader\n */\nexport class WebGPUShader extends Shader {\n readonly device: WebGPUDevice;\n readonly handle: GPUShaderModule;\n\n constructor(device: WebGPUDevice, props: WebGPUShaderProps) {\n super(device, props);\n this.device = device;\n\n this.device.handle.pushErrorScope('validation');\n\n this.handle = this.props.handle || this.createHandle();\n this.handle.label = this.props.id;\n\n this._checkCompilationError(this.device.handle.popErrorScope());\n }\n\n async _checkCompilationError(errorScope: Promise<GPUError | null>): Promise<void> {\n const error = await errorScope as GPUValidationError;\n if (error) {\n const shaderLog = await this.getCompilationInfo();\n log.error(`Shader compilation error: ${error.message}`, shaderLog)();\n // Note: Even though this error is asynchronous and thrown after the constructor completes,\n // it will result in a useful stack trace leading back to the constructor\n throw new Error(`Shader compilation error: ${error.message}`);\n }\n }\n\n override destroy(): void {\n // Note: WebGPU does not offer a method to destroy shaders\n // this.handle.destroy();\n }\n\n /** Returns compilation info for this shader */\n async getCompilationInfo(): Promise<readonly CompilerMessage[]> {\n const compilationInfo = await this.handle.getCompilationInfo();\n return compilationInfo.messages;\n }\n\n // PRIVATE METHODS\n\n protected createHandle(): GPUShaderModule {\n const {source, stage} = this.props;\n\n let language = this.props.language;\n // Compile from src\n if (language === 'auto') {\n // wgsl uses C++ \"auto\" style arrow notation\n language = source.includes('->') ? 'wgsl' : 'glsl';\n }\n\n switch(language) {\n case 'wgsl':\n return this.device.handle.createShaderModule({code: source});\n case 'glsl':\n return this.device.handle.createShaderModule({\n code: source,\n // @ts-expect-error\n transform: (glsl) => this.device.glslang.compileGLSL(glsl, stage)\n });\n default:\n throw new Error(language);\n }\n }\n}\n"],"mappings":"AAIA,SAAQA,MAAM,EAAEC,GAAG,QAAO,eAAe;AAUzC,OAAO,MAAMC,YAAY,SAASF,MAAM,CAAC;EAIvCG,WAAWA,CAACC,MAAoB,EAAEC,KAAwB,EAAE;IAC1D,KAAK,CAACD,MAAM,EAAEC,KAAK,CAAC;IAAC,KAJdD,MAAM;IAAA,KACNE,MAAM;IAIb,IAAI,CAACF,MAAM,GAAGA,MAAM;IAEpB,IAAI,CAACA,MAAM,CAACE,MAAM,CAACC,cAAc,CAAC,YAAY,CAAC;IAE/C,IAAI,CAACD,MAAM,GAAG,IAAI,CAACD,KAAK,CAACC,MAAM,IAAI,IAAI,CAACE,YAAY,CAAC,CAAC;IACtD,IAAI,CAACF,MAAM,CAACG,KAAK,GAAG,IAAI,CAACJ,KAAK,CAACK,EAAE;IAEjC,IAAI,CAACC,sBAAsB,CAAC,IAAI,CAACP,MAAM,CAACE,MAAM,CAACM,aAAa,CAAC,CAAC,CAAC;EACjE;EAEA,MAAMD,sBAAsBA,CAACE,UAAoC,EAAiB;IAChF,MAAMC,KAAK,GAAG,MAAMD,UAAgC;IACpD,IAAIC,KAAK,EAAE;MACT,MAAMC,SAAS,GAAG,MAAM,IAAI,CAACC,kBAAkB,CAAC,CAAC;MACjDf,GAAG,CAACa,KAAK,CAAE,6BAA4BA,KAAK,CAACG,OAAQ,EAAC,EAAEF,SAAS,CAAC,CAAC,CAAC;MAGpE,MAAM,IAAIG,KAAK,CAAE,6BAA4BJ,KAAK,CAACG,OAAQ,EAAC,CAAC;IAC/D;EACF;EAESE,OAAOA,CAAA,EAAS,CAGzB;EAGA,MAAMH,kBAAkBA,CAAA,EAAwC;IAC9D,MAAMI,eAAe,GAAG,MAAM,IAAI,CAACd,MAAM,CAACU,kBAAkB,CAAC,CAAC;IAC9D,OAAOI,eAAe,CAACC,QAAQ;EACjC;EAIUb,YAAYA,CAAA,EAAoB;IACxC,MAAM;MAACc,MAAM;MAAEC;IAAK,CAAC,GAAG,IAAI,CAAClB,KAAK;IAElC,IAAImB,QAAQ,GAAG,IAAI,CAACnB,KAAK,CAACmB,QAAQ;IAElC,IAAIA,QAAQ,KAAK,MAAM,EAAE;MAEvBA,QAAQ,GAAGF,MAAM,CAACG,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM;IACpD;IAEA,QAAOD,QAAQ;MACb,KAAK,MAAM;QACT,OAAO,IAAI,CAACpB,MAAM,CAACE,MAAM,CAACoB,kBAAkB,CAAC;UAACC,IAAI,EAAEL;QAAM,CAAC,CAAC;MAC9D,KAAK,MAAM;QACT,OAAO,IAAI,CAAClB,MAAM,CAACE,MAAM,CAACoB,kBAAkB,CAAC;UAC3CC,IAAI,EAAEL,MAAM;UAEZM,SAAS,EAAGC,IAAI,IAAK,IAAI,CAACzB,MAAM,CAAC0B,OAAO,CAACC,WAAW,CAACF,IAAI,EAAEN,KAAK;QAClE,CAAC,CAAC;MACJ;QACE,MAAM,IAAIL,KAAK,CAACM,QAAQ,CAAC;IAC7B;EACF;AACF"}
1
+ {"version":3,"file":"webgpu-shader.js","names":["Shader","log","WebGPUShader","constructor","device","props","handle","pushErrorScope","createHandle","label","id","_checkCompilationError","popErrorScope","errorScope","error","debugShader","shaderLog","getCompilationInfo","message","Error","destroy","compilationInfo","messages","source","stage","language","includes","createShaderModule","code","transform","glsl","glslang","compileGLSL"],"sources":["../../../src/adapter/resources/webgpu-shader.ts"],"sourcesContent":["// luma.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderProps, CompilerMessage} from '@luma.gl/core';\nimport {Shader, log} from '@luma.gl/core';\nimport type {WebGPUDevice} from '../webgpu-device';\n\nexport type WebGPUShaderProps = ShaderProps & {\n handle?: GPUShaderModule;\n};\n\n/**\n * Immutable shader\n */\nexport class WebGPUShader extends Shader {\n readonly device: WebGPUDevice;\n readonly handle: GPUShaderModule;\n\n constructor(device: WebGPUDevice, props: WebGPUShaderProps) {\n super(device, props);\n this.device = device;\n\n this.device.handle.pushErrorScope('validation');\n\n this.handle = this.props.handle || this.createHandle();\n this.handle.label = this.props.id;\n\n this._checkCompilationError(this.device.handle.popErrorScope());\n }\n\n async _checkCompilationError(errorScope: Promise<GPUError | null>): Promise<void> {\n const error = await errorScope as GPUValidationError;\n if (error) {\n // The `Shader` base class will determine if debug window should be opened based on props\n this.debugShader();\n\n const shaderLog = await this.getCompilationInfo();\n log.error(`Shader compilation error: ${error.message}`, shaderLog)();\n // Note: Even though this error is asynchronous and thrown after the constructor completes,\n // it will result in a useful stack trace leading back to the constructor\n throw new Error(`Shader compilation error: ${error.message}`);\n }\n }\n\n override destroy(): void {\n // Note: WebGPU does not offer a method to destroy shaders\n // this.handle.destroy();\n }\n\n /** Returns compilation info for this shader */\n async getCompilationInfo(): Promise<readonly CompilerMessage[]> {\n const compilationInfo = await this.handle.getCompilationInfo();\n return compilationInfo.messages;\n }\n\n // PRIVATE METHODS\n\n protected createHandle(): GPUShaderModule {\n const {source, stage} = this.props;\n\n let language = this.props.language;\n // Compile from src\n if (language === 'auto') {\n // wgsl uses C++ \"auto\" style arrow notation\n language = source.includes('->') ? 'wgsl' : 'glsl';\n }\n\n switch(language) {\n case 'wgsl':\n return this.device.handle.createShaderModule({code: source});\n case 'glsl':\n return this.device.handle.createShaderModule({\n code: source,\n // @ts-expect-error\n transform: (glsl) => this.device.glslang.compileGLSL(glsl, stage)\n });\n default:\n throw new Error(language);\n }\n }\n}\n"],"mappings":"AAIA,SAAQA,MAAM,EAAEC,GAAG,QAAO,eAAe;AAUzC,OAAO,MAAMC,YAAY,SAASF,MAAM,CAAC;EAIvCG,WAAWA,CAACC,MAAoB,EAAEC,KAAwB,EAAE;IAC1D,KAAK,CAACD,MAAM,EAAEC,KAAK,CAAC;IAAC,KAJdD,MAAM;IAAA,KACNE,MAAM;IAIb,IAAI,CAACF,MAAM,GAAGA,MAAM;IAEpB,IAAI,CAACA,MAAM,CAACE,MAAM,CAACC,cAAc,CAAC,YAAY,CAAC;IAE/C,IAAI,CAACD,MAAM,GAAG,IAAI,CAACD,KAAK,CAACC,MAAM,IAAI,IAAI,CAACE,YAAY,CAAC,CAAC;IACtD,IAAI,CAACF,MAAM,CAACG,KAAK,GAAG,IAAI,CAACJ,KAAK,CAACK,EAAE;IAEjC,IAAI,CAACC,sBAAsB,CAAC,IAAI,CAACP,MAAM,CAACE,MAAM,CAACM,aAAa,CAAC,CAAC,CAAC;EACjE;EAEA,MAAMD,sBAAsBA,CAACE,UAAoC,EAAiB;IAChF,MAAMC,KAAK,GAAG,MAAMD,UAAgC;IACpD,IAAIC,KAAK,EAAE;MAET,IAAI,CAACC,WAAW,CAAC,CAAC;MAElB,MAAMC,SAAS,GAAG,MAAM,IAAI,CAACC,kBAAkB,CAAC,CAAC;MACjDhB,GAAG,CAACa,KAAK,CAAE,6BAA4BA,KAAK,CAACI,OAAQ,EAAC,EAAEF,SAAS,CAAC,CAAC,CAAC;MAGpE,MAAM,IAAIG,KAAK,CAAE,6BAA4BL,KAAK,CAACI,OAAQ,EAAC,CAAC;IAC/D;EACF;EAESE,OAAOA,CAAA,EAAS,CAGzB;EAGA,MAAMH,kBAAkBA,CAAA,EAAwC;IAC9D,MAAMI,eAAe,GAAG,MAAM,IAAI,CAACf,MAAM,CAACW,kBAAkB,CAAC,CAAC;IAC9D,OAAOI,eAAe,CAACC,QAAQ;EACjC;EAIUd,YAAYA,CAAA,EAAoB;IACxC,MAAM;MAACe,MAAM;MAAEC;IAAK,CAAC,GAAG,IAAI,CAACnB,KAAK;IAElC,IAAIoB,QAAQ,GAAG,IAAI,CAACpB,KAAK,CAACoB,QAAQ;IAElC,IAAIA,QAAQ,KAAK,MAAM,EAAE;MAEvBA,QAAQ,GAAGF,MAAM,CAACG,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM;IACpD;IAEA,QAAOD,QAAQ;MACb,KAAK,MAAM;QACT,OAAO,IAAI,CAACrB,MAAM,CAACE,MAAM,CAACqB,kBAAkB,CAAC;UAACC,IAAI,EAAEL;QAAM,CAAC,CAAC;MAC9D,KAAK,MAAM;QACT,OAAO,IAAI,CAACnB,MAAM,CAACE,MAAM,CAACqB,kBAAkB,CAAC;UAC3CC,IAAI,EAAEL,MAAM;UAEZM,SAAS,EAAGC,IAAI,IAAK,IAAI,CAAC1B,MAAM,CAAC2B,OAAO,CAACC,WAAW,CAACF,IAAI,EAAEN,KAAK;QAClE,CAAC,CAAC;MACJ;QACE,MAAM,IAAIL,KAAK,CAACM,QAAQ,CAAC;IAC7B;EACF;AACF"}
@@ -16,8 +16,8 @@ export declare class WebGPUVertexArray extends VertexArray {
16
16
  * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
17
17
  */
18
18
  setIndexBuffer(buffer: Buffer | null): void;
19
- /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
20
- setBuffer(location: number, buffer: Buffer): void;
19
+ /** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
20
+ setBuffer(bufferSlot: number, buffer: Buffer): void;
21
21
  /** Set a location in vertex attributes array to a constant value, disables the location */
22
22
  setConstant(location: number, value: TypedArray): void;
23
23
  bindBeforeRender(renderPass: RenderPass, firstIndex?: number, indexCount?: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-vertex-array.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-vertex-array.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAC,WAAW,EAAM,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAK9C,gCAAgC;AAChC,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,IAAa,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAE1C;IAED,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAEvB,6EAA6E;IAC7E,MAAM,CAAC,gCAAgC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;gBAKpD,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,gBAAgB;IAKjD,OAAO,IAAI,IAAI;IAExB;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK3C,gGAAgG;IAChG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IASjD,2FAA2F;IAClF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAItD,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAkBxF,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;CAKzD"}
1
+ {"version":3,"file":"webgpu-vertex-array.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgpu-vertex-array.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAC,WAAW,EAAM,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAK9C,gCAAgC;AAChC,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,IAAa,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAE1C;IAED,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAEvB,6EAA6E;IAC7E,MAAM,CAAC,gCAAgC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;gBAKpD,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,gBAAgB;IAKjD,OAAO,IAAI,IAAI;IAExB;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK3C,oGAAoG;IACpG,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IASnD,2FAA2F;IAClF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAItD,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAkBxF,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;CAKzD"}
@@ -19,8 +19,8 @@ export class WebGPUVertexArray extends VertexArray {
19
19
  setIndexBuffer(buffer) {
20
20
  this.indexBuffer = buffer;
21
21
  }
22
- setBuffer(location, buffer) {
23
- this.attributes[location] = buffer;
22
+ setBuffer(bufferSlot, buffer) {
23
+ this.attributes[bufferSlot] = buffer;
24
24
  }
25
25
  setConstant(location, value) {
26
26
  log.warn(`${this.id} constant attributes not supported on WebGPU`);
@@ -35,7 +35,7 @@ export class WebGPUVertexArray extends VertexArray {
35
35
  for (let location = 0; location < this.maxVertexAttributes; location++) {
36
36
  const webgpuBuffer = this.attributes[location];
37
37
  if (webgpuBuffer !== null && webgpuBuffer !== void 0 && webgpuBuffer.handle) {
38
- log.warn('setting vertex buffer', location, webgpuBuffer === null || webgpuBuffer === void 0 ? void 0 : webgpuBuffer.handle)();
38
+ log.warn(`setting vertex buffer ${location}`, webgpuBuffer === null || webgpuBuffer === void 0 ? void 0 : webgpuBuffer.handle)();
39
39
  webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer === null || webgpuBuffer === void 0 ? void 0 : webgpuBuffer.handle);
40
40
  }
41
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-vertex-array.js","names":["VertexArray","log","getBrowser","_Symbol$toStringTag","Symbol","toStringTag","WebGPUVertexArray","isConstantAttributeZeroSupported","device","info","type","constructor","props","handle","destroy","setIndexBuffer","buffer","indexBuffer","setBuffer","location","attributes","setConstant","value","warn","id","bindBeforeRender","renderPass","firstIndex","indexCount","webgpuRenderPass","webgpuIndexBuffer","indexType","maxVertexAttributes","webgpuBuffer","setVertexBuffer","unbindAfterRender"],"sources":["../../../src/adapter/resources/webgpu-vertex-array.ts"],"sourcesContent":["// luma.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {Device, Buffer, VertexArrayProps, RenderPass, TypedArray} from '@luma.gl/core';\nimport {VertexArray, log} from '@luma.gl/core';\nimport {getBrowser} from '@probe.gl/env';\n\nimport {WebGPUDevice} from '../webgpu-device';\nimport {WebGPUBuffer} from '../resources/webgpu-buffer';\n\nimport {WebGPURenderPass} from './webgpu-render-pass';\n\n/** VertexArrayObject wrapper */\nexport class WebGPUVertexArray extends VertexArray {\n override get [Symbol.toStringTag](): string {\n return 'WebGPUVertexArray';\n }\n\n readonly device: WebGPUDevice;\n /** Vertex Array is a helper class under WebGPU */\n readonly handle: never;\n\n /** * Attribute 0 can not be disable on most desktop OpenGL based browsers */\n static isConstantAttributeZeroSupported(device: Device): boolean {\n return device.info.type === 'webgl2' || getBrowser() === 'Chrome';\n }\n\n // Create a VertexArray\n constructor(device: WebGPUDevice, props?: VertexArrayProps) {\n super(device, props);\n this.device = device;\n }\n\n override destroy(): void {}\n\n /**\n * Set an elements buffer, for indexed rendering.\n * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set. \n */\n setIndexBuffer(buffer: Buffer | null): void {\n // assert(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);\n this.indexBuffer = buffer;\n }\n\n /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */\n setBuffer(location: number, buffer: Buffer): void {\n // Sanity check target\n // if (buffer.glUsage === GL.ELEMENT_ARRAY_BUFFER) {\n // throw new Error('Use setIndexBuffer');\n // }\n\n this.attributes[location] = buffer;\n }\n\n /** Set a location in vertex attributes array to a constant value, disables the location */\n override setConstant(location: number, value: TypedArray): void {\n log.warn(`${this.id} constant attributes not supported on WebGPU`)\n }\n\n override bindBeforeRender(renderPass: RenderPass, firstIndex?: number, indexCount?: number): void {\n const webgpuRenderPass = renderPass as WebGPURenderPass;\n const webgpuIndexBuffer = this.indexBuffer as WebGPUBuffer;\n if (webgpuIndexBuffer?.handle) {\n // Note we can't unset an index buffer\n log.warn('setting index buffer', webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType)();\n webgpuRenderPass.handle.setIndexBuffer(webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType);\n }\n for (let location = 0; location < this.maxVertexAttributes; location++) {\n const webgpuBuffer = this.attributes[location] as WebGPUBuffer;\n if (webgpuBuffer?.handle) {\n log.warn('setting vertex buffer', location, webgpuBuffer?.handle)();\n webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);\n }\n }\n // TODO - emit warnings/errors/throw if constants have been set on this vertex array\n }\n\n override unbindAfterRender(renderPass: RenderPass): void {\n // On WebGPU we don't need to unbind. \n // In fact we can't easily do it. setIndexBuffer/setVertexBuffer don't accept null.\n // Unbinding presumably happens automatically when the render pass is ended.\n }\n}\n"],"mappings":";AAIA,SAAQA,WAAW,EAAEC,GAAG,QAAO,eAAe;AAC9C,SAAQC,UAAU,QAAO,eAAe;AAACC,mBAAA,GASzBC,MAAM,CAACC,WAAW;AADlC,OAAO,MAAMC,iBAAiB,SAASN,WAAW,CAAC;EACjD,KAAAG,mBAAA,IAA4C;IAC1C,OAAO,mBAAmB;EAC5B;EAOA,OAAOI,gCAAgCA,CAACC,MAAc,EAAW;IAC/D,OAAOA,MAAM,CAACC,IAAI,CAACC,IAAI,KAAK,QAAQ,IAAIR,UAAU,CAAC,CAAC,KAAK,QAAQ;EACnE;EAGAS,WAAWA,CAACH,MAAoB,EAAEI,KAAwB,EAAE;IAC1D,KAAK,CAACJ,MAAM,EAAEI,KAAK,CAAC;IAAC,KAXdJ,MAAM;IAAA,KAENK,MAAM;IAUb,IAAI,CAACL,MAAM,GAAGA,MAAM;EACtB;EAESM,OAAOA,CAAA,EAAS,CAAC;EAM1BC,cAAcA,CAACC,MAAqB,EAAQ;IAE1C,IAAI,CAACC,WAAW,GAAGD,MAAM;EAC3B;EAGAE,SAASA,CAACC,QAAgB,EAAEH,MAAc,EAAQ;IAMhD,IAAI,CAACI,UAAU,CAACD,QAAQ,CAAC,GAAGH,MAAM;EACpC;EAGSK,WAAWA,CAACF,QAAgB,EAAEG,KAAiB,EAAQ;IAC9DrB,GAAG,CAACsB,IAAI,CAAE,GAAE,IAAI,CAACC,EAAG,8CAA6C,CAAC;EACpE;EAESC,gBAAgBA,CAACC,UAAsB,EAAEC,UAAmB,EAAEC,UAAmB,EAAQ;IAChG,MAAMC,gBAAgB,GAAGH,UAA8B;IACvD,MAAMI,iBAAiB,GAAG,IAAI,CAACb,WAA2B;IAC1D,IAAIa,iBAAiB,aAAjBA,iBAAiB,eAAjBA,iBAAiB,CAAEjB,MAAM,EAAE;MAE7BZ,GAAG,CAACsB,IAAI,CAAC,sBAAsB,EAAEO,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEjB,MAAM,EAAEiB,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEC,SAAS,CAAC,CAAC,CAAC;MAC3FF,gBAAgB,CAAChB,MAAM,CAACE,cAAc,CAACe,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEjB,MAAM,EAAEiB,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEC,SAAS,CAAC;IACjG;IACA,KAAK,IAAIZ,QAAQ,GAAG,CAAC,EAAEA,QAAQ,GAAG,IAAI,CAACa,mBAAmB,EAAEb,QAAQ,EAAE,EAAE;MACtE,MAAMc,YAAY,GAAG,IAAI,CAACb,UAAU,CAACD,QAAQ,CAAiB;MAC9D,IAAIc,YAAY,aAAZA,YAAY,eAAZA,YAAY,CAAEpB,MAAM,EAAE;QACxBZ,GAAG,CAACsB,IAAI,CAAC,uBAAuB,EAAEJ,QAAQ,EAAEc,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAEpB,MAAM,CAAC,CAAC,CAAC;QACnEgB,gBAAgB,CAAChB,MAAM,CAACqB,eAAe,CAACf,QAAQ,EAAEc,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAEpB,MAAM,CAAC;MACzE;IACF;EAEF;EAESsB,iBAAiBA,CAACT,UAAsB,EAAQ,CAIzD;AACF"}
1
+ {"version":3,"file":"webgpu-vertex-array.js","names":["VertexArray","log","getBrowser","_Symbol$toStringTag","Symbol","toStringTag","WebGPUVertexArray","isConstantAttributeZeroSupported","device","info","type","constructor","props","handle","destroy","setIndexBuffer","buffer","indexBuffer","setBuffer","bufferSlot","attributes","setConstant","location","value","warn","id","bindBeforeRender","renderPass","firstIndex","indexCount","webgpuRenderPass","webgpuIndexBuffer","indexType","maxVertexAttributes","webgpuBuffer","setVertexBuffer","unbindAfterRender"],"sources":["../../../src/adapter/resources/webgpu-vertex-array.ts"],"sourcesContent":["// luma.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {Device, Buffer, VertexArrayProps, RenderPass, TypedArray} from '@luma.gl/core';\nimport {VertexArray, log} from '@luma.gl/core';\nimport {getBrowser} from '@probe.gl/env';\n\nimport {WebGPUDevice} from '../webgpu-device';\nimport {WebGPUBuffer} from '../resources/webgpu-buffer';\n\nimport {WebGPURenderPass} from './webgpu-render-pass';\n\n/** VertexArrayObject wrapper */\nexport class WebGPUVertexArray extends VertexArray {\n override get [Symbol.toStringTag](): string {\n return 'WebGPUVertexArray';\n }\n\n readonly device: WebGPUDevice;\n /** Vertex Array is a helper class under WebGPU */\n readonly handle: never;\n\n /** * Attribute 0 can not be disable on most desktop OpenGL based browsers */\n static isConstantAttributeZeroSupported(device: Device): boolean {\n return device.info.type === 'webgl2' || getBrowser() === 'Chrome';\n }\n\n // Create a VertexArray\n constructor(device: WebGPUDevice, props?: VertexArrayProps) {\n super(device, props);\n this.device = device;\n }\n\n override destroy(): void {}\n\n /**\n * Set an elements buffer, for indexed rendering.\n * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set. \n */\n setIndexBuffer(buffer: Buffer | null): void {\n // assert(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);\n this.indexBuffer = buffer;\n }\n\n /** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */\n setBuffer(bufferSlot: number, buffer: Buffer): void {\n // Sanity check target\n // if (buffer.glUsage === GL.ELEMENT_ARRAY_BUFFER) {\n // throw new Error('Use setIndexBuffer');\n // }\n\n this.attributes[bufferSlot] = buffer;\n }\n\n /** Set a location in vertex attributes array to a constant value, disables the location */\n override setConstant(location: number, value: TypedArray): void {\n log.warn(`${this.id} constant attributes not supported on WebGPU`)\n }\n\n override bindBeforeRender(renderPass: RenderPass, firstIndex?: number, indexCount?: number): void {\n const webgpuRenderPass = renderPass as WebGPURenderPass;\n const webgpuIndexBuffer = this.indexBuffer as WebGPUBuffer;\n if (webgpuIndexBuffer?.handle) {\n // Note we can't unset an index buffer\n log.warn('setting index buffer', webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType)();\n webgpuRenderPass.handle.setIndexBuffer(webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType);\n }\n for (let location = 0; location < this.maxVertexAttributes; location++) {\n const webgpuBuffer = this.attributes[location] as WebGPUBuffer;\n if (webgpuBuffer?.handle) {\n log.warn(`setting vertex buffer ${location}`,webgpuBuffer?.handle)();\n webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);\n }\n }\n // TODO - emit warnings/errors/throw if constants have been set on this vertex array\n }\n\n override unbindAfterRender(renderPass: RenderPass): void {\n // On WebGPU we don't need to unbind. \n // In fact we can't easily do it. setIndexBuffer/setVertexBuffer don't accept null.\n // Unbinding presumably happens automatically when the render pass is ended.\n }\n}\n"],"mappings":";AAIA,SAAQA,WAAW,EAAEC,GAAG,QAAO,eAAe;AAC9C,SAAQC,UAAU,QAAO,eAAe;AAACC,mBAAA,GASzBC,MAAM,CAACC,WAAW;AADlC,OAAO,MAAMC,iBAAiB,SAASN,WAAW,CAAC;EACjD,KAAAG,mBAAA,IAA4C;IAC1C,OAAO,mBAAmB;EAC5B;EAOA,OAAOI,gCAAgCA,CAACC,MAAc,EAAW;IAC/D,OAAOA,MAAM,CAACC,IAAI,CAACC,IAAI,KAAK,QAAQ,IAAIR,UAAU,CAAC,CAAC,KAAK,QAAQ;EACnE;EAGAS,WAAWA,CAACH,MAAoB,EAAEI,KAAwB,EAAE;IAC1D,KAAK,CAACJ,MAAM,EAAEI,KAAK,CAAC;IAAC,KAXdJ,MAAM;IAAA,KAENK,MAAM;IAUb,IAAI,CAACL,MAAM,GAAGA,MAAM;EACtB;EAESM,OAAOA,CAAA,EAAS,CAAC;EAM1BC,cAAcA,CAACC,MAAqB,EAAQ;IAE1C,IAAI,CAACC,WAAW,GAAGD,MAAM;EAC3B;EAGAE,SAASA,CAACC,UAAkB,EAAEH,MAAc,EAAQ;IAMlD,IAAI,CAACI,UAAU,CAACD,UAAU,CAAC,GAAGH,MAAM;EACtC;EAGSK,WAAWA,CAACC,QAAgB,EAAEC,KAAiB,EAAQ;IAC9DtB,GAAG,CAACuB,IAAI,CAAE,GAAE,IAAI,CAACC,EAAG,8CAA6C,CAAC;EACpE;EAESC,gBAAgBA,CAACC,UAAsB,EAAEC,UAAmB,EAAEC,UAAmB,EAAQ;IAChG,MAAMC,gBAAgB,GAAGH,UAA8B;IACvD,MAAMI,iBAAiB,GAAG,IAAI,CAACd,WAA2B;IAC1D,IAAIc,iBAAiB,aAAjBA,iBAAiB,eAAjBA,iBAAiB,CAAElB,MAAM,EAAE;MAE7BZ,GAAG,CAACuB,IAAI,CAAC,sBAAsB,EAAEO,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAElB,MAAM,EAAEkB,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEC,SAAS,CAAC,CAAC,CAAC;MAC3FF,gBAAgB,CAACjB,MAAM,CAACE,cAAc,CAACgB,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAElB,MAAM,EAAEkB,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEC,SAAS,CAAC;IACjG;IACA,KAAK,IAAIV,QAAQ,GAAG,CAAC,EAAEA,QAAQ,GAAG,IAAI,CAACW,mBAAmB,EAAEX,QAAQ,EAAE,EAAE;MACtE,MAAMY,YAAY,GAAG,IAAI,CAACd,UAAU,CAACE,QAAQ,CAAiB;MAC9D,IAAIY,YAAY,aAAZA,YAAY,eAAZA,YAAY,CAAErB,MAAM,EAAE;QACxBZ,GAAG,CAACuB,IAAI,CAAE,yBAAwBF,QAAS,EAAC,EAACY,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAErB,MAAM,CAAC,CAAC,CAAC;QACpEiB,gBAAgB,CAACjB,MAAM,CAACsB,eAAe,CAACb,QAAQ,EAAEY,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAErB,MAAM,CAAC;MACzE;IACF;EAEF;EAESuB,iBAAiBA,CAACT,UAAsB,EAAQ,CAIzD;AACF"}
package/dist/dist.dev.js CHANGED
@@ -1041,6 +1041,15 @@ var __exports__ = (() => {
1041
1041
  readPixelsToBufferWebGL2(source, options) {
1042
1042
  throw new Error("not implemented");
1043
1043
  }
1044
+ setParametersWebGL(parameters) {
1045
+ throw new Error("not implemented");
1046
+ }
1047
+ withParametersWebGL(parameters, func) {
1048
+ throw new Error("not implemented");
1049
+ }
1050
+ clearWebGL(options) {
1051
+ throw new Error("not implemented");
1052
+ }
1044
1053
  _getBufferProps(props) {
1045
1054
  if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1046
1055
  props = {
@@ -1425,7 +1434,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
1425
1434
  return numberedLines;
1426
1435
  }
1427
1436
  function getNumberedLine(line, lineNum, options) {
1428
- return `${padLeft(String(lineNum), 4)}: ${line}${options?.html ? "<br/>" : "\n"}`;
1437
+ const escapedLine = options?.html ? escapeHTML(line) : line;
1438
+ return `${padLeft(String(lineNum), 4)}: ${escapedLine}${options?.html ? "<br/>" : "\n"}`;
1429
1439
  }
1430
1440
  function padLeft(string, paddedLength) {
1431
1441
  let result = "";
@@ -1434,6 +1444,9 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
1434
1444
  }
1435
1445
  return result + string;
1436
1446
  }
1447
+ function escapeHTML(unsafe) {
1448
+ return unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
1449
+ }
1437
1450
 
1438
1451
  // ../core/src/lib/compiler-log/get-shader-info.ts
1439
1452
  function getShaderInfo(source, defaultName) {
@@ -2236,6 +2249,7 @@ ${htmlLog}
2236
2249
  async _checkCompilationError(errorScope) {
2237
2250
  const error = await errorScope;
2238
2251
  if (error) {
2252
+ this.debugShader();
2239
2253
  const shaderLog = await this.getCompilationInfo();
2240
2254
  log.error(`Shader compilation error: ${error.message}`, shaderLog)();
2241
2255
  throw new Error(`Shader compilation error: ${error.message}`);
@@ -2416,7 +2430,7 @@ ${htmlLog}
2416
2430
  });
2417
2431
  }
2418
2432
  function getShaderLayoutBinding(shaderLayout, bindingName) {
2419
- const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName);
2433
+ const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());
2420
2434
  if (!bindingLayout) {
2421
2435
  log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
2422
2436
  }
@@ -2475,7 +2489,7 @@ ${htmlLog}
2475
2489
  for (const attributeMapping of mapping.attributes) {
2476
2490
  const attributeName = attributeMapping.attribute;
2477
2491
  const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
2478
- stepMode = attributeLayout.stepMode || "vertex";
2492
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
2479
2493
  vertexAttributes.push({
2480
2494
  format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
2481
2495
  offset: attributeMapping.byteOffset,
@@ -2489,7 +2503,7 @@ ${htmlLog}
2489
2503
  continue;
2490
2504
  }
2491
2505
  byteStride = decodeVertexFormat(mapping.format).byteLength;
2492
- stepMode = attributeLayout.stepMode || "vertex";
2506
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
2493
2507
  vertexAttributes.push({
2494
2508
  format: getWebGPUVertexFormat(mapping.format),
2495
2509
  offset: 0,
@@ -2498,7 +2512,7 @@ ${htmlLog}
2498
2512
  }
2499
2513
  vertexBufferLayouts.push({
2500
2514
  arrayStride: mapping.byteStride || byteStride,
2501
- stepMode: stepMode || "vertex",
2515
+ stepMode,
2502
2516
  attributes: vertexAttributes
2503
2517
  });
2504
2518
  }
@@ -2506,7 +2520,7 @@ ${htmlLog}
2506
2520
  if (!usedAttributes.has(attribute.name)) {
2507
2521
  vertexBufferLayouts.push({
2508
2522
  arrayStride: decodeVertexFormat("float32x3").byteLength,
2509
- stepMode: attribute.stepMode || "vertex",
2523
+ stepMode: attribute.stepMode || (attribute.name.startsWith("instance") ? "instance" : "vertex"),
2510
2524
  attributes: [{
2511
2525
  format: getWebGPUVertexFormat("float32x3"),
2512
2526
  offset: 0,
@@ -2553,11 +2567,7 @@ ${htmlLog}
2553
2567
  destroy() {
2554
2568
  }
2555
2569
  setBindings(bindings) {
2556
- if (!isObjectEmpty(this.props.bindings)) {
2557
- Object.assign(this.props.bindings, bindings);
2558
- this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
2559
- this._bindGroup = getBindGroup(this.device.handle, this._bindGroupLayout, this.props.shaderLayout, this.props.bindings);
2560
- }
2570
+ Object.assign(this.props.bindings, bindings);
2561
2571
  }
2562
2572
  setUniforms(uniforms) {
2563
2573
  if (!isObjectEmpty(uniforms)) {
@@ -2580,6 +2590,8 @@ ${htmlLog}
2580
2590
  options.vertexArray.unbindAfterRender(options.renderPass);
2581
2591
  }
2582
2592
  _getBindGroup() {
2593
+ this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
2594
+ this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.props.shaderLayout, this.props.bindings);
2583
2595
  return this._bindGroup;
2584
2596
  }
2585
2597
  _getRenderPipelineDescriptor() {
@@ -2805,8 +2817,8 @@ ${htmlLog}
2805
2817
  setIndexBuffer(buffer) {
2806
2818
  this.indexBuffer = buffer;
2807
2819
  }
2808
- setBuffer(location, buffer) {
2809
- this.attributes[location] = buffer;
2820
+ setBuffer(bufferSlot, buffer) {
2821
+ this.attributes[bufferSlot] = buffer;
2810
2822
  }
2811
2823
  setConstant(location, value) {
2812
2824
  log.warn(`${this.id} constant attributes not supported on WebGPU`);
@@ -2821,7 +2833,7 @@ ${htmlLog}
2821
2833
  for (let location = 0; location < this.maxVertexAttributes; location++) {
2822
2834
  const webgpuBuffer = this.attributes[location];
2823
2835
  if (webgpuBuffer?.handle) {
2824
- log.warn("setting vertex buffer", location, webgpuBuffer?.handle)();
2836
+ log.warn(`setting vertex buffer ${location}`, webgpuBuffer?.handle)();
2825
2837
  webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
2826
2838
  }
2827
2839
  }
package/dist/index.cjs CHANGED
@@ -381,6 +381,7 @@ var WebGPUShader = class extends import_core5.Shader {
381
381
  async _checkCompilationError(errorScope) {
382
382
  const error = await errorScope;
383
383
  if (error) {
384
+ this.debugShader();
384
385
  const shaderLog = await this.getCompilationInfo();
385
386
  import_core5.log.error(`Shader compilation error: ${error.message}`, shaderLog)();
386
387
  throw new Error(`Shader compilation error: ${error.message}`);
@@ -613,7 +614,7 @@ function getBindGroup(device, bindGroupLayout, shaderLayout, bindings) {
613
614
  });
614
615
  }
615
616
  function getShaderLayoutBinding(shaderLayout, bindingName) {
616
- const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName);
617
+ const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());
617
618
  if (!bindingLayout) {
618
619
  import_core6.log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
619
620
  }
@@ -671,7 +672,7 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
671
672
  for (const attributeMapping of mapping.attributes) {
672
673
  const attributeName = attributeMapping.attribute;
673
674
  const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
674
- stepMode = attributeLayout.stepMode || "vertex";
675
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
675
676
  vertexAttributes.push({
676
677
  format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
677
678
  offset: attributeMapping.byteOffset,
@@ -685,7 +686,7 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
685
686
  continue;
686
687
  }
687
688
  byteStride = (0, import_core7.decodeVertexFormat)(mapping.format).byteLength;
688
- stepMode = attributeLayout.stepMode || "vertex";
689
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
689
690
  vertexAttributes.push({
690
691
  format: getWebGPUVertexFormat(mapping.format),
691
692
  // We only support 0 offset for non-interleaved buffer layouts
@@ -695,7 +696,7 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
695
696
  }
696
697
  vertexBufferLayouts.push({
697
698
  arrayStride: mapping.byteStride || byteStride,
698
- stepMode: stepMode || "vertex",
699
+ stepMode,
699
700
  attributes: vertexAttributes
700
701
  });
701
702
  }
@@ -703,7 +704,7 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
703
704
  if (!usedAttributes.has(attribute.name)) {
704
705
  vertexBufferLayouts.push({
705
706
  arrayStride: (0, import_core7.decodeVertexFormat)("float32x3").byteLength,
706
- stepMode: attribute.stepMode || "vertex",
707
+ stepMode: attribute.stepMode || (attribute.name.startsWith("instance") ? "instance" : "vertex"),
707
708
  attributes: [
708
709
  {
709
710
  format: getWebGPUVertexFormat("float32x3"),
@@ -786,16 +787,7 @@ var WebGPURenderPipeline = class extends import_core8.RenderPipeline {
786
787
  // throw new Error('not implemented');
787
788
  // }
788
789
  setBindings(bindings) {
789
- if (!(0, import_core8.isObjectEmpty)(this.props.bindings)) {
790
- Object.assign(this.props.bindings, bindings);
791
- this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
792
- this._bindGroup = getBindGroup(
793
- this.device.handle,
794
- this._bindGroupLayout,
795
- this.props.shaderLayout,
796
- this.props.bindings
797
- );
798
- }
790
+ Object.assign(this.props.bindings, bindings);
799
791
  }
800
792
  setUniforms(uniforms) {
801
793
  if (!(0, import_core8.isObjectEmpty)(uniforms)) {
@@ -833,6 +825,13 @@ var WebGPURenderPipeline = class extends import_core8.RenderPipeline {
833
825
  // }
834
826
  /** Return a bind group created by setBindings */
835
827
  _getBindGroup() {
828
+ this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
829
+ this._bindGroup = this._bindGroup || getBindGroup(
830
+ this.device.handle,
831
+ this._bindGroupLayout,
832
+ this.props.shaderLayout,
833
+ this.props.bindings
834
+ );
836
835
  return this._bindGroup;
837
836
  }
838
837
  /**
@@ -1174,9 +1173,9 @@ var WebGPUVertexArray = class extends import_core12.VertexArray {
1174
1173
  setIndexBuffer(buffer) {
1175
1174
  this.indexBuffer = buffer;
1176
1175
  }
1177
- /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
1178
- setBuffer(location, buffer) {
1179
- this.attributes[location] = buffer;
1176
+ /** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
1177
+ setBuffer(bufferSlot, buffer) {
1178
+ this.attributes[bufferSlot] = buffer;
1180
1179
  }
1181
1180
  /** Set a location in vertex attributes array to a constant value, disables the location */
1182
1181
  setConstant(location, value) {
@@ -1192,7 +1191,7 @@ var WebGPUVertexArray = class extends import_core12.VertexArray {
1192
1191
  for (let location = 0; location < this.maxVertexAttributes; location++) {
1193
1192
  const webgpuBuffer = this.attributes[location];
1194
1193
  if (webgpuBuffer == null ? void 0 : webgpuBuffer.handle) {
1195
- import_core12.log.warn("setting vertex buffer", location, webgpuBuffer == null ? void 0 : webgpuBuffer.handle)();
1194
+ import_core12.log.warn(`setting vertex buffer ${location}`, webgpuBuffer == null ? void 0 : webgpuBuffer.handle)();
1196
1195
  webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer == null ? void 0 : webgpuBuffer.handle);
1197
1196
  }
1198
1197
  }