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

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":"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"}
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
@@ -1038,7 +1038,19 @@ var __exports__ = (() => {
1038
1038
  readPixelsToArrayWebGL(source, options) {
1039
1039
  throw new Error("not implemented");
1040
1040
  }
1041
- readPixelsToBufferWebGL2(source, options) {
1041
+ readPixelsToBufferWebGL(source, options) {
1042
+ throw new Error("not implemented");
1043
+ }
1044
+ setParametersWebGL(parameters) {
1045
+ throw new Error("not implemented");
1046
+ }
1047
+ getParametersWebGL(parameters) {
1048
+ throw new Error("not implemented");
1049
+ }
1050
+ withParametersWebGL(parameters, func) {
1051
+ throw new Error("not implemented");
1052
+ }
1053
+ clearWebGL(options) {
1042
1054
  throw new Error("not implemented");
1043
1055
  }
1044
1056
  _getBufferProps(props) {
@@ -1425,7 +1437,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
1425
1437
  return numberedLines;
1426
1438
  }
1427
1439
  function getNumberedLine(line, lineNum, options) {
1428
- return `${padLeft(String(lineNum), 4)}: ${line}${options?.html ? "<br/>" : "\n"}`;
1440
+ const escapedLine = options?.html ? escapeHTML(line) : line;
1441
+ return `${padLeft(String(lineNum), 4)}: ${escapedLine}${options?.html ? "<br/>" : "\n"}`;
1429
1442
  }
1430
1443
  function padLeft(string, paddedLength) {
1431
1444
  let result = "";
@@ -1434,6 +1447,9 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
1434
1447
  }
1435
1448
  return result + string;
1436
1449
  }
1450
+ function escapeHTML(unsafe) {
1451
+ return unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
1452
+ }
1437
1453
 
1438
1454
  // ../core/src/lib/compiler-log/get-shader-info.ts
1439
1455
  function getShaderInfo(source, defaultName) {
@@ -2236,6 +2252,7 @@ ${htmlLog}
2236
2252
  async _checkCompilationError(errorScope) {
2237
2253
  const error = await errorScope;
2238
2254
  if (error) {
2255
+ this.debugShader();
2239
2256
  const shaderLog = await this.getCompilationInfo();
2240
2257
  log.error(`Shader compilation error: ${error.message}`, shaderLog)();
2241
2258
  throw new Error(`Shader compilation error: ${error.message}`);
@@ -2416,7 +2433,7 @@ ${htmlLog}
2416
2433
  });
2417
2434
  }
2418
2435
  function getShaderLayoutBinding(shaderLayout, bindingName) {
2419
- const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName);
2436
+ const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name}uniforms` === bindingName.toLocaleLowerCase());
2420
2437
  if (!bindingLayout) {
2421
2438
  log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
2422
2439
  }
@@ -2475,7 +2492,7 @@ ${htmlLog}
2475
2492
  for (const attributeMapping of mapping.attributes) {
2476
2493
  const attributeName = attributeMapping.attribute;
2477
2494
  const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
2478
- stepMode = attributeLayout.stepMode || "vertex";
2495
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
2479
2496
  vertexAttributes.push({
2480
2497
  format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
2481
2498
  offset: attributeMapping.byteOffset,
@@ -2489,7 +2506,7 @@ ${htmlLog}
2489
2506
  continue;
2490
2507
  }
2491
2508
  byteStride = decodeVertexFormat(mapping.format).byteLength;
2492
- stepMode = attributeLayout.stepMode || "vertex";
2509
+ stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
2493
2510
  vertexAttributes.push({
2494
2511
  format: getWebGPUVertexFormat(mapping.format),
2495
2512
  offset: 0,
@@ -2498,7 +2515,7 @@ ${htmlLog}
2498
2515
  }
2499
2516
  vertexBufferLayouts.push({
2500
2517
  arrayStride: mapping.byteStride || byteStride,
2501
- stepMode: stepMode || "vertex",
2518
+ stepMode,
2502
2519
  attributes: vertexAttributes
2503
2520
  });
2504
2521
  }
@@ -2506,7 +2523,7 @@ ${htmlLog}
2506
2523
  if (!usedAttributes.has(attribute.name)) {
2507
2524
  vertexBufferLayouts.push({
2508
2525
  arrayStride: decodeVertexFormat("float32x3").byteLength,
2509
- stepMode: attribute.stepMode || "vertex",
2526
+ stepMode: attribute.stepMode || (attribute.name.startsWith("instance") ? "instance" : "vertex"),
2510
2527
  attributes: [{
2511
2528
  format: getWebGPUVertexFormat("float32x3"),
2512
2529
  offset: 0,
@@ -2553,11 +2570,7 @@ ${htmlLog}
2553
2570
  destroy() {
2554
2571
  }
2555
2572
  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
- }
2573
+ Object.assign(this.props.bindings, bindings);
2561
2574
  }
2562
2575
  setUniforms(uniforms) {
2563
2576
  if (!isObjectEmpty(uniforms)) {
@@ -2580,6 +2593,8 @@ ${htmlLog}
2580
2593
  options.vertexArray.unbindAfterRender(options.renderPass);
2581
2594
  }
2582
2595
  _getBindGroup() {
2596
+ this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
2597
+ this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.props.shaderLayout, this.props.bindings);
2583
2598
  return this._bindGroup;
2584
2599
  }
2585
2600
  _getRenderPipelineDescriptor() {
@@ -2805,8 +2820,8 @@ ${htmlLog}
2805
2820
  setIndexBuffer(buffer) {
2806
2821
  this.indexBuffer = buffer;
2807
2822
  }
2808
- setBuffer(location, buffer) {
2809
- this.attributes[location] = buffer;
2823
+ setBuffer(bufferSlot, buffer) {
2824
+ this.attributes[bufferSlot] = buffer;
2810
2825
  }
2811
2826
  setConstant(location, value) {
2812
2827
  log.warn(`${this.id} constant attributes not supported on WebGPU`);
@@ -2821,7 +2836,7 @@ ${htmlLog}
2821
2836
  for (let location = 0; location < this.maxVertexAttributes; location++) {
2822
2837
  const webgpuBuffer = this.attributes[location];
2823
2838
  if (webgpuBuffer?.handle) {
2824
- log.warn("setting vertex buffer", location, webgpuBuffer?.handle)();
2839
+ log.warn(`setting vertex buffer ${location}`, webgpuBuffer?.handle)();
2825
2840
  webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
2826
2841
  }
2827
2842
  }
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
  }