@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Patrick Dias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Temporary Holding Version
1
+ # @aethervtt/shard-gpu-webgl2
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Part of [Shard](https://github.com/aethervtt/shard), a WebGPU-first 2D/3D game engine in TypeScript. See the repository for documentation.
@@ -0,0 +1,32 @@
1
+ import { type Webgl2Buffer, Webgl2Sampler, Webgl2TextureView } from './resources.js';
2
+ export declare class Webgl2BindGroupLayout {
3
+ readonly id: number;
4
+ readonly label: string;
5
+ readonly entries: readonly GPUBindGroupLayoutEntry[];
6
+ /** Uniform buffers with a dynamic offset, in binding order: the order dynamic offsets come in. */
7
+ readonly dynamic: readonly number[];
8
+ constructor(d: GPUBindGroupLayoutDescriptor);
9
+ }
10
+ export declare class Webgl2PipelineLayout {
11
+ readonly id: number;
12
+ readonly label: string;
13
+ readonly groups: readonly Webgl2BindGroupLayout[];
14
+ constructor(d: GPUPipelineLayoutDescriptor);
15
+ }
16
+ export interface BoundBuffer {
17
+ buffer: Webgl2Buffer;
18
+ offset: number;
19
+ size: number;
20
+ }
21
+ export declare class Webgl2BindGroup {
22
+ readonly id: number;
23
+ readonly label: string;
24
+ readonly layout: Webgl2BindGroupLayout;
25
+ /** By binding number. */
26
+ readonly buffers: (BoundBuffer | undefined)[];
27
+ readonly views: (Webgl2TextureView | undefined)[];
28
+ readonly samplers: (Webgl2Sampler | undefined)[];
29
+ /** Where each dynamic offset applies: its binding, in the order offsets are given. */
30
+ readonly dynamic: readonly number[];
31
+ constructor(d: GPUBindGroupDescriptor);
32
+ }
@@ -0,0 +1,81 @@
1
+ import { unsupported } from "./errors.js";
2
+ import { Webgl2Sampler, Webgl2TextureView } from "./resources.js";
3
+ let nextId = 1;
4
+ class Webgl2BindGroupLayout {
5
+ id = nextId++;
6
+ label;
7
+ entries;
8
+ /** Uniform buffers with a dynamic offset, in binding order: the order dynamic offsets come in. */
9
+ dynamic;
10
+ constructor(d) {
11
+ this.label = d.label ?? "";
12
+ this.entries = [...d.entries];
13
+ for (const e of this.entries) {
14
+ if (e.storageTexture) throw unsupported(`bind a storage texture ("${this.label}")`);
15
+ if (e.buffer && (e.buffer.type === "storage" || e.buffer.type === "read-only-storage")) {
16
+ if (e.visibility & 3) {
17
+ throw unsupported(
18
+ `bind a storage buffer to a vertex or fragment shader ("${this.label}" #${e.binding})`,
19
+ "Read engine data through a @data declaration (0064)."
20
+ );
21
+ }
22
+ }
23
+ if (e.externalTexture) throw unsupported(`bind an external texture ("${this.label}")`);
24
+ }
25
+ this.dynamic = this.entries.filter((e) => e.buffer?.hasDynamicOffset).map((e) => e.binding).sort((a, b) => a - b);
26
+ }
27
+ }
28
+ class Webgl2PipelineLayout {
29
+ id = nextId++;
30
+ label;
31
+ groups;
32
+ constructor(d) {
33
+ this.label = d.label ?? "";
34
+ this.groups = [...d.bindGroupLayouts];
35
+ }
36
+ }
37
+ class Webgl2BindGroup {
38
+ id = nextId++;
39
+ label;
40
+ layout;
41
+ /** By binding number. */
42
+ buffers = [];
43
+ views = [];
44
+ samplers = [];
45
+ /** Where each dynamic offset applies: its binding, in the order offsets are given. */
46
+ dynamic;
47
+ constructor(d) {
48
+ this.label = d.label ?? "";
49
+ this.layout = d.layout;
50
+ this.dynamic = this.layout.dynamic;
51
+ for (const e of d.entries) {
52
+ const r = e.resource;
53
+ if (r instanceof Webgl2TextureView) {
54
+ if (!r.bindable()) {
55
+ throw unsupported(
56
+ `bind "${r.texture.label}" as a ${r.dimension} view of layers ${r.baseArrayLayer}\u2013${r.baseArrayLayer + r.arrayLayerCount - 1} (it binds as ${r.texture.bindingDimension})`,
57
+ "A baseline texture binds as the one dimension it was made for (textureBindingViewDimension)."
58
+ );
59
+ }
60
+ this.views[e.binding] = r;
61
+ } else if (r instanceof Webgl2Sampler) {
62
+ this.samplers[e.binding] = r;
63
+ } else if (r && typeof r === "object" && "buffer" in r) {
64
+ const b = r;
65
+ const offset = b.offset ?? 0;
66
+ this.buffers[e.binding] = {
67
+ buffer: b.buffer,
68
+ offset,
69
+ size: b.size ?? b.buffer.size - offset
70
+ };
71
+ } else {
72
+ throw unsupported(`bind ${String(r)} ("${this.label}" #${e.binding})`);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ export {
78
+ Webgl2BindGroup,
79
+ Webgl2BindGroupLayout,
80
+ Webgl2PipelineLayout
81
+ };
@@ -0,0 +1,73 @@
1
+ import { type GlslStage, type GlslTranslation, type Naga } from './naga.js';
2
+ /** The naga build in `wasm/shard_naga.wasm` (crates/shard-naga): part of every key. */
3
+ export declare const NAGA_VERSION = "30.0.1";
4
+ /**
5
+ * The shim's own version, also in every key: bump it when what the shim asks naga for, or does to
6
+ * its GLSL, changes.
7
+ */
8
+ export declare const SHIM_VERSION = 1;
9
+ /** What a baked set holds (`.shard/shaders/webgl2.json`). */
10
+ export interface BakedTranslations {
11
+ format: 'shard-webgl2-glsl';
12
+ naga: string;
13
+ shim: number;
14
+ /** By key (`translationKey`). */
15
+ entries: Record<string, GlslTranslation>;
16
+ }
17
+ export interface ShaderCacheStats {
18
+ /** Translations found without naga, by where. */
19
+ hits: {
20
+ memory: number;
21
+ baked: number;
22
+ stored: number;
23
+ };
24
+ /** What naga translated this session, and how long each took (ms). */
25
+ misses: {
26
+ entry: string;
27
+ stage: GlslStage;
28
+ ms: number;
29
+ }[];
30
+ /** How long loading naga took, or undefined if this session never needed it. */
31
+ nagaLoadMs: number | undefined;
32
+ /** Translations in the baked set (0 without one, or if it was for another naga or shim). */
33
+ baked: number;
34
+ }
35
+ export interface TranslatorOptions {
36
+ /** EXT_clip_control is on: only y is flipped in the vertex stage. */
37
+ clipControl: boolean;
38
+ /** A baked set, or where it's served. */
39
+ baked?: string | URL | BakedTranslations;
40
+ /** Keeps translations in IndexedDB across sessions. Default true where there is IndexedDB. */
41
+ persist?: boolean;
42
+ /** Loads naga. Tests stub it. */
43
+ naga?: () => Promise<Naga>;
44
+ }
45
+ /**
46
+ * A translation's key: naga's and the shim's versions, the clip mode, the stage and entry point,
47
+ * and the linked WGSL. A define or a data layout changes the WGSL, so the key; nothing else does.
48
+ */
49
+ export declare function translationKey(code: string, entry: string, stage: GlslStage, clipControl: boolean): string;
50
+ export declare class Translator {
51
+ readonly stats: ShaderCacheStats;
52
+ private readonly options;
53
+ private readonly memory;
54
+ private bakedSet;
55
+ private bakedEntries;
56
+ private store;
57
+ private naga;
58
+ constructor(options: TranslatorOptions);
59
+ /**
60
+ * Every translation this session used, as a baked set: what a host records by running once on
61
+ * WebGL2, to ship (`webgl2.shaders`) so later sessions skip naga for them.
62
+ */
63
+ export(): BakedTranslations;
64
+ /** From memory or the (already fetched) baked set; undefined otherwise. Never loads anything. */
65
+ cached(code: string, entry: string, stage: GlslStage): GlslTranslation | undefined;
66
+ translate(code: string, entry: string, stage: GlslStage): Promise<GlslTranslation>;
67
+ /** Fetches the baked set once; a set for another naga or shim counts as none. */
68
+ private loadBaked;
69
+ private loadNaga;
70
+ private db;
71
+ private read;
72
+ private write;
73
+ }
package/dist/cache.js ADDED
@@ -0,0 +1,184 @@
1
+ import { loadNaga } from "./naga.js";
2
+ const NAGA_VERSION = "30.0.1";
3
+ const SHIM_VERSION = 1;
4
+ function hash(text) {
5
+ const lane = (seed) => {
6
+ let h1 = 3735928559 ^ seed;
7
+ let h2 = 1103547991 ^ seed;
8
+ for (let i = 0; i < text.length; i++) {
9
+ const c = text.charCodeAt(i);
10
+ h1 = Math.imul(h1 ^ c, 2654435761);
11
+ h2 = Math.imul(h2 ^ c, 1597334677);
12
+ }
13
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
14
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
15
+ return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16).padStart(14, "0");
16
+ };
17
+ return lane(1) + lane(2);
18
+ }
19
+ function translationKey(code, entry, stage, clipControl) {
20
+ return hash(
21
+ `${NAGA_VERSION}|${SHIM_VERSION}|${clipControl ? "clip" : "remap"}|${stage}|${entry}|${code}`
22
+ );
23
+ }
24
+ const DB = "shard";
25
+ const STORE = "webgl2-glsl";
26
+ function openStore() {
27
+ const idb = globalThis.indexedDB;
28
+ if (!idb) return Promise.resolve(void 0);
29
+ return new Promise((resolve) => {
30
+ try {
31
+ const request = idb.open(DB, 1);
32
+ request.onupgradeneeded = () => {
33
+ if (!request.result.objectStoreNames.contains(STORE))
34
+ request.result.createObjectStore(STORE);
35
+ };
36
+ request.onsuccess = () => resolve(request.result);
37
+ request.onerror = () => resolve(void 0);
38
+ request.onblocked = () => resolve(void 0);
39
+ } catch {
40
+ resolve(void 0);
41
+ }
42
+ });
43
+ }
44
+ class Translator {
45
+ stats = {
46
+ hits: { memory: 0, baked: 0, stored: 0 },
47
+ misses: [],
48
+ nagaLoadMs: void 0,
49
+ baked: 0
50
+ };
51
+ options;
52
+ memory = /* @__PURE__ */ new Map();
53
+ bakedSet;
54
+ bakedEntries;
55
+ store;
56
+ naga;
57
+ constructor(options) {
58
+ this.options = options;
59
+ }
60
+ /**
61
+ * Every translation this session used, as a baked set: what a host records by running once on
62
+ * WebGL2, to ship (`webgl2.shaders`) so later sessions skip naga for them.
63
+ */
64
+ export() {
65
+ return {
66
+ format: "shard-webgl2-glsl",
67
+ naga: NAGA_VERSION,
68
+ shim: SHIM_VERSION,
69
+ entries: Object.fromEntries(this.memory)
70
+ };
71
+ }
72
+ /** From memory or the (already fetched) baked set; undefined otherwise. Never loads anything. */
73
+ cached(code, entry, stage) {
74
+ const key = translationKey(code, entry, stage, this.options.clipControl);
75
+ const hit = this.memory.get(key);
76
+ if (hit) {
77
+ this.stats.hits.memory++;
78
+ return hit;
79
+ }
80
+ const baked = this.bakedEntries?.[key];
81
+ if (baked) {
82
+ this.memory.set(key, baked);
83
+ this.stats.hits.baked++;
84
+ }
85
+ return baked;
86
+ }
87
+ async translate(code, entry, stage) {
88
+ const key = translationKey(code, entry, stage, this.options.clipControl);
89
+ const hit = this.memory.get(key);
90
+ if (hit) {
91
+ this.stats.hits.memory++;
92
+ return hit;
93
+ }
94
+ const baked = (await this.loadBaked())?.[key];
95
+ if (baked) {
96
+ this.memory.set(key, baked);
97
+ this.stats.hits.baked++;
98
+ return baked;
99
+ }
100
+ const stored = await this.read(key);
101
+ if (stored) {
102
+ this.memory.set(key, stored);
103
+ this.stats.hits.stored++;
104
+ return stored;
105
+ }
106
+ const naga = await this.loadNaga();
107
+ const start = performance.now();
108
+ const made = naga.translate(code, entry, stage, { clipControl: this.options.clipControl });
109
+ this.stats.misses.push({ entry, stage, ms: performance.now() - start });
110
+ this.memory.set(key, made);
111
+ void this.write(key, made);
112
+ return made;
113
+ }
114
+ /** Fetches the baked set once; a set for another naga or shim counts as none. */
115
+ loadBaked() {
116
+ const source = this.options.baked;
117
+ if (!source) return Promise.resolve(void 0);
118
+ this.bakedSet ??= (async () => {
119
+ try {
120
+ let set;
121
+ if (typeof source === "string" || source instanceof URL) {
122
+ const response = await fetch(source);
123
+ if (!response.ok) return void 0;
124
+ set = await response.json();
125
+ } else {
126
+ set = source;
127
+ }
128
+ if (set.format !== "shard-webgl2-glsl" || set.naga !== NAGA_VERSION || set.shim !== SHIM_VERSION) {
129
+ return void 0;
130
+ }
131
+ this.stats.baked = Object.keys(set.entries).length;
132
+ this.bakedEntries = set.entries;
133
+ return set.entries;
134
+ } catch {
135
+ return void 0;
136
+ }
137
+ })();
138
+ return this.bakedSet;
139
+ }
140
+ loadNaga() {
141
+ this.naga ??= (async () => {
142
+ const start = performance.now();
143
+ const naga = await (this.options.naga ?? loadNaga)();
144
+ this.stats.nagaLoadMs = performance.now() - start;
145
+ return naga;
146
+ })();
147
+ this.naga.catch(() => {
148
+ this.naga = void 0;
149
+ });
150
+ return this.naga;
151
+ }
152
+ db() {
153
+ if (this.options.persist === false) return Promise.resolve(void 0);
154
+ this.store ??= openStore();
155
+ return this.store;
156
+ }
157
+ async read(key) {
158
+ const db = await this.db();
159
+ if (!db) return void 0;
160
+ return new Promise((resolve) => {
161
+ try {
162
+ const request = db.transaction(STORE, "readonly").objectStore(STORE).get(key);
163
+ request.onsuccess = () => resolve(request.result);
164
+ request.onerror = () => resolve(void 0);
165
+ } catch {
166
+ resolve(void 0);
167
+ }
168
+ });
169
+ }
170
+ async write(key, value) {
171
+ const db = await this.db();
172
+ if (!db) return;
173
+ try {
174
+ db.transaction(STORE, "readwrite").objectStore(STORE).put(value, key);
175
+ } catch {
176
+ }
177
+ }
178
+ }
179
+ export {
180
+ NAGA_VERSION,
181
+ SHIM_VERSION,
182
+ Translator,
183
+ translationKey
184
+ };
@@ -0,0 +1,101 @@
1
+ import type { Webgl2BindGroup } from './binding.js';
2
+ import type { Webgl2RenderPipeline } from './pipeline.js';
3
+ import type { Webgl2QuerySet } from './queries.js';
4
+ import type { Webgl2Buffer, Webgl2TextureView } from './resources.js';
5
+ export declare const OP: {
6
+ readonly BEGIN_PASS: 1;
7
+ readonly END_PASS: 2;
8
+ readonly SET_PIPELINE: 3;
9
+ readonly SET_BIND_GROUP: 4;
10
+ readonly SET_VERTEX_BUFFER: 5;
11
+ readonly SET_INDEX_BUFFER: 6;
12
+ readonly DRAW: 7;
13
+ readonly DRAW_INDEXED: 8;
14
+ readonly VIEWPORT: 9;
15
+ readonly SCISSOR: 10;
16
+ readonly STENCIL_REFERENCE: 11;
17
+ readonly BLEND_CONSTANT: 12;
18
+ readonly COPY_BUFFER: 13;
19
+ readonly COPY_BUFFER_TO_TEXTURE: 14;
20
+ readonly COPY_TEXTURE_TO_BUFFER: 15;
21
+ readonly COPY_TEXTURE: 16;
22
+ readonly CLEAR_BUFFER: 17;
23
+ readonly BEGIN_QUERY: 18;
24
+ readonly END_QUERY: 19;
25
+ readonly RESOLVE_QUERIES: 20;
26
+ };
27
+ export declare class CommandStream {
28
+ nums: Float64Array<ArrayBuffer>;
29
+ n: number;
30
+ readonly refs: unknown[];
31
+ r: number;
32
+ num(value: number): void;
33
+ ref(value: unknown): void;
34
+ /** Empties it, dropping its references so recorded objects can be collected. */
35
+ reset(): void;
36
+ }
37
+ export declare class Webgl2CommandBuffer {
38
+ label: string;
39
+ /** What to replay; undefined once submitted. */
40
+ stream: CommandStream | undefined;
41
+ /** The encoder that made it, pooled again after the submit. */
42
+ readonly encoder: Webgl2CommandEncoder;
43
+ constructor(encoder: Webgl2CommandEncoder);
44
+ }
45
+ type Extent = GPUExtent3D;
46
+ export declare class Webgl2CommandEncoder {
47
+ label: string;
48
+ /** @internal The pass being recorded times itself (`timestampWrites`): its end ends the query. */
49
+ timedPass: boolean;
50
+ private stream;
51
+ private readonly pass;
52
+ private readonly buffer;
53
+ constructor();
54
+ /** @internal Starts recording into `stream` (a new or pooled encoder). */
55
+ begin(stream: CommandStream, label: string): this;
56
+ /** @internal The stream commands record into. */
57
+ get recording(): CommandStream;
58
+ beginRenderPass(d: GPURenderPassDescriptor): Webgl2RenderPassEncoder;
59
+ beginComputePass(d?: GPUComputePassDescriptor): never;
60
+ copyBufferToBuffer(source: Webgl2Buffer, a: number | Webgl2Buffer, b?: Webgl2Buffer | number, c?: number, d?: number): void;
61
+ copyBufferToTexture(source: GPUTexelCopyBufferInfo, destination: GPUTexelCopyTextureInfo, size: Extent): void;
62
+ copyTextureToBuffer(source: GPUTexelCopyTextureInfo, destination: GPUTexelCopyBufferInfo, size: Extent): void;
63
+ copyTextureToTexture(source: GPUTexelCopyTextureInfo, destination: GPUTexelCopyTextureInfo, size: Extent): void;
64
+ clearBuffer(buffer: Webgl2Buffer, offset?: number, size?: number): void;
65
+ /** Pairs of the set to the buffer: written when the buffer is mapped (queries.ts). */
66
+ resolveQuerySet(querySet: Webgl2QuerySet, firstQuery: number, queryCount: number, destination: Webgl2Buffer, destinationOffset: number): void;
67
+ writeTimestamp(): never;
68
+ pushDebugGroup(): void;
69
+ popDebugGroup(): void;
70
+ insertDebugMarker(): void;
71
+ finish(d?: GPUCommandBufferDescriptor): Webgl2CommandBuffer;
72
+ }
73
+ export declare class Webgl2RenderPassEncoder {
74
+ label: string;
75
+ private readonly encoder;
76
+ constructor(encoder: Webgl2CommandEncoder);
77
+ setPipeline(pipeline: Webgl2RenderPipeline): void;
78
+ setBindGroup(index: number, group: Webgl2BindGroup | null, offsets?: Iterable<number> | Uint32Array, start?: number, length?: number): void;
79
+ setVertexBuffer(slot: number, buffer: Webgl2Buffer | null, offset?: number, size?: number): void;
80
+ setIndexBuffer(buffer: Webgl2Buffer, format: GPUIndexFormat, offset?: number, size?: number): void;
81
+ draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void;
82
+ drawIndexed(indexCount: number, instanceCount?: number, firstIndex?: number, baseVertex?: number, firstInstance?: number): void;
83
+ drawIndirect(): never;
84
+ drawIndexedIndirect(): never;
85
+ setViewport(x: number, y: number, width: number, height: number, minDepth: number, maxDepth: number): void;
86
+ setScissorRect(x: number, y: number, width: number, height: number): void;
87
+ setStencilReference(reference: number): void;
88
+ setBlendConstant(color: GPUColor): void;
89
+ executeBundles(): never;
90
+ beginOcclusionQuery(): never;
91
+ endOcclusionQuery(): never;
92
+ pushDebugGroup(): void;
93
+ popDebugGroup(): void;
94
+ insertDebugMarker(): void;
95
+ end(): void;
96
+ }
97
+ /** Where a view attaches: its array layer, cube face, or (3D) the pass's depth slice. */
98
+ export declare function layerOf(view: Webgl2TextureView, depthSlice: number): number;
99
+ /** A mip level's extent. */
100
+ export declare function mipSize(size: number, mip: number): number;
101
+ export {};