@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.
- package/dist/adapter/helpers/get-bind-group.js +1 -1
- package/dist/adapter/helpers/get-bind-group.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +4 -4
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +3 -5
- package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +1 -0
- package/dist/adapter/resources/webgpu-shader.js.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.d.ts +2 -2
- package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +3 -3
- package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
- package/dist/dist.dev.js +26 -14
- package/dist/index.cjs +18 -19
- package/dist.min.js +15 -15
- package/package.json +3 -3
- package/src/adapter/helpers/get-bind-group.ts +1 -1
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +4 -4
- package/src/adapter/resources/webgpu-render-pipeline.ts +17 -16
- package/src/adapter/resources/webgpu-shader.ts +3 -0
- package/src/adapter/resources/webgpu-vertex-array.ts +4 -4
|
@@ -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;
|
|
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
|
|
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","
|
|
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":"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,KAAKM,eAAe,CAACE,IAAI,CAACC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC;QAC5GV,gBAAgB,CAACW,IAAI,CAAC;UACpBrB,MAAM,EAAED,qBAAqB,CAACe,gBAAgB,CAACd,MAAM,IAAIS,OAAO,CAACT,MAAM,CAAC;UACxEsB,MAAM,EAAER,gBAAgB,CAACS,UAAU;UACnCC,cAAc,EAAEP,eAAe,CAACQ;QAClC,CAAC,CAAC;QAEFb,UAAU,IAAId,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAAC0B,UAAU;MAC7D;IAEF,CAAC,MAAM;MACL,MAAMT,eAAe,GAAGC,mBAAmB,CAACd,YAAY,EAAEK,OAAO,CAACU,IAAI,EAAEZ,cAAc,CAAC;MACvF,IAAI,CAACU,eAAe,EAAE;QACpB;MACF;MACAL,UAAU,GAAGd,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAAC0B,UAAU;MAE1Df,QAAQ,GAAGM,eAAe,CAACN,QAAQ,KAAKM,eAAe,CAACE,IAAI,CAACC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC;MAC5GV,gBAAgB,CAACW,IAAI,CAAC;QACpBrB,MAAM,EAAED,qBAAqB,CAACU,OAAO,CAACT,MAAM,CAAC;QAE7CsB,MAAM,EAAE,CAAC;QACTE,cAAc,EAAEP,eAAe,CAACQ;MAClC,CAAC,CAAC;IACJ;IAGAnB,mBAAmB,CAACe,IAAI,CAAC;MACvBM,WAAW,EAAElB,OAAO,CAACG,UAAU,IAAIA,UAAU;MAC7CD,QAAQ;MACRE,UAAU,EAAEH;IACd,CAAC,CAAC;EACJ;EAGA,KAAK,MAAMM,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACqB,GAAG,CAACZ,SAAS,CAACG,IAAI,CAAC,EAAE;MACvCb,mBAAmB,CAACe,IAAI,CAAC;QACvBM,WAAW,EAAE7B,kBAAkB,CAAC,WAAW,CAAC,CAAC4B,UAAU;QACvDf,QAAQ,EAAEK,SAAS,CAACL,QAAQ,KAAKK,SAAS,CAACG,IAAI,CAACC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC;QAC/FP,UAAU,EAAE,CACV;UACEb,MAAM,EAAED,qBAAqB,CAAC,WAAW,CAAC;UAC1CuB,MAAM,EAAE,CAAC;UACTE,cAAc,EAAER,SAAS,CAACS;QAC5B,CAAC;MAEL,CAAC,CAAC;IACJ;EACF;EAEA,OAAOnB,mBAAmB;AAC5B;AAEA,OAAO,SAASuB,cAAcA,CAC5BzB,YAA0B,EAC1BC,YAA4B,EACJ;EACxB,MAAME,cAAc,GAAG,IAAIC,GAAG,CAAS,CAAC;EACxC,IAAIsB,UAAU,GAAG,CAAC;EAClB,MAAMC,WAAmC,GAAG,CAAC,CAAC;EAG9C,KAAK,MAAMtB,OAAO,IAAIJ,YAAY,EAAE;IAElC,IAAI,YAAY,IAAII,OAAO,EAAE;MAC3B,KAAK,MAAMuB,WAAW,IAAIvB,OAAO,CAACI,UAAU,EAAE;QAC5CN,cAAc,CAAC0B,GAAG,CAACD,WAAW,CAAChB,SAAS,CAAC;MAC3C;IAEF,CAAC,MAAM;MACLT,cAAc,CAAC0B,GAAG,CAACxB,OAAO,CAACU,IAAI,CAAC;IAClC;IACAY,WAAW,CAACtB,OAAO,CAACU,IAAI,CAAC,GAAGW,UAAU,EAAE;EAC1C;EAGA,KAAK,MAAMd,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACqB,GAAG,CAACZ,SAAS,CAACG,IAAI,CAAC,EAAE;MACvCY,WAAW,CAACf,SAAS,CAACG,IAAI,CAAC,GAAGW,UAAU,EAAE;IAC5C;EACF;EAEA,OAAOC,WAAW;AACpB;AAOA,SAASb,mBAAmBA,CAC1Bd,YAA0B,EAC1Be,IAAY,EACZe,cAA2B,EACL;EACtB,MAAMlB,SAAS,GAAGZ,YAAY,CAACS,UAAU,CAACsB,IAAI,CAACnB,SAAS,IAAIA,SAAS,CAACG,IAAI,KAAKA,IAAI,CAAC;EACpF,IAAI,CAACH,SAAS,EAAE;IACdnB,GAAG,CAACuC,IAAI,CAAE,qBAAoBjB,IAAK,EAAC,CAAC,CAAC,CAAC;IACvC,OAAO,IAAI;EACb;EACA,IAAIe,cAAc,CAACN,GAAG,CAACT,IAAI,CAAC,EAAE;IAC5B,MAAM,IAAIjB,KAAK,CAAE,uBAAsBiB,IAAK,EAAC,CAAC;EAChD;EACAe,cAAc,CAACD,GAAG,CAACd,IAAI,CAAC;EACxB,OAAOH,SAAS;AAClB"}
|
|
@@ -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;
|
|
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
|
-
|
|
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;
|
|
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;
|
|
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
|
|
20
|
-
setBuffer(
|
|
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,
|
|
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(
|
|
23
|
-
this.attributes[
|
|
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(
|
|
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","
|
|
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
|
-
|
|
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("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
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
|
|
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
|
-
|
|
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(
|
|
2809
|
-
this.attributes[
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
1178
|
-
setBuffer(
|
|
1179
|
-
this.attributes[
|
|
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(
|
|
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
|
}
|