@aethervtt/shard-gpu-webgl2 0.0.0-stage → 0.2.0

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -2
  3. package/dist/binding.d.ts +32 -0
  4. package/dist/binding.js +81 -0
  5. package/dist/cache.d.ts +73 -0
  6. package/dist/cache.js +184 -0
  7. package/dist/commands.d.ts +101 -0
  8. package/dist/commands.js +391 -0
  9. package/dist/constants.d.ts +41 -0
  10. package/dist/constants.js +38 -0
  11. package/dist/copies.d.ts +61 -0
  12. package/dist/copies.js +629 -0
  13. package/dist/device.d.ts +168 -0
  14. package/dist/device.js +401 -0
  15. package/dist/errors.d.ts +8 -0
  16. package/dist/errors.js +18 -0
  17. package/dist/fake-gl.d.ts +338 -0
  18. package/dist/fake-gl.js +980 -0
  19. package/dist/fbo.d.ts +30 -0
  20. package/dist/fbo.js +142 -0
  21. package/dist/formats.d.ts +25 -0
  22. package/dist/formats.js +106 -0
  23. package/dist/gl.d.ts +216 -0
  24. package/dist/gl.js +232 -0
  25. package/dist/gpu.d.ts +58 -0
  26. package/dist/gpu.js +215 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.js +42 -0
  29. package/dist/naga.d.ts +37 -0
  30. package/dist/naga.js +99 -0
  31. package/dist/pipeline.d.ts +113 -0
  32. package/dist/pipeline.js +294 -0
  33. package/dist/present.d.ts +18 -0
  34. package/dist/present.js +108 -0
  35. package/dist/queries.d.ts +41 -0
  36. package/dist/queries.js +110 -0
  37. package/dist/queue.d.ts +13 -0
  38. package/dist/queue.js +50 -0
  39. package/dist/readback.d.ts +17 -0
  40. package/dist/readback.js +104 -0
  41. package/dist/replay.d.ts +78 -0
  42. package/dist/replay.js +678 -0
  43. package/dist/resources.d.ts +96 -0
  44. package/dist/resources.js +355 -0
  45. package/dist/state.d.ts +43 -0
  46. package/dist/state.js +169 -0
  47. package/package.json +36 -4
  48. package/wasm/shard_naga.wasm +0 -0
@@ -0,0 +1,391 @@
1
+ import { unsupported } from "./errors.js";
2
+ const OP = {
3
+ BEGIN_PASS: 1,
4
+ END_PASS: 2,
5
+ SET_PIPELINE: 3,
6
+ SET_BIND_GROUP: 4,
7
+ SET_VERTEX_BUFFER: 5,
8
+ SET_INDEX_BUFFER: 6,
9
+ DRAW: 7,
10
+ DRAW_INDEXED: 8,
11
+ VIEWPORT: 9,
12
+ SCISSOR: 10,
13
+ STENCIL_REFERENCE: 11,
14
+ BLEND_CONSTANT: 12,
15
+ COPY_BUFFER: 13,
16
+ COPY_BUFFER_TO_TEXTURE: 14,
17
+ COPY_TEXTURE_TO_BUFFER: 15,
18
+ COPY_TEXTURE: 16,
19
+ CLEAR_BUFFER: 17,
20
+ BEGIN_QUERY: 18,
21
+ END_QUERY: 19,
22
+ RESOLVE_QUERIES: 20
23
+ };
24
+ class CommandStream {
25
+ nums = new Float64Array(1024);
26
+ n = 0;
27
+ refs = [];
28
+ r = 0;
29
+ num(value) {
30
+ if (this.n === this.nums.length) {
31
+ const grown = new Float64Array(this.nums.length * 2);
32
+ grown.set(this.nums);
33
+ this.nums = grown;
34
+ }
35
+ this.nums[this.n++] = value;
36
+ }
37
+ ref(value) {
38
+ this.refs[this.r++] = value;
39
+ }
40
+ /** Empties it, dropping its references so recorded objects can be collected. */
41
+ reset() {
42
+ for (let i = 0; i < this.r; i++) this.refs[i] = void 0;
43
+ this.n = 0;
44
+ this.r = 0;
45
+ }
46
+ }
47
+ class Webgl2CommandBuffer {
48
+ label = "";
49
+ /** What to replay; undefined once submitted. */
50
+ stream;
51
+ /** The encoder that made it, pooled again after the submit. */
52
+ encoder;
53
+ constructor(encoder) {
54
+ this.encoder = encoder;
55
+ }
56
+ }
57
+ function originOf(o, i) {
58
+ if (!o) return 0;
59
+ if (Array.isArray(o)) return o[i] ?? 0;
60
+ const d = o;
61
+ return (i === 0 ? d.x : i === 1 ? d.y : d.z) ?? 0;
62
+ }
63
+ function extentOf(e, i) {
64
+ if (Array.isArray(e)) return e[i] ?? 1;
65
+ const d = e;
66
+ return (i === 0 ? d.width : i === 1 ? d.height : d.depthOrArrayLayers) ?? 1;
67
+ }
68
+ function colorOf(c, i) {
69
+ if (!c) return 0;
70
+ if (Array.isArray(c)) return c[i] ?? 0;
71
+ const d = c;
72
+ return i === 0 ? d.r : i === 1 ? d.g : i === 2 ? d.b : d.a;
73
+ }
74
+ class Webgl2CommandEncoder {
75
+ label = "";
76
+ /** @internal The pass being recorded times itself (`timestampWrites`): its end ends the query. */
77
+ timedPass = false;
78
+ stream;
79
+ pass;
80
+ buffer;
81
+ constructor() {
82
+ this.pass = new Webgl2RenderPassEncoder(this);
83
+ this.buffer = new Webgl2CommandBuffer(this);
84
+ }
85
+ /** @internal Starts recording into `stream` (a new or pooled encoder). */
86
+ begin(stream, label) {
87
+ this.stream = stream;
88
+ this.label = label;
89
+ return this;
90
+ }
91
+ /** @internal The stream commands record into. */
92
+ get recording() {
93
+ const stream = this.stream;
94
+ if (!stream) throw new Error(`Command encoder "${this.label}" was already finished`);
95
+ return stream;
96
+ }
97
+ beginRenderPass(d) {
98
+ const s = this.recording;
99
+ if (d.occlusionQuerySet) throw unsupported(`run occlusion queries ("${d.label ?? this.label}")`);
100
+ const writes = d.timestampWrites;
101
+ const index = writes?.beginningOfPassWriteIndex ?? writes?.endOfPassWriteIndex;
102
+ this.timedPass = writes !== void 0 && index !== void 0;
103
+ if (this.timedPass) {
104
+ s.num(OP.BEGIN_QUERY);
105
+ s.num(index >> 1);
106
+ s.ref(writes.querySet);
107
+ }
108
+ s.num(OP.BEGIN_PASS);
109
+ const colors = d.colorAttachments;
110
+ s.num(colors.length);
111
+ for (let i = 0; i < colors.length; i++) {
112
+ const c = colors[i];
113
+ if (!c) {
114
+ s.num(0);
115
+ continue;
116
+ }
117
+ s.num(1);
118
+ s.ref(c.view);
119
+ s.ref(c.resolveTarget ?? null);
120
+ s.num(c.loadOp === "clear" ? 1 : 0);
121
+ s.num(c.storeOp === "discard" ? 1 : 0);
122
+ s.num(c.depthSlice ?? -1);
123
+ s.num(colorOf(c.clearValue, 0));
124
+ s.num(colorOf(c.clearValue, 1));
125
+ s.num(colorOf(c.clearValue, 2));
126
+ s.num(colorOf(c.clearValue, 3));
127
+ }
128
+ const ds = d.depthStencilAttachment;
129
+ if (!ds) {
130
+ s.num(0);
131
+ } else {
132
+ s.num(1);
133
+ s.ref(ds.view);
134
+ s.num(ds.depthLoadOp === "clear" ? 1 : 0);
135
+ s.num(ds.depthStoreOp === "discard" ? 1 : 0);
136
+ s.num(ds.depthClearValue ?? 0);
137
+ s.num(ds.depthReadOnly ? 1 : 0);
138
+ s.num(ds.stencilLoadOp === "clear" ? 1 : 0);
139
+ s.num(ds.stencilStoreOp === "discard" ? 1 : 0);
140
+ s.num(ds.stencilClearValue ?? 0);
141
+ s.num(ds.stencilReadOnly ? 1 : 0);
142
+ }
143
+ return this.pass;
144
+ }
145
+ beginComputePass(d) {
146
+ throw unsupported(
147
+ `run the compute pass "${d?.label ?? this.label}"`,
148
+ 'Compute is the full tier: a feature that needs it registers baseline "unsupported" (0064).'
149
+ );
150
+ }
151
+ copyBufferToBuffer(source, a, b, c, d) {
152
+ const s = this.recording;
153
+ s.num(OP.COPY_BUFFER);
154
+ if (typeof a === "number") {
155
+ const destination = b;
156
+ s.num(a);
157
+ s.num(c ?? 0);
158
+ s.num(d ?? source.size - a);
159
+ s.ref(source);
160
+ s.ref(destination);
161
+ } else {
162
+ s.num(0);
163
+ s.num(0);
164
+ s.num(b ?? source.size);
165
+ s.ref(source);
166
+ s.ref(a);
167
+ }
168
+ }
169
+ copyBufferToTexture(source, destination, size) {
170
+ const s = this.recording;
171
+ const h = extentOf(size, 1);
172
+ s.num(OP.COPY_BUFFER_TO_TEXTURE);
173
+ s.num(source.offset ?? 0);
174
+ s.num(source.bytesPerRow ?? 0);
175
+ s.num(source.rowsPerImage ?? h);
176
+ s.num(destination.mipLevel ?? 0);
177
+ s.num(originOf(destination.origin, 0));
178
+ s.num(originOf(destination.origin, 1));
179
+ s.num(originOf(destination.origin, 2));
180
+ s.num(extentOf(size, 0));
181
+ s.num(h);
182
+ s.num(extentOf(size, 2));
183
+ s.ref(source.buffer);
184
+ s.ref(destination.texture);
185
+ }
186
+ copyTextureToBuffer(source, destination, size) {
187
+ const s = this.recording;
188
+ const h = extentOf(size, 1);
189
+ s.num(OP.COPY_TEXTURE_TO_BUFFER);
190
+ s.num(source.mipLevel ?? 0);
191
+ s.num(originOf(source.origin, 0));
192
+ s.num(originOf(source.origin, 1));
193
+ s.num(originOf(source.origin, 2));
194
+ s.num(destination.offset ?? 0);
195
+ s.num(destination.bytesPerRow ?? 0);
196
+ s.num(destination.rowsPerImage ?? h);
197
+ s.num(extentOf(size, 0));
198
+ s.num(h);
199
+ s.num(extentOf(size, 2));
200
+ s.ref(source.texture);
201
+ s.ref(destination.buffer);
202
+ }
203
+ copyTextureToTexture(source, destination, size) {
204
+ const s = this.recording;
205
+ s.num(OP.COPY_TEXTURE);
206
+ s.num(source.mipLevel ?? 0);
207
+ s.num(originOf(source.origin, 0));
208
+ s.num(originOf(source.origin, 1));
209
+ s.num(originOf(source.origin, 2));
210
+ s.num(destination.mipLevel ?? 0);
211
+ s.num(originOf(destination.origin, 0));
212
+ s.num(originOf(destination.origin, 1));
213
+ s.num(originOf(destination.origin, 2));
214
+ s.num(extentOf(size, 0));
215
+ s.num(extentOf(size, 1));
216
+ s.num(extentOf(size, 2));
217
+ s.ref(source.texture);
218
+ s.ref(destination.texture);
219
+ }
220
+ clearBuffer(buffer, offset = 0, size) {
221
+ const s = this.recording;
222
+ s.num(OP.CLEAR_BUFFER);
223
+ s.num(offset);
224
+ s.num(size ?? buffer.size - offset);
225
+ s.ref(buffer);
226
+ }
227
+ /** Pairs of the set to the buffer: written when the buffer is mapped (queries.ts). */
228
+ resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {
229
+ const s = this.recording;
230
+ s.num(OP.RESOLVE_QUERIES);
231
+ s.num(firstQuery);
232
+ s.num(queryCount);
233
+ s.num(destinationOffset);
234
+ s.ref(querySet);
235
+ s.ref(destination);
236
+ }
237
+ writeTimestamp() {
238
+ throw unsupported("write timestamps", "WebGL2 times passes (timestampWrites) only.");
239
+ }
240
+ pushDebugGroup() {
241
+ }
242
+ popDebugGroup() {
243
+ }
244
+ insertDebugMarker() {
245
+ }
246
+ finish(d) {
247
+ const buffer = this.buffer;
248
+ buffer.stream = this.recording;
249
+ buffer.label = d?.label ?? this.label;
250
+ this.stream = void 0;
251
+ return buffer;
252
+ }
253
+ }
254
+ class Webgl2RenderPassEncoder {
255
+ label = "";
256
+ encoder;
257
+ constructor(encoder) {
258
+ this.encoder = encoder;
259
+ }
260
+ setPipeline(pipeline) {
261
+ const s = this.encoder.recording;
262
+ s.num(OP.SET_PIPELINE);
263
+ s.ref(pipeline);
264
+ }
265
+ setBindGroup(index, group, offsets, start = 0, length) {
266
+ const s = this.encoder.recording;
267
+ s.num(OP.SET_BIND_GROUP);
268
+ s.num(index);
269
+ if (!offsets) {
270
+ s.num(0);
271
+ } else if (offsets instanceof Uint32Array) {
272
+ const n = length ?? offsets.length - start;
273
+ s.num(n);
274
+ for (let i = 0; i < n; i++) s.num(offsets[start + i]);
275
+ } else {
276
+ const list = Array.isArray(offsets) ? offsets : [...offsets];
277
+ s.num(list.length);
278
+ for (let i = 0; i < list.length; i++) s.num(list[i]);
279
+ }
280
+ s.ref(group);
281
+ }
282
+ setVertexBuffer(slot, buffer, offset = 0, size) {
283
+ const s = this.encoder.recording;
284
+ s.num(OP.SET_VERTEX_BUFFER);
285
+ s.num(slot);
286
+ s.num(offset);
287
+ s.num(size ?? (buffer ? buffer.size - offset : 0));
288
+ s.ref(buffer);
289
+ }
290
+ setIndexBuffer(buffer, format, offset = 0, size) {
291
+ const s = this.encoder.recording;
292
+ s.num(OP.SET_INDEX_BUFFER);
293
+ s.num(format === "uint32" ? 4 : 2);
294
+ s.num(offset);
295
+ s.num(size ?? buffer.size - offset);
296
+ s.ref(buffer);
297
+ }
298
+ draw(vertexCount, instanceCount = 1, firstVertex = 0, firstInstance = 0) {
299
+ const s = this.encoder.recording;
300
+ s.num(OP.DRAW);
301
+ s.num(vertexCount);
302
+ s.num(instanceCount);
303
+ s.num(firstVertex);
304
+ s.num(firstInstance);
305
+ }
306
+ drawIndexed(indexCount, instanceCount = 1, firstIndex = 0, baseVertex = 0, firstInstance = 0) {
307
+ const s = this.encoder.recording;
308
+ s.num(OP.DRAW_INDEXED);
309
+ s.num(indexCount);
310
+ s.num(instanceCount);
311
+ s.num(firstIndex);
312
+ s.num(baseVertex);
313
+ s.num(firstInstance);
314
+ }
315
+ drawIndirect() {
316
+ throw unsupported("draw indirectly", "The baseline tier culls on the CPU and draws directly.");
317
+ }
318
+ drawIndexedIndirect() {
319
+ throw unsupported("draw indirectly", "The baseline tier culls on the CPU and draws directly.");
320
+ }
321
+ setViewport(x, y, width, height, minDepth, maxDepth) {
322
+ const s = this.encoder.recording;
323
+ s.num(OP.VIEWPORT);
324
+ s.num(x);
325
+ s.num(y);
326
+ s.num(width);
327
+ s.num(height);
328
+ s.num(minDepth);
329
+ s.num(maxDepth);
330
+ }
331
+ setScissorRect(x, y, width, height) {
332
+ const s = this.encoder.recording;
333
+ s.num(OP.SCISSOR);
334
+ s.num(x);
335
+ s.num(y);
336
+ s.num(width);
337
+ s.num(height);
338
+ }
339
+ setStencilReference(reference) {
340
+ const s = this.encoder.recording;
341
+ s.num(OP.STENCIL_REFERENCE);
342
+ s.num(reference);
343
+ }
344
+ setBlendConstant(color) {
345
+ const s = this.encoder.recording;
346
+ s.num(OP.BLEND_CONSTANT);
347
+ s.num(colorOf(color, 0));
348
+ s.num(colorOf(color, 1));
349
+ s.num(colorOf(color, 2));
350
+ s.num(colorOf(color, 3));
351
+ }
352
+ executeBundles() {
353
+ throw unsupported("execute render bundles");
354
+ }
355
+ beginOcclusionQuery() {
356
+ throw unsupported("run occlusion queries");
357
+ }
358
+ endOcclusionQuery() {
359
+ throw unsupported("run occlusion queries");
360
+ }
361
+ pushDebugGroup() {
362
+ }
363
+ popDebugGroup() {
364
+ }
365
+ insertDebugMarker() {
366
+ }
367
+ end() {
368
+ const s = this.encoder.recording;
369
+ s.num(OP.END_PASS);
370
+ if (this.encoder.timedPass) {
371
+ s.num(OP.END_QUERY);
372
+ this.encoder.timedPass = false;
373
+ }
374
+ }
375
+ }
376
+ function layerOf(view, depthSlice) {
377
+ if (view.texture.dimension === "3d") return depthSlice < 0 ? 0 : depthSlice;
378
+ return view.baseArrayLayer;
379
+ }
380
+ function mipSize(size, mip) {
381
+ return Math.max(1, size >> mip);
382
+ }
383
+ export {
384
+ CommandStream,
385
+ OP,
386
+ Webgl2CommandBuffer,
387
+ Webgl2CommandEncoder,
388
+ Webgl2RenderPassEncoder,
389
+ layerOf,
390
+ mipSize
391
+ };
@@ -0,0 +1,41 @@
1
+ export declare const BufferUsage: {
2
+ readonly MAP_READ: 1;
3
+ readonly MAP_WRITE: 2;
4
+ readonly COPY_SRC: 4;
5
+ readonly COPY_DST: 8;
6
+ readonly INDEX: 16;
7
+ readonly VERTEX: 32;
8
+ readonly UNIFORM: 64;
9
+ readonly STORAGE: 128;
10
+ readonly INDIRECT: 256;
11
+ readonly QUERY_RESOLVE: 512;
12
+ };
13
+ export declare const TextureUsage: {
14
+ readonly COPY_SRC: 1;
15
+ readonly COPY_DST: 2;
16
+ readonly TEXTURE_BINDING: 4;
17
+ readonly STORAGE_BINDING: 8;
18
+ readonly RENDER_ATTACHMENT: 16;
19
+ };
20
+ export declare const ShaderStage: {
21
+ readonly VERTEX: 1;
22
+ readonly FRAGMENT: 2;
23
+ readonly COMPUTE: 4;
24
+ };
25
+ export declare const MapMode: {
26
+ readonly READ: 1;
27
+ readonly WRITE: 2;
28
+ };
29
+ export declare const ColorWrite: {
30
+ readonly RED: 1;
31
+ readonly GREEN: 2;
32
+ readonly BLUE: 4;
33
+ readonly ALPHA: 8;
34
+ readonly ALL: 15;
35
+ };
36
+ /**
37
+ * Defines `GPUBufferUsage`, `GPUTextureUsage`, `GPUShaderStage`, `GPUMapMode` and `GPUColorWrite`
38
+ * on globalThis where the browser doesn't. Where it does (WebGPU and WebGL2 in one page), they
39
+ * stay: the values are the spec's either way.
40
+ */
41
+ export declare function installGpuConstants(): void;
@@ -0,0 +1,38 @@
1
+ const BufferUsage = {
2
+ MAP_READ: 1,
3
+ MAP_WRITE: 2,
4
+ COPY_SRC: 4,
5
+ COPY_DST: 8,
6
+ INDEX: 16,
7
+ VERTEX: 32,
8
+ UNIFORM: 64,
9
+ STORAGE: 128,
10
+ INDIRECT: 256,
11
+ QUERY_RESOLVE: 512
12
+ };
13
+ const TextureUsage = {
14
+ COPY_SRC: 1,
15
+ COPY_DST: 2,
16
+ TEXTURE_BINDING: 4,
17
+ STORAGE_BINDING: 8,
18
+ RENDER_ATTACHMENT: 16
19
+ };
20
+ const ShaderStage = { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 };
21
+ const MapMode = { READ: 1, WRITE: 2 };
22
+ const ColorWrite = { RED: 1, GREEN: 2, BLUE: 4, ALPHA: 8, ALL: 15 };
23
+ function installGpuConstants() {
24
+ const g = globalThis;
25
+ g.GPUBufferUsage ??= BufferUsage;
26
+ g.GPUTextureUsage ??= TextureUsage;
27
+ g.GPUShaderStage ??= ShaderStage;
28
+ g.GPUMapMode ??= MapMode;
29
+ g.GPUColorWrite ??= ColorWrite;
30
+ }
31
+ export {
32
+ BufferUsage,
33
+ ColorWrite,
34
+ MapMode,
35
+ ShaderStage,
36
+ TextureUsage,
37
+ installGpuConstants
38
+ };
@@ -0,0 +1,61 @@
1
+ import type { Webgl2Device } from './device.js';
2
+ import type { GlFormat } from './formats.js';
3
+ import { type ReadFormat } from './readback.js';
4
+ import { type Webgl2Buffer, Webgl2Texture } from './resources.js';
5
+ /** A texture read waiting for its buffer to be mapped: where it landed and how to repack it. */
6
+ export interface ReadJob {
7
+ pack: WebGLBuffer | null;
8
+ packSize: number;
9
+ read: ReadFormat;
10
+ info: GlFormat;
11
+ width: number;
12
+ rows: number;
13
+ layers: number;
14
+ offset: number;
15
+ bytesPerRow: number;
16
+ rowsPerImage: number;
17
+ }
18
+ export declare class Copier {
19
+ private readonly device;
20
+ private readonly gl;
21
+ private readonly read;
22
+ private readonly draw;
23
+ private rowLength;
24
+ private imageHeight;
25
+ private readonly views;
26
+ private viewOffset;
27
+ private zeros;
28
+ private readonly packs;
29
+ private depthPrograms;
30
+ private depthTarget;
31
+ constructor(device: Webgl2Device);
32
+ writeTexture(texture: Webgl2Texture, mip: number, x: number, y: number, z: number, data: BufferSource, offset: number, bytesPerRow: number | undefined, rowsPerImage: number | undefined, width: number, height: number, depth: number): void;
33
+ copyExternal(source: GPUCopyExternalImageSourceInfo, destination: GPUCopyExternalImageDestInfo, width: number, height: number): void;
34
+ copyBuffer(src: Webgl2Buffer, srcOffset: number, dst: Webgl2Buffer, dstOffset: number, size: number): void;
35
+ clearBuffer(buffer: Webgl2Buffer, offset: number, size: number): void;
36
+ copyBufferToTexture(buffer: Webgl2Buffer, offset: number, bytesPerRow: number, rowsPerImage: number, texture: Webgl2Texture, mip: number, x: number, y: number, z: number, width: number, height: number, depth: number): void;
37
+ copyTextureToBuffer(texture: Webgl2Texture, mip: number, x: number, y: number, z: number, buffer: Webgl2Buffer, offset: number, bytesPerRow: number, rowsPerImage: number, width: number, height: number, depth: number): void;
38
+ /** Repacks a finished read into `out`, at the job's offset plus `shift`, and frees its pack buffer. */
39
+ finishRead(job: ReadJob, out: Uint8Array, shift: number): void;
40
+ releaseRead(job: ReadJob): void;
41
+ copyTexture(src: Webgl2Texture, srcMip: number, sx: number, sy: number, sz: number, dst: Webgl2Texture, dstMip: number, dx: number, dy: number, dz: number, width: number, height: number, depth: number): void;
42
+ /** Binds `texture`'s mip and layer as the read framebuffer. */
43
+ bindRead(texture: Webgl2Texture, mip: number, layer: number): void;
44
+ /** Forgets GL objects of a lost or destroyed device. */
45
+ clear(): void;
46
+ private unpack;
47
+ /**
48
+ * A typed array of the upload type over all of `buffer`, kept while uploads come from the same
49
+ * buffer; `viewOffset` is where `byteOffset` falls in it, in elements.
50
+ */
51
+ private view;
52
+ private compressed;
53
+ private compressedAt;
54
+ private pack;
55
+ /**
56
+ * Reads depth (which readPixels can't) by drawing it into an R32F target with texelFetch, then
57
+ * reading that as floats into the bound pack buffer at `at`.
58
+ */
59
+ private readDepth;
60
+ private depthProgram;
61
+ }