• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / luma.gl / 23405473644

22 Mar 2026 02:45PM UTC coverage: 72.569% (+0.2%) from 72.39%
23405473644

push

github

web-flow
feat(core, webgpu): Support WebGPU bind groups and WGSL `auto` binding syntax (#2560)

4321 of 6694 branches covered (64.55%)

Branch coverage included in aggregate %.

470 of 560 new or added lines in 30 files covered. (83.93%)

2 existing lines in 2 files now uncovered.

9523 of 12383 relevant lines covered (76.9%)

271.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/modules/core/src/adapter-utils/bind-groups.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import type {
6
  BindingDeclaration,
7
  Bindings,
8
  BindingsByGroup,
9
  ComputeShaderLayout,
10
  ShaderLayout
11
} from '../adapter/types/shader-layout';
12
import {log} from '../utils/log';
13

14
type AnyShaderLayout = Pick<ShaderLayout | ComputeShaderLayout, 'bindings'>;
15

16
export function getShaderLayoutBinding(
17
  shaderLayout: AnyShaderLayout,
18
  bindingName: string,
19
  options?: {ignoreWarnings?: boolean}
20
): BindingDeclaration | null {
21
  const bindingLayout = shaderLayout.bindings.find(
138✔
22
    binding =>
23
      binding.name === bindingName ||
224✔
24
      `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase()
25
  );
26

27
  if (!bindingLayout && !options?.ignoreWarnings) {
138!
NEW
28
    log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
×
29
  }
30

31
  return bindingLayout || null;
138!
32
}
33

34
export function normalizeBindingsByGroup(
35
  shaderLayout: AnyShaderLayout,
36
  bindingsOrBindGroups?: Bindings | BindingsByGroup
37
): BindingsByGroup {
38
  if (!bindingsOrBindGroups) {
104✔
39
    return {};
11✔
40
  }
41

42
  if (areBindingsGrouped(bindingsOrBindGroups)) {
93✔
43
    const bindGroups = bindingsOrBindGroups as BindingsByGroup;
19✔
44
    return Object.fromEntries(
19✔
45
      Object.entries(bindGroups).map(([group, bindings]) => [Number(group), {...bindings}])
25✔
46
    ) as BindingsByGroup;
47
  }
48

49
  const bindGroups: BindingsByGroup = {};
74✔
50
  for (const [bindingName, binding] of Object.entries(bindingsOrBindGroups as Bindings)) {
74✔
51
    const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
132✔
52
    const group = bindingLayout?.group ?? 0;
132!
53
    bindGroups[group] ||= {};
132✔
54
    bindGroups[group][bindingName] = binding;
132✔
55
  }
56

57
  return bindGroups;
74✔
58
}
59

60
export function flattenBindingsByGroup(bindGroups: BindingsByGroup): Bindings {
61
  const bindings: Bindings = {};
31✔
62
  for (const groupBindings of Object.values(bindGroups)) {
31✔
63
    Object.assign(bindings, groupBindings);
31✔
64
  }
65
  return bindings;
31✔
66
}
67

68
function areBindingsGrouped(bindingsOrBindGroups: Bindings | BindingsByGroup): boolean {
69
  const keys = Object.keys(bindingsOrBindGroups);
93✔
70
  return keys.length > 0 && keys.every(key => /^\d+$/.test(key));
99✔
71
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc