webgl2 1.2.4 → 1.2.6

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.
package/coverage.md CHANGED
@@ -4,43 +4,48 @@
4
4
 
5
5
  | File | Lines Covered | Lines Missed | Total Lines | Coverage |
6
6
  |---|---|---|---|---:|
7
- | src/coverage.rs | 18 | 1 | 19 | 94.74% 🟢 |
8
- | src/decompiler/ast.rs | 4 | 0 | 4 | 100.00% 🟢 |
9
- | src/decompiler/emitter.rs | 35 | 2 | 37 | 94.59% 🟢 |
10
- | src/decompiler/lifter.rs | 11 | 14 | 25 | 44.00% 🟠 |
11
- | src/decompiler/simplifier.rs | 30 | 1 | 31 | 96.77% 🟢 |
12
- | src/error.rs | 13 | 2 | 15 | 86.67% 🟢 |
13
- | src/lib.rs | 87 | 299 | 386 | 22.54% 🟠 |
14
- | src/naga_wasm_backend/backend.rs | 173 | 24 | 197 | 87.82% 🟢 |
15
- | src/naga_wasm_backend/call_lowering.rs | 22 | 3 | 25 | 88.00% 🟢 |
16
- | src/naga_wasm_backend/control_flow.rs | 37 | 41 | 78 | 47.44% 🟠 |
17
- | src/naga_wasm_backend/debug/stub.rs | 25 | 9 | 34 | 73.53% 🟡 |
18
- | src/naga_wasm_backend/expressions.rs | 143 | 155 | 298 | 47.99% 🟠 |
19
- | src/naga_wasm_backend/function_abi.rs | 31 | 0 | 31 | 100.00% 🟢 |
20
- | src/naga_wasm_backend/functions/prep.rs | 4 | 2 | 6 | 66.67% 🟡 |
21
- | src/naga_wasm_backend/functions/registry.rs | 0 | 1 | 1 | 0.00% 🟡 |
22
- | src/naga_wasm_backend/memory_layout.rs | 16 | 4 | 20 | 80.00% 🟢 |
23
- | src/naga_wasm_backend/mod.rs | 5 | 5 | 10 | 50.00% 🟡 |
24
- | src/naga_wasm_backend/output_layout.rs | 2 | 1 | 3 | 66.67% 🟡 |
25
- | src/wasm_gl_emu/device.rs | 49 | 12 | 61 | 80.33% 🟢 |
26
- | src/wasm_gl_emu/framebuffer.rs | 3 | 1 | 4 | 75.00% 🟡 |
27
- | src/wasm_gl_emu/rasterizer.rs | 52 | 58 | 110 | 47.27% 🟠 |
28
- | src/wasm_gl_emu/transfer.rs | 11 | 16 | 27 | 40.74% 🟠 |
29
- | src/webgl2_context/shaders.rs | 160 | 14 | 174 | 91.95% 🟢 |
30
- | src/webgl2_context/state.rs | 80 | 1 | 81 | 98.77% 🟢 |
31
- | src/webgl2_context/textures.rs | 22 | 7 | 29 | 75.86% 🟡 |
32
- | src/webgl2_context/types.rs | 52 | 14 | 66 | 78.79% 🟡 |
33
- | src/webgl2_context/vaos.rs | 25 | 19 | 44 | 56.82% 🟡 |
34
- | src/webgpu/adapter.rs | 3 | 2 | 5 | 60.00% 🟡 |
35
- | src/webgpu/backend.rs | 68 | 20 | 88 | 77.27% 🟡 |
36
- | src/webgpu/command.rs | 1 | 1 | 2 | 50.00% 🟡 |
37
- | **Total** | **1182** | **729** | **1911** | **61.85% 🟡** |
7
+ | src/coverage.rs | 4 | 1 | 5 | 80.00% 🟢 |
8
+ | src/decompiler/ast.rs | 5 | 0 | 5 | 100.00% 🟢 |
9
+ | src/decompiler/emitter.rs | 25 | 5 | 30 | 83.33% 🟢 |
10
+ | src/decompiler/lifter.rs | 7 | 1 | 8 | 87.50% 🟢 |
11
+ | src/decompiler/mod.rs | 2 | 1 | 3 | 66.67% 🟡 |
12
+ | src/decompiler/module.rs | 1 | 2 | 3 | 33.33% 🟡 |
13
+ | src/decompiler/parser.rs | 24 | 2 | 26 | 92.31% 🟢 |
14
+ | src/decompiler/simplifier.rs | 32 | 0 | 32 | 100.00% 🟢 |
15
+ | src/error.rs | 34 | 2 | 36 | 94.44% 🟢 |
16
+ | src/lib.rs | 83 | 317 | 400 | 20.75% 🟠 |
17
+ | src/naga_wasm_backend/backend.rs | 147 | 42 | 189 | 77.78% 🟡 |
18
+ | src/naga_wasm_backend/call_lowering.rs | 23 | 3 | 26 | 88.46% 🟢 |
19
+ | src/naga_wasm_backend/control_flow.rs | 37 | 37 | 74 | 50.00% 🟡 |
20
+ | src/naga_wasm_backend/debug/stub.rs | 8 | 0 | 8 | 100.00% 🟢 |
21
+ | src/naga_wasm_backend/expressions.rs | 130 | 151 | 281 | 46.26% 🟠 |
22
+ | src/naga_wasm_backend/function_abi.rs | 22 | 19 | 41 | 53.66% 🟡 |
23
+ | src/naga_wasm_backend/functions/prep.rs | 7 | 2 | 9 | 77.78% 🟡 |
24
+ | src/naga_wasm_backend/functions/registry.rs | 3 | 0 | 3 | 100.00% 🟢 |
25
+ | src/naga_wasm_backend/mod.rs | 6 | 1 | 7 | 85.71% 🟢 |
26
+ | src/naga_wasm_backend/output_layout.rs | 10 | 1 | 11 | 90.91% 🟢 |
27
+ | src/naga_wasm_backend/types.rs | 19 | 3 | 22 | 86.36% 🟢 |
28
+ | src/wasm_gl_emu/device.rs | 2 | 1 | 3 | 66.67% 🟡 |
29
+ | src/wasm_gl_emu/framebuffer.rs | 3 | 0 | 3 | 100.00% 🟢 |
30
+ | src/wasm_gl_emu/transfer.rs | 11 | 10 | 21 | 52.38% 🟡 |
31
+ | src/webgl2_context/buffers.rs | 4 | 0 | 4 | 100.00% 🟢 |
32
+ | src/webgl2_context/drawing.rs | 32 | 1 | 33 | 96.97% 🟢 |
33
+ | src/webgl2_context/renderbuffers.rs | 5 | 6 | 11 | 45.45% 🟠 |
34
+ | src/webgl2_context/shaders.rs | 179 | 33 | 212 | 84.43% 🟢 |
35
+ | src/webgl2_context/state.rs | 13 | 2 | 15 | 86.67% 🟢 |
36
+ | src/webgl2_context/textures.rs | 47 | 8 | 55 | 85.45% 🟢 |
37
+ | src/webgl2_context/types.rs | 11 | 3 | 14 | 78.57% 🟡 |
38
+ | src/webgpu/adapter.rs | 8 | 0 | 8 | 100.00% 🟢 |
39
+ | src/webgpu/backend.rs | 124 | 25 | 149 | 83.22% 🟢 |
40
+ | src/webgpu/command.rs | 7 | 0 | 7 | 100.00% 🟢 |
41
+ | src/webgpu/texture.rs | 1 | 0 | 1 | 100.00% 🟢 |
42
+ | **Total** | **1076** | **679** | **1755** | **61.31% 🟡** |
38
43
 
39
44
  ## Top Missed Files
40
45
 
41
46
  | File | Lines Missed | Illustrative Line | Coverage |
42
47
  |---|---|---|---:|
43
- | src/lib.rs | 299/386 | [1994] `) -> u32 {` | 22.54% 🟠 |
44
- | src/naga_wasm_backend/expressions.rs | 155/298 | [1845] `translate_expression(*argument, ctx)?;` | 47.99% 🟠 |
45
- | src/wasm_gl_emu/rasterizer.rs | 58/110 | [370] `match eq {` | 47.27% 🟠 |
46
- | src/naga_wasm_backend/control_flow.rs | 41/78 | [535] `let types = super::types::naga_to_wasm_types(` | 47.44% 🟠 |
48
+ | src/lib.rs | 317/400 | [1994] `///` | 20.75% 🟠 |
49
+ | src/naga_wasm_backend/expressions.rs | 151/281 | [1426] `}` | 46.26% 🟠 |
50
+ | src/naga_wasm_backend/backend.rs | 42/189 | [325] `func.instruction(&Instruction::LocalGet(l_bpp));` | 77.78% 🟡 |
51
+ | src/naga_wasm_backend/control_flow.rs | 37/74 | [464] `for arg in arguments {` | 50.00% 🟡 |
package/index.js CHANGED
@@ -269,18 +269,25 @@ async function initWASM({ debug } = {}) {
269
269
  ACTIVE_FRAME_SP: turboGlobals.ACTIVE_FRAME_SP,
270
270
  };
271
271
 
272
- // Copy math functions
273
- const mathFuncs = [
274
- 'gl_cos', 'gl_sin', 'gl_tan', 'gl_acos', 'gl_asin', 'gl_atan', 'gl_atan2',
275
- 'gl_exp', 'gl_exp2', 'gl_log', 'gl_log2', 'gl_pow', 'gl_floor', 'gl_ceil',
276
- 'gl_fract', 'gl_mod', 'gl_min', 'gl_max', 'gl_abs', 'gl_sign', 'gl_sqrt',
277
- 'gl_inversesqrt', 'gl_sinh', 'gl_cosh', 'gl_tanh', 'gl_asinh', 'gl_acosh', 'gl_atanh'
278
- ];
279
- for (const name of mathFuncs) {
280
- if (instance.exports[name]) {
281
- env[name] = instance.exports[name];
282
- }
283
- }
272
+ // Map transcendental functions to JS Math equivalents for maximum accuracy
273
+ env.gl_sin = Math.sin;
274
+ env.gl_cos = Math.cos;
275
+ env.gl_tan = Math.tan;
276
+ env.gl_asin = Math.asin;
277
+ env.gl_acos = Math.acos;
278
+ env.gl_atan = Math.atan;
279
+ env.gl_atan2 = Math.atan2;
280
+ env.gl_exp = Math.exp;
281
+ env.gl_exp2 = (x) => Math.pow(2, x);
282
+ env.gl_log = Math.log;
283
+ env.gl_log2 = Math.log2;
284
+ env.gl_pow = Math.pow;
285
+ env.gl_sinh = Math.sinh;
286
+ env.gl_cosh = Math.cosh;
287
+ env.gl_tanh = Math.tanh;
288
+ env.gl_asinh = Math.asinh;
289
+ env.gl_acosh = Math.acosh;
290
+ env.gl_atanh = Math.atanh;
284
291
 
285
292
  const shaderInstance = new WebAssembly.Instance(shaderModule, { env });
286
293
  if (shaderInstance.exports.main) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webgl2",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "WebGL2 tools to derisk large GPU projects on the web beyond toys and demos.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -14,6 +14,43 @@ export const ERR_NOT_IMPLEMENTED = 4;
14
14
  export const ERR_GL = 5;
15
15
  export const ERR_INTERNAL = 6;
16
16
 
17
+ function getBPP(internalFormat) {
18
+ switch (internalFormat) {
19
+ case 0x822E: // R32F
20
+ case 0x8236: // R32UI
21
+ case 0x8235: // R32I
22
+ return 4;
23
+ case 0x8230: // RG32F
24
+ case 0x823C: // RG32UI
25
+ case 0x823B: // RG32I
26
+ return 8;
27
+ case 0x8814: // RGBA32F
28
+ case 0x8D70: // RGBA32UI
29
+ case 0x8D82: // RGBA32I
30
+ case 0x8815: // RGB32F (often promoted to RGBA32F)
31
+ case 0x8D71: // RGB32UI
32
+ case 0x8D83: // RGB32I
33
+ return 16;
34
+ case 0x822D: // R16F
35
+ case 0x8234: // R16UI
36
+ case 0x8233: // R16I
37
+ return 2;
38
+ case 0x822F: // RG16F
39
+ case 0x823A: // RG16UI
40
+ case 0x8239: // RG16I
41
+ return 4;
42
+ case 0x881A: // RGBA16F
43
+ case 0x8D76: // RGBA16UI
44
+ case 0x8D88: // RGBA16I
45
+ case 0x881B: // RGB16F
46
+ case 0x8D77: // RGB16UI
47
+ case 0x8D89: // RGB16I
48
+ return 8;
49
+ default:
50
+ return 4; // Default to RGBA8
51
+ }
52
+ }
53
+
17
54
  import { WasmWebGLTexture } from './webgl2_texture.js';
18
55
  import {
19
56
  WasmWebGLShader,
@@ -43,6 +80,8 @@ export class WasmWebGL2RenderingContext {
43
80
  DEPTH_TEST = 0x0B71;
44
81
  STENCIL_TEST = 0x0B90;
45
82
  SCISSOR_TEST = 0x0C11;
83
+ BLEND = 0x0BE2;
84
+ CULL_FACE = 0x0B44;
46
85
  STENCIL_BUFFER_BIT = 0x00000400;
47
86
  COMPILE_STATUS = 0x8B81;
48
87
  LINK_STATUS = 0x8B82;
@@ -56,6 +95,22 @@ export class WasmWebGL2RenderingContext {
56
95
  PIXEL_UNPACK_BUFFER = 0x88EC;
57
96
  UNIFORM_BUFFER = 0x8A11;
58
97
  TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
98
+ TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F;
99
+ TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84;
100
+ TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
101
+ TRANSFORM_FEEDBACK_BINDING = 0x8E25;
102
+ TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F;
103
+ TRANSFORM_FEEDBACK_VARYINGS = 0x8C83;
104
+ TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76;
105
+ MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
106
+ MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
107
+ MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80;
108
+ INTERLEAVED_ATTRIBS = 0x8C8C;
109
+ SEPARATE_ATTRIBS = 0x8C8D;
110
+ TRANSFORM_FEEDBACK_PAUSED = 0x8E23;
111
+ TRANSFORM_FEEDBACK_ACTIVE = 0x8E24;
112
+ TRANSFORM_FEEDBACK = 0x8E22;
113
+ RASTERIZER_DISCARD = 0x8C89;
59
114
  STATIC_DRAW = 0x88E4;
60
115
  BYTE = 0x1400;
61
116
  UNSIGNED_BYTE = 0x1401;
@@ -137,6 +192,22 @@ export class WasmWebGL2RenderingContext {
137
192
  FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56;
138
193
  RENDERBUFFER_SAMPLES = 0x8CAB;
139
194
  FRAMEBUFFER_UNDEFINED = 0x8219;
195
+
196
+ MAX_DRAW_BUFFERS = 0x8824;
197
+ DRAW_BUFFER0 = 0x8825;
198
+ DRAW_BUFFER1 = 0x8826;
199
+ DRAW_BUFFER2 = 0x8827;
200
+ DRAW_BUFFER3 = 0x8828;
201
+ DRAW_BUFFER4 = 0x8829;
202
+ DRAW_BUFFER5 = 0x882A;
203
+ DRAW_BUFFER6 = 0x882B;
204
+ DRAW_BUFFER7 = 0x882C;
205
+ MAX_COLOR_ATTACHMENTS = 0x8CDF;
206
+ FRAMEBUFFER_BINDING = 0x8CA6;
207
+ DRAW_FRAMEBUFFER_BINDING = 0x8CA6;
208
+ READ_FRAMEBUFFER_BINDING = 0x8CAA;
209
+ RENDERBUFFER_BINDING = 0x8CA7;
210
+
140
211
  DEPTH_COMPONENT16 = 0x81A5;
141
212
  DEPTH_STENCIL = 0x84F9;
142
213
  RGBA4 = 0x8056;
@@ -263,6 +334,29 @@ export class WasmWebGL2RenderingContext {
263
334
  // TODO: potentially retrieve those one demand from the main WASM module when shader WASM modules are initialised
264
335
  this._turboGlobals = turboGlobals;
265
336
 
337
+ /** @type {Map<number, WasmWebGLTexture>} */
338
+ this._textureHandles = new Map();
339
+ /** @type {Map<number, WasmWebGLFramebuffer>} */
340
+ this._fbHandles = new Map();
341
+ /** @type {Map<number, WasmWebGLRenderbuffer>} */
342
+ this._rbHandles = new Map();
343
+ /** @type {Map<number, WasmWebGLBuffer>} */
344
+ this._bufferHandles = new Map();
345
+ /** @type {Map<number, WasmWebGLProgram>} */
346
+ this._programHandles = new Map();
347
+ /** @type {Map<number, WasmWebGLShader>} */
348
+ this._shaderHandles = new Map();
349
+ /** @type {Map<number, WasmWebGLVertexArrayObject>} */
350
+ this._vaoHandles = new Map();
351
+ /** @type {Map<number, WasmWebGLSampler>} */
352
+ this._samplerHandles = new Map();
353
+ /** @type {Map<number, WasmWebGLQuery>} */
354
+ this._queryHandles = new Map();
355
+ /** @type {Map<number, WasmWebGLSync>} */
356
+ this._syncHandles = new Map();
357
+ /** @type {Map<number, WasmWebGLTransformFeedback>} */
358
+ this._tfHandles = new Map();
359
+
266
360
  WasmWebGL2RenderingContext._contexts.set(this._ctxHandle, this);
267
361
  }
268
362
 
@@ -327,7 +421,9 @@ export class WasmWebGL2RenderingContext {
327
421
  throw new Error(`Failed to create texture: ${msg}`);
328
422
  }
329
423
  // Return a thin wrapper object representing the texture.
330
- return new WasmWebGLTexture(this, handle);
424
+ const tex = new WasmWebGLTexture(this, handle);
425
+ this._textureHandles.set(handle, tex);
426
+ return tex;
331
427
  }
332
428
 
333
429
  deleteTexture(tex) {
@@ -339,6 +435,7 @@ export class WasmWebGL2RenderingContext {
339
435
  const handle = tex && typeof tex === 'object' && typeof tex._handle === 'number' ? tex._handle : (tex >>> 0);
340
436
  const code = ex.wasm_ctx_delete_texture(this._ctxHandle, handle);
341
437
  _checkErr(code, this._instance);
438
+ this._textureHandles.delete(handle);
342
439
  // If a wrapper object was passed, mark it as deleted.
343
440
  if (tex && typeof tex === 'object') {
344
441
  try { tex._handle = 0; tex._deleted = true; } catch (e) { /* ignore */ }
@@ -370,7 +467,7 @@ export class WasmWebGL2RenderingContext {
370
467
 
371
468
  let data = pixels;
372
469
  if (!data) {
373
- data = new Uint8Array(width * height * 4);
470
+ data = new Uint8Array(width * height * getBPP(internalFormat));
374
471
  } else if (ArrayBuffer.isView(data)) {
375
472
  data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
376
473
  } else if (data instanceof ArrayBuffer) {
@@ -413,7 +510,7 @@ export class WasmWebGL2RenderingContext {
413
510
 
414
511
  let data = pixels;
415
512
  if (!data) {
416
- data = new Uint8Array(width * height * depth * 4);
513
+ data = new Uint8Array(width * height * depth * getBPP(internalFormat));
417
514
  } else if (ArrayBuffer.isView(data)) {
418
515
  data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
419
516
  } else if (data instanceof ArrayBuffer) {
@@ -479,7 +576,9 @@ export class WasmWebGL2RenderingContext {
479
576
  const msg = readErrorMessage(this._instance);
480
577
  throw new Error(`Failed to create framebuffer: ${msg}`);
481
578
  }
482
- return new WasmWebGLFramebuffer(this, handle);
579
+ const fb = new WasmWebGLFramebuffer(this, handle);
580
+ this._fbHandles.set(handle, fb);
581
+ return fb;
483
582
  }
484
583
 
485
584
  deleteFramebuffer(fb) {
@@ -491,6 +590,7 @@ export class WasmWebGL2RenderingContext {
491
590
  const handle = fb && typeof fb === 'object' && typeof fb._handle === 'number' ? fb._handle : (fb >>> 0);
492
591
  const code = ex.wasm_ctx_delete_framebuffer(this._ctxHandle, handle);
493
592
  _checkErr(code, this._instance);
593
+ this._fbHandles.delete(handle);
494
594
  if (fb && typeof fb === 'object') {
495
595
  try { fb._handle = 0; fb._deleted = true; } catch (e) { /* ignore */ }
496
596
  }
@@ -536,7 +636,9 @@ export class WasmWebGL2RenderingContext {
536
636
  const msg = readErrorMessage(this._instance);
537
637
  throw new Error(`Failed to create renderbuffer: ${msg}`);
538
638
  }
539
- return new WasmWebGLRenderbuffer(this, handle);
639
+ const rb = new WasmWebGLRenderbuffer(this, handle);
640
+ this._rbHandles.set(handle, rb);
641
+ return rb;
540
642
  }
541
643
 
542
644
  bindRenderbuffer(target, renderbuffer) {
@@ -559,6 +661,10 @@ export class WasmWebGL2RenderingContext {
559
661
  const rbHandle = renderbuffer && typeof renderbuffer === 'object' && typeof renderbuffer._handle === 'number' ? renderbuffer._handle : (renderbuffer >>> 0);
560
662
  const code = ex.wasm_ctx_delete_renderbuffer(this._ctxHandle, rbHandle);
561
663
  _checkErr(code, this._instance);
664
+ this._rbHandles.delete(rbHandle);
665
+ if (renderbuffer && typeof renderbuffer === 'object') {
666
+ try { renderbuffer._handle = 0; renderbuffer._deleted = true; } catch (e) { /* ignore */ }
667
+ }
562
668
  }
563
669
 
564
670
  isRenderbuffer(rb) {
@@ -1380,7 +1486,9 @@ export class WasmWebGL2RenderingContext {
1380
1486
  const msg = readErrorMessage(this._instance);
1381
1487
  throw new Error(`Failed to create buffer: ${msg}`);
1382
1488
  }
1383
- return new WasmWebGLBuffer(this, handle);
1489
+ const buf = new WasmWebGLBuffer(this, handle);
1490
+ this._bufferHandles.set(handle, buf);
1491
+ return buf;
1384
1492
  }
1385
1493
 
1386
1494
  bindBuffer(target, buffer) {
@@ -1394,6 +1502,35 @@ export class WasmWebGL2RenderingContext {
1394
1502
  _checkErr(code, this._instance);
1395
1503
  }
1396
1504
 
1505
+ bindBufferRange(target, index, buffer, offset, size) {
1506
+ this._assertNotDestroyed();
1507
+ const ex = this._instance.exports;
1508
+ if (!ex || typeof ex.wasm_ctx_bind_buffer_range !== "function") {
1509
+ throw new Error("wasm_ctx_bind_buffer_range not found");
1510
+ }
1511
+ const handle = buffer && typeof buffer === "object" && typeof buffer._handle === "number" ? buffer._handle : (buffer >>> 0);
1512
+ const code = ex.wasm_ctx_bind_buffer_range(
1513
+ this._ctxHandle,
1514
+ target >>> 0,
1515
+ index >>> 0,
1516
+ handle,
1517
+ offset >>> 0,
1518
+ size >>> 0
1519
+ );
1520
+ _checkErr(code, this._instance);
1521
+ }
1522
+
1523
+ bindBufferBase(target, index, buffer) {
1524
+ this._assertNotDestroyed();
1525
+ const ex = this._instance.exports;
1526
+ if (!ex || typeof ex.wasm_ctx_bind_buffer_base !== "function") {
1527
+ throw new Error("wasm_ctx_bind_buffer_base not found");
1528
+ }
1529
+ const handle = buffer && typeof buffer === "object" && typeof buffer._handle === "number" ? buffer._handle : (buffer >>> 0);
1530
+ const code = ex.wasm_ctx_bind_buffer_base(this._ctxHandle, target >>> 0, index >>> 0, handle);
1531
+ _checkErr(code, this._instance);
1532
+ }
1533
+
1397
1534
  deleteBuffer(buffer) {
1398
1535
  this._assertNotDestroyed();
1399
1536
  const ex = this._instance.exports;
@@ -1402,7 +1539,9 @@ export class WasmWebGL2RenderingContext {
1402
1539
  }
1403
1540
  const handle = buffer && typeof buffer === 'object' && typeof buffer._handle === 'number' ? buffer._handle : (buffer >>> 0);
1404
1541
  const code = ex.wasm_ctx_delete_buffer(this._ctxHandle, handle);
1405
- _checkErr(code, this._instance); if (buffer && typeof buffer === 'object') {
1542
+ _checkErr(code, this._instance);
1543
+ this._bufferHandles.delete(handle);
1544
+ if (buffer && typeof buffer === 'object') {
1406
1545
  try { buffer._handle = 0; buffer._deleted = true; } catch (e) { /* ignore */ }
1407
1546
  }
1408
1547
  }
@@ -1626,14 +1765,180 @@ export class WasmWebGL2RenderingContext {
1626
1765
  return res !== 0;
1627
1766
  }
1628
1767
 
1629
- createTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1630
- bindTransformFeedback(target, tf) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1631
- beginTransformFeedback(primitiveMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1632
- pauseTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1633
- resumeTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1634
- endTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1635
- transformFeedbackVaryings(program, varyings, bufferMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1636
- getTransformFeedbackVarying(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1768
+ createTransformFeedback() {
1769
+ this._assertNotDestroyed();
1770
+ const ex = this._instance.exports;
1771
+ if (!ex || typeof ex.wasm_ctx_create_transform_feedback !== "function") {
1772
+ throw new Error("wasm_ctx_create_transform_feedback not found");
1773
+ }
1774
+ const handle = ex.wasm_ctx_create_transform_feedback(this._ctxHandle);
1775
+ if (handle === 0) {
1776
+ const msg = readErrorMessage(this._instance);
1777
+ throw new Error(`Failed to create transform feedback: ${msg}`);
1778
+ }
1779
+ const tf = new WasmWebGLTransformFeedback(this, handle);
1780
+ this._tfHandles.set(handle, tf);
1781
+ return tf;
1782
+ }
1783
+
1784
+ deleteTransformFeedback(tf) {
1785
+ this._assertNotDestroyed();
1786
+ const ex = this._instance.exports;
1787
+ if (!ex || typeof ex.wasm_ctx_delete_transform_feedback !== "function") {
1788
+ throw new Error("wasm_ctx_delete_transform_feedback not found");
1789
+ }
1790
+ const handle = tf && typeof tf === "object" && typeof tf._handle === "number" ? tf._handle : (tf >>> 0);
1791
+ const code = ex.wasm_ctx_delete_transform_feedback(this._ctxHandle, handle);
1792
+ _checkErr(code, this._instance);
1793
+ this._tfHandles.delete(handle);
1794
+ if (tf && typeof tf === "object") {
1795
+ try { tf._handle = 0; tf._deleted = true; } catch (e) { /* ignore */ }
1796
+ }
1797
+ }
1798
+
1799
+ isTransformFeedback(tf) {
1800
+ this._assertNotDestroyed();
1801
+ const ex = this._instance.exports;
1802
+ if (!ex || typeof ex.wasm_ctx_is_transform_feedback !== "function") {
1803
+ throw new Error("wasm_ctx_is_transform_feedback not found");
1804
+ }
1805
+ const handle = tf && typeof tf === "object" && typeof tf._handle === "number" ? tf._handle : (tf >>> 0);
1806
+ return !!ex.wasm_ctx_is_transform_feedback(this._ctxHandle, handle);
1807
+ }
1808
+
1809
+ bindTransformFeedback(target, tf) {
1810
+ this._assertNotDestroyed();
1811
+ const ex = this._instance.exports;
1812
+ if (!ex || typeof ex.wasm_ctx_bind_transform_feedback !== "function") {
1813
+ throw new Error("wasm_ctx_bind_transform_feedback not found");
1814
+ }
1815
+ const handle = tf && typeof tf === "object" && typeof tf._handle === "number" ? tf._handle : (tf >>> 0);
1816
+ const code = ex.wasm_ctx_bind_transform_feedback(this._ctxHandle, target >>> 0, handle);
1817
+ _checkErr(code, this._instance);
1818
+ }
1819
+
1820
+ beginTransformFeedback(primitiveMode) {
1821
+ this._assertNotDestroyed();
1822
+ const ex = this._instance.exports;
1823
+ if (!ex || typeof ex.wasm_ctx_begin_transform_feedback !== "function") {
1824
+ throw new Error("wasm_ctx_begin_transform_feedback not found");
1825
+ }
1826
+ const code = ex.wasm_ctx_begin_transform_feedback(this._ctxHandle, primitiveMode >>> 0);
1827
+ _checkErr(code, this._instance);
1828
+ }
1829
+
1830
+ pauseTransformFeedback() {
1831
+ this._assertNotDestroyed();
1832
+ const ex = this._instance.exports;
1833
+ if (!ex || typeof ex.wasm_ctx_pause_transform_feedback !== "function") {
1834
+ throw new Error("wasm_ctx_pause_transform_feedback not found");
1835
+ }
1836
+ const code = ex.wasm_ctx_pause_transform_feedback(this._ctxHandle);
1837
+ _checkErr(code, this._instance);
1838
+ }
1839
+
1840
+ resumeTransformFeedback() {
1841
+ this._assertNotDestroyed();
1842
+ const ex = this._instance.exports;
1843
+ if (!ex || typeof ex.wasm_ctx_resume_transform_feedback !== "function") {
1844
+ throw new Error("wasm_ctx_resume_transform_feedback not found");
1845
+ }
1846
+ const code = ex.wasm_ctx_resume_transform_feedback(this._ctxHandle);
1847
+ _checkErr(code, this._instance);
1848
+ }
1849
+
1850
+ endTransformFeedback() {
1851
+ this._assertNotDestroyed();
1852
+ const ex = this._instance.exports;
1853
+ if (!ex || typeof ex.wasm_ctx_end_transform_feedback !== "function") {
1854
+ throw new Error("wasm_ctx_end_transform_feedback not found");
1855
+ }
1856
+ const code = ex.wasm_ctx_end_transform_feedback(this._ctxHandle);
1857
+ _checkErr(code, this._instance);
1858
+ }
1859
+
1860
+ transformFeedbackVaryings(program, varyings, bufferMode) {
1861
+ this._assertNotDestroyed();
1862
+ const ex = this._instance.exports;
1863
+ if (!ex || typeof ex.wasm_ctx_transform_feedback_varyings !== "function") {
1864
+ throw new Error("wasm_ctx_transform_feedback_varyings not found");
1865
+ }
1866
+ const programHandle = program && typeof program === "object" && typeof program._handle === "number" ? program._handle : (program >>> 0);
1867
+
1868
+ // Pack varyings as null-separated list
1869
+ const encoder = new TextEncoder();
1870
+ let totalLen = 0;
1871
+ const encoded = varyings.map(v => {
1872
+ const b = encoder.encode(v + "\0");
1873
+ totalLen += b.length;
1874
+ return b;
1875
+ });
1876
+
1877
+ const ptr = ex.wasm_alloc(totalLen);
1878
+ if (ptr === 0) throw new Error("Failed to allocate memory for transformFeedbackVaryings");
1879
+
1880
+ try {
1881
+ const mem = new Uint8Array(ex.memory.buffer);
1882
+ let offset = 0;
1883
+ for (const b of encoded) {
1884
+ mem.set(b, ptr + offset);
1885
+ offset += b.length;
1886
+ }
1887
+ const code = ex.wasm_ctx_transform_feedback_varyings(this._ctxHandle, programHandle, ptr, totalLen, bufferMode >>> 0);
1888
+ _checkErr(code, this._instance);
1889
+ } finally {
1890
+ ex.wasm_free(ptr);
1891
+ }
1892
+ }
1893
+
1894
+ getTransformFeedbackVarying(program, index) {
1895
+ this._assertNotDestroyed();
1896
+ const ex = this._instance.exports;
1897
+ if (!ex || typeof ex.wasm_ctx_get_transform_feedback_varying !== "function") {
1898
+ throw new Error("wasm_ctx_get_transform_feedback_varying not found");
1899
+ }
1900
+ const programHandle = program && typeof program === "object" && typeof program._handle === "number" ? program._handle : (program >>> 0);
1901
+
1902
+ const sizePtr = ex.wasm_alloc(4);
1903
+ const typePtr = ex.wasm_alloc(4);
1904
+ const nameCapacity = 256;
1905
+ const namePtr = ex.wasm_alloc(nameCapacity);
1906
+
1907
+ if (sizePtr === 0 || typePtr === 0 || namePtr === 0) {
1908
+ if (sizePtr) ex.wasm_free(sizePtr);
1909
+ if (typePtr) ex.wasm_free(typePtr);
1910
+ if (namePtr) ex.wasm_free(namePtr);
1911
+ throw new Error("Failed to allocate memory for getTransformFeedbackVarying");
1912
+ }
1913
+
1914
+ try {
1915
+ const code = ex.wasm_ctx_get_transform_feedback_varying(
1916
+ this._ctxHandle,
1917
+ programHandle,
1918
+ index >>> 0,
1919
+ sizePtr,
1920
+ typePtr,
1921
+ namePtr,
1922
+ nameCapacity
1923
+ );
1924
+ _checkErr(code, this._instance);
1925
+
1926
+ const mem = new DataView(ex.memory.buffer);
1927
+ const size = mem.getInt32(sizePtr, true);
1928
+ const type = mem.getUint32(typePtr, true);
1929
+
1930
+ const nameBytes = new Uint8Array(ex.memory.buffer, namePtr, nameCapacity);
1931
+ let nameLen = 0;
1932
+ while (nameLen < nameCapacity && nameBytes[nameLen] !== 0) nameLen++;
1933
+ const name = new TextDecoder().decode(nameBytes.subarray(0, nameLen));
1934
+
1935
+ return { name, size, type };
1936
+ } finally {
1937
+ ex.wasm_free(sizePtr);
1938
+ ex.wasm_free(typePtr);
1939
+ ex.wasm_free(namePtr);
1940
+ }
1941
+ }
1637
1942
 
1638
1943
  createQuery() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1639
1944
  deleteQuery(q) { this._assertNotDestroyed(); throw new Error('not implemented'); }
@@ -1807,6 +2112,46 @@ export class WasmWebGL2RenderingContext {
1807
2112
  }
1808
2113
  }
1809
2114
 
2115
+ getUniformBlockIndex(program, name) {
2116
+ this._assertNotDestroyed();
2117
+ const ex = this._instance.exports;
2118
+ if (!ex || typeof ex.wasm_ctx_get_uniform_block_index !== "function") {
2119
+ throw new Error("wasm_ctx_get_uniform_block_index not found");
2120
+ }
2121
+ const programHandle = program && typeof program === "object" && typeof program._handle === "number" ? program._handle : (program >>> 0);
2122
+ const nameStr = String(name);
2123
+ const bytes = new TextEncoder().encode(nameStr);
2124
+ const len = bytes.length;
2125
+ const ptr = ex.wasm_alloc(len);
2126
+ if (ptr === 0) throw new Error("Failed to allocate memory for getUniformBlockIndex");
2127
+
2128
+ try {
2129
+ const mem = new Uint8Array(ex.memory.buffer);
2130
+ mem.set(bytes, ptr);
2131
+ const raw = ex.wasm_ctx_get_uniform_block_index(this._ctxHandle, programHandle, ptr, len);
2132
+ const idx = raw >>> 0; // normalize to unsigned
2133
+ return idx === 0xFFFFFFFF ? 0xFFFFFFFF : idx;
2134
+ } finally {
2135
+ ex.wasm_free(ptr);
2136
+ }
2137
+ }
2138
+
2139
+ uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding) {
2140
+ this._assertNotDestroyed();
2141
+ const ex = this._instance.exports;
2142
+ if (!ex || typeof ex.wasm_ctx_uniform_block_binding !== "function") {
2143
+ throw new Error("wasm_ctx_uniform_block_binding not found");
2144
+ }
2145
+ const programHandle = program && typeof program === "object" && typeof program._handle === "number" ? program._handle : (program >>> 0);
2146
+ const code = ex.wasm_ctx_uniform_block_binding(
2147
+ this._ctxHandle,
2148
+ programHandle,
2149
+ uniformBlockIndex >>> 0,
2150
+ uniformBlockBinding >>> 0
2151
+ );
2152
+ _checkErr(code, this._instance);
2153
+ }
2154
+
1810
2155
  uniform1f(loc, x) {
1811
2156
  this._assertNotDestroyed();
1812
2157
  const ex = this._instance.exports;
@@ -1993,6 +2338,54 @@ export class WasmWebGL2RenderingContext {
1993
2338
  }
1994
2339
  }
1995
2340
 
2341
+ if (pname === 0x8CA6 /* DRAW_FRAMEBUFFER_BINDING */ || pname === 0x8CAA /* READ_FRAMEBUFFER_BINDING */) {
2342
+ const ptr = ex.wasm_alloc(4);
2343
+ try {
2344
+ const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 4);
2345
+ _checkErr(code, this._instance);
2346
+ const handle = new Int32Array(ex.memory.buffer, ptr, 1)[0];
2347
+ if (handle === 0) return null;
2348
+ return this._fbHandles.get(handle) || null;
2349
+ } finally {
2350
+ ex.wasm_free(ptr, 4);
2351
+ }
2352
+ }
2353
+
2354
+ if (pname === 0x8CA7 /* RENDERBUFFER_BINDING */) {
2355
+ const ptr = ex.wasm_alloc(4);
2356
+ try {
2357
+ const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 4);
2358
+ _checkErr(code, this._instance);
2359
+ const handle = new Int32Array(ex.memory.buffer, ptr, 1)[0];
2360
+ if (handle === 0) return null;
2361
+ return this._rbHandles.get(handle) || null;
2362
+ } finally {
2363
+ ex.wasm_free(ptr, 4);
2364
+ }
2365
+ }
2366
+
2367
+ if (pname === 0x8824 /* MAX_DRAW_BUFFERS */ || pname === 0x8CDF /* MAX_COLOR_ATTACHMENTS */) {
2368
+ const ptr = ex.wasm_alloc(4);
2369
+ try {
2370
+ const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 4);
2371
+ _checkErr(code, this._instance);
2372
+ return new Int32Array(ex.memory.buffer, ptr, 1)[0];
2373
+ } finally {
2374
+ ex.wasm_free(ptr, 4);
2375
+ }
2376
+ }
2377
+
2378
+ if (pname >= 0x8825 /* DRAW_BUFFER0 */ && pname <= 0x882C /* DRAW_BUFFER7 */) {
2379
+ const ptr = ex.wasm_alloc(4);
2380
+ try {
2381
+ const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 4);
2382
+ _checkErr(code, this._instance);
2383
+ return new Int32Array(ex.memory.buffer, ptr, 1)[0];
2384
+ } finally {
2385
+ ex.wasm_free(ptr, 4);
2386
+ }
2387
+ }
2388
+
1996
2389
  if (pname === 0x0B72 /* DEPTH_WRITEMASK */) {
1997
2390
  const ptr = ex.wasm_alloc(4);
1998
2391
  try {
@@ -2183,7 +2576,14 @@ export class WasmWebGL2RenderingContext {
2183
2576
  _checkErr(code, this._instance);
2184
2577
  }
2185
2578
 
2186
- isEnabled(cap) { this._assertNotDestroyed(); throw new Error('not implemented'); }
2579
+ isEnabled(cap) {
2580
+ this._assertNotDestroyed();
2581
+ const ex = this._instance.exports;
2582
+ if (!ex || typeof ex.wasm_ctx_is_enabled !== 'function') {
2583
+ throw new Error('wasm_ctx_is_enabled not found');
2584
+ }
2585
+ return ex.wasm_ctx_is_enabled(this._ctxHandle, cap >>> 0) !== 0;
2586
+ }
2187
2587
 
2188
2588
  viewport(x, y, width, height) {
2189
2589
  this._assertNotDestroyed();
package/webgl2.debug.wasm CHANGED
Binary file
package/webgl2.wasm CHANGED
Binary file