• 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

85.0
/modules/engine/src/utils/shader-module-utils.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import type {ComputeShaderLayout, ShaderLayout} from '@luma.gl/core';
6
import type {ShaderModule} from '@luma.gl/shadertools';
7

8
type AnyShaderLayout = ShaderLayout | ComputeShaderLayout;
9

10
export function mergeShaderModuleBindingsIntoLayout<TShaderLayout extends AnyShaderLayout>(
11
  shaderLayout: TShaderLayout | null | undefined,
12
  modules: ShaderModule[]
13
): TShaderLayout | null | undefined {
14
  if (!shaderLayout || !modules.some(module => module.bindingLayout?.length)) {
73✔
15
    return shaderLayout;
71✔
16
  }
17

18
  const mergedLayout = {
2✔
19
    ...shaderLayout,
20
    bindings: shaderLayout.bindings.map(binding => ({...binding}))
5✔
21
  } as TShaderLayout;
22

23
  if ('attributes' in (shaderLayout || {})) {
2!
24
    (mergedLayout as ShaderLayout).attributes = (shaderLayout as ShaderLayout)?.attributes || [];
2!
25
  }
26

27
  for (const module of modules) {
2✔
28
    for (const bindingLayout of module.bindingLayout || []) {
3!
29
      for (const relatedBindingName of getRelatedBindingNames(bindingLayout.name)) {
17✔
30
        const binding = mergedLayout.bindings.find(
51✔
31
          candidate => candidate.name === relatedBindingName
104✔
32
        );
33
        if (binding?.group === 0) {
51✔
34
          binding.group = bindingLayout.group;
4✔
35
        }
36
      }
37
    }
38
  }
39

40
  return mergedLayout;
2✔
41
}
42

43
export function shaderModuleHasUniforms(module: ShaderModule): boolean {
44
  return Boolean(module.uniformTypes && !isObjectEmpty(module.uniformTypes));
69✔
45
}
46

47
/** Returns binding-name aliases that should share the module-declared bind group. */
48
function getRelatedBindingNames(bindingName: string): string[] {
49
  const bindingNames = new Set<string>([bindingName, `${bindingName}Uniforms`]);
17✔
50

51
  if (!bindingName.endsWith('Uniforms')) {
17!
52
    bindingNames.add(`${bindingName}Sampler`);
17✔
53
  }
54

55
  return [...bindingNames];
17✔
56
}
57

58
function isObjectEmpty(obj: object): boolean {
59
  // @ts-ignore key is intentionally unused
60
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
  for (const key in obj) {
54✔
62
    return false;
54✔
63
  }
NEW
64
  return true;
×
65
}
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