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

visgl / luma.gl / 25677315527

11 May 2026 02:45PM UTC coverage: 74.394% (+0.2%) from 74.161%
25677315527

push

github

web-flow
feat(arrow) ArrowGPUTable, ArrowModel (#2607)

Co-authored-by: Ib Green <ib.green.home@gmail.com>

5402 of 8198 branches covered (65.89%)

Branch coverage included in aggregate %.

193 of 228 new or added lines in 13 files covered. (84.65%)

1 existing line in 1 file now uncovered.

12047 of 15257 relevant lines covered (78.96%)

767.58 hits per line

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

77.78
/modules/webgpu/src/adapter/resources/webgpu-vertex-array.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import type {Device, Buffer, VertexArrayProps, RenderPass} from '@luma.gl/core';
6
import {VertexArray, log} from '@luma.gl/core';
7
import {getBrowser} from '@probe.gl/env';
8

9
import {WebGPUDevice} from '../webgpu-device';
10
import {WebGPUBuffer} from '../resources/webgpu-buffer';
11
import {
12
  getBufferSlots,
13
  resolveVertexBufferLayouts,
14
  type ResolvedVertexBufferSlot
15
} from '../helpers/get-vertex-buffer-layout';
16

17
import {WebGPURenderPass} from './webgpu-render-pass';
18

19
/** VertexArrayObject wrapper */
20
export class WebGPUVertexArray extends VertexArray {
21
  override get [Symbol.toStringTag](): string {
22
    return 'VertexArray';
12✔
23
  }
24

25
  readonly device: WebGPUDevice;
26
  /** Vertex Array is just a helper class under WebGPU */
27
  readonly handle = null;
12✔
28
  /** Physical WebGPU vertex-buffer slots derived from the logical buffer layout. */
29
  private readonly resolvedBufferSlots: ResolvedVertexBufferSlot[];
30
  /** Logical vertex-array slot lookup keyed by buffer name. */
31
  private readonly logicalBufferSlots: Record<string, number>;
32

33
  /** Creates a WebGPU vertex array helper for draw-time buffer rebinding. */
34
  constructor(device: WebGPUDevice, props: VertexArrayProps) {
35
    super(device, props);
12✔
36
    this.device = device;
12✔
37
    const {resolvedSlots} = resolveVertexBufferLayouts(props.shaderLayout, props.bufferLayout);
12✔
38
    this.resolvedBufferSlots = resolvedSlots;
12✔
39
    this.logicalBufferSlots = getBufferSlots(props.shaderLayout, props.bufferLayout);
12✔
40
  }
41

42
  override destroy(): void {}
43

44
  /**
45
   * Set an elements buffer, for indexed rendering.
46
   * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
47
   */
48
  setIndexBuffer(buffer: Buffer | null): void {
49
    // assert(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
50
    this.indexBuffer = buffer;
3✔
51
  }
52

53
  /** Sets the buffer stored in one logical vertex-array slot. */
54
  setBuffer(bufferSlot: number, buffer: Buffer): void {
55
    // Sanity check target
56
    // if (buffer.glUsage === GL.ELEMENT_ARRAY_BUFFER) {
57
    //   throw new Error('Use setIndexBuffer');
58
    // }
59

60
    this.attributes[bufferSlot] = buffer;
44✔
61
  }
62

63
  override getBufferSlot(bufferName: string): number | null {
64
    return this.logicalBufferSlots[bufferName] ?? null;
42!
65
  }
66

67
  override getDrawValidationError(): string | null {
68
    const missingSlots: number[] = [];
8✔
69
    for (const resolvedSlot of this.resolvedBufferSlots) {
8✔
70
      const logicalBufferSlot =
71
        this.logicalBufferSlots[resolvedSlot.bufferName] ?? resolvedSlot.shaderSlot;
30!
72
      const webgpuBuffer = this.attributes[logicalBufferSlot] as WebGPUBuffer;
30✔
73
      if (!webgpuBuffer?.handle) {
30!
NEW
74
        missingSlots.push(resolvedSlot.shaderSlot);
×
75
      }
76
    }
77

78
    return missingSlots.length
8!
79
      ? `WebGPU vertex buffer slot${missingSlots.length === 1 ? '' : 's'} ${missingSlots.join(
×
80
          ', '
81
        )} not set`
82
      : null;
83
  }
84

85
  /**
86
   * Binds index and vertex buffers for the current draw call.
87
   * Repeats logical buffers across multiple WebGPU slots when the resolved layout was expanded.
88
   */
89
  override bindBeforeRender(
90
    renderPass: RenderPass,
91
    firstIndex?: number,
92
    indexCount?: number
93
  ): void {
94
    const webgpuRenderPass = renderPass as WebGPURenderPass;
10✔
95
    const webgpuIndexBuffer = this.indexBuffer as WebGPUBuffer;
10✔
96
    if (webgpuIndexBuffer?.handle) {
10✔
97
      // Note we can't unset an index buffer
98
      log.info(
6✔
99
        3,
100
        'setting index buffer',
101
        webgpuIndexBuffer?.handle,
102
        webgpuIndexBuffer?.indexType
103
      )();
104
      webgpuRenderPass.handle.setIndexBuffer(
6✔
105
        webgpuIndexBuffer?.handle,
106
        // @ts-expect-error TODO - we must enforce type
107
        webgpuIndexBuffer?.indexType
108
      );
109
    }
110
    for (const resolvedSlot of this.resolvedBufferSlots) {
10✔
111
      const logicalBufferSlot =
112
        this.logicalBufferSlots[resolvedSlot.bufferName] ?? resolvedSlot.shaderSlot;
35!
113
      const webgpuBuffer = this.attributes[logicalBufferSlot] as WebGPUBuffer;
35✔
114
      if (webgpuBuffer?.handle) {
35!
115
        log.info(
35✔
116
          3,
117
          `setting vertex buffer ${resolvedSlot.shaderSlot}`,
118
          webgpuBuffer?.handle,
119
          resolvedSlot.bindingOffset
120
        )();
121
        webgpuRenderPass.handle.setVertexBuffer(
35✔
122
          resolvedSlot.shaderSlot,
123
          webgpuBuffer?.handle,
124
          resolvedSlot.bindingOffset
125
        );
126
      }
127
    }
128
    // TODO - emit warnings/errors/throw if constants have been set on this vertex array
129
  }
130

131
  override unbindAfterRender(renderPass: RenderPass): void {
132
    // On WebGPU we don't need to unbind.
133
    // In fact we can't easily do it. setIndexBuffer/setVertexBuffer don't accept null.
134
    // Unbinding presumably happens automatically when the render pass is ended.
135
  }
136

137
  // DEPRECATED METHODS
138

139
  /**
140
   * @deprecated is this even an issue for WebGPU?
141
   * Attribute 0 can not be disable on most desktop OpenGL based browsers
142
   */
143
  static isConstantAttributeZeroSupported(device: Device): boolean {
144
    return getBrowser() === 'Chrome';
×
145
  }
146
}
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