webgl2 1.1.18 → 1.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.
package/coverage.md CHANGED
@@ -9,42 +9,43 @@
9
9
  | src/decompiler/lifter.rs | 17 | 21 | 38 | 44.74% 🟠 |
10
10
  | src/decompiler/mod.rs | 8 | 6 | 14 | 57.14% 🟡 |
11
11
  | src/decompiler/module.rs | 1 | 1 | 2 | 50.00% 🟡 |
12
- | src/decompiler/parser.rs | 16 | 2 | 18 | 88.89% 🟢 |
13
- | src/decompiler/simplifier.rs | 56 | 18 | 74 | 75.68% 🟡 |
12
+ | src/decompiler/parser.rs | 17 | 2 | 19 | 89.47% 🟢 |
13
+ | src/decompiler/simplifier.rs | 53 | 19 | 72 | 73.61% 🟡 |
14
14
  | src/error.rs | 7 | 15 | 22 | 31.82% 🟠 |
15
- | src/lib.rs | 308 | 196 | 504 | 61.11% 🟡 |
16
- | src/naga_wasm_backend/backend.rs | 54 | 1 | 55 | 98.18% 🟢 |
17
- | src/naga_wasm_backend/call_lowering.rs | 17 | 0 | 17 | 100.00% 🟢 |
18
- | src/naga_wasm_backend/control_flow.rs | 29 | 15 | 44 | 65.91% 🟡 |
19
- | src/naga_wasm_backend/debug/stub.rs | 21 | 0 | 21 | 100.00% 🟢 |
20
- | src/naga_wasm_backend/expressions.rs | 55 | 16 | 71 | 77.46% 🟡 |
21
- | src/naga_wasm_backend/function_abi.rs | 23 | 0 | 23 | 100.00% 🟢 |
15
+ | src/lib.rs | 315 | 210 | 525 | 60.00% 🟡 |
16
+ | src/naga_wasm_backend/backend.rs | 62 | 2 | 64 | 96.88% 🟢 |
17
+ | src/naga_wasm_backend/call_lowering.rs | 18 | 0 | 18 | 100.00% 🟢 |
18
+ | src/naga_wasm_backend/control_flow.rs | 54 | 16 | 70 | 77.14% 🟡 |
19
+ | src/naga_wasm_backend/debug/stub.rs | 20 | 0 | 20 | 100.00% 🟢 |
20
+ | src/naga_wasm_backend/expressions.rs | 65 | 105 | 170 | 38.24% 🟠 |
21
+ | src/naga_wasm_backend/function_abi.rs | 22 | 0 | 22 | 100.00% 🟢 |
22
22
  | src/naga_wasm_backend/functions/prep.rs | 4 | 0 | 4 | 100.00% 🟢 |
23
- | src/naga_wasm_backend/functions/registry.rs | 4 | 0 | 4 | 100.00% 🟢 |
23
+ | src/naga_wasm_backend/functions/registry.rs | 4 | 1 | 5 | 80.00% 🟢 |
24
+ | src/naga_wasm_backend/memory_layout.rs | 9 | 0 | 9 | 100.00% 🟢 |
24
25
  | src/naga_wasm_backend/output_layout.rs | 2 | 2 | 4 | 50.00% 🟡 |
25
26
  | src/naga_wasm_backend/types.rs | 11 | 0 | 11 | 100.00% 🟢 |
26
- | src/wasm_gl_emu/framebuffer.rs | 2 | 0 | 2 | 100.00% 🟢 |
27
- | src/wasm_gl_emu/rasterizer.rs | 36 | 13 | 49 | 73.47% 🟡 |
27
+ | src/wasm_gl_emu/framebuffer.rs | 1 | 0 | 1 | 100.00% 🟢 |
28
+ | src/wasm_gl_emu/rasterizer.rs | 26 | 18 | 44 | 59.09% 🟡 |
28
29
  | src/webgl2_context/blend.rs | 2 | 1 | 3 | 66.67% 🟡 |
29
30
  | src/webgl2_context/buffers.rs | 18 | 1 | 19 | 94.74% 🟢 |
30
- | src/webgl2_context/drawing.rs | 32 | 6 | 38 | 84.21% 🟢 |
31
+ | src/webgl2_context/drawing.rs | 26 | 3 | 29 | 89.66% 🟢 |
31
32
  | src/webgl2_context/framebuffers.rs | 10 | 0 | 10 | 100.00% 🟢 |
32
- | src/webgl2_context/registry.rs | 6 | 0 | 6 | 100.00% 🟢 |
33
- | src/webgl2_context/renderbuffers.rs | 12 | 0 | 12 | 100.00% 🟢 |
34
- | src/webgl2_context/shaders.rs | 109 | 14 | 123 | 88.62% 🟢 |
35
- | src/webgl2_context/state.rs | 21 | 1 | 22 | 95.45% 🟢 |
36
- | src/webgl2_context/textures.rs | 23 | 9 | 32 | 71.88% 🟡 |
37
- | src/webgl2_context/types.rs | 10 | 1 | 11 | 90.91% 🟢 |
38
- | src/webgl2_context/vaos.rs | 36 | 0 | 36 | 100.00% 🟢 |
33
+ | src/webgl2_context/registry.rs | 7 | 0 | 7 | 100.00% 🟢 |
34
+ | src/webgl2_context/renderbuffers.rs | 11 | 0 | 11 | 100.00% 🟢 |
35
+ | src/webgl2_context/shaders.rs | 113 | 12 | 125 | 90.40% 🟢 |
36
+ | src/webgl2_context/state.rs | 23 | 1 | 24 | 95.83% 🟢 |
37
+ | src/webgl2_context/textures.rs | 28 | 17 | 45 | 62.22% 🟡 |
38
+ | src/webgl2_context/types.rs | 15 | 1 | 16 | 93.75% 🟢 |
39
+ | src/webgl2_context/vaos.rs | 35 | 0 | 35 | 100.00% 🟢 |
39
40
  | src/webgpu/adapter.rs | 3 | 0 | 3 | 100.00% 🟢 |
40
- | src/webgpu/backend.rs | 25 | 25 | 50 | 50.00% 🟡 |
41
- | **Total** | **995** | **373** | **1368** | **72.73% 🟡** |
41
+ | src/webgpu/backend.rs | 25 | 27 | 52 | 48.08% 🟠 |
42
+ | **Total** | **1049** | **490** | **1539** | **68.16% 🟡** |
42
43
 
43
44
  ## Top Missed Files
44
45
 
45
46
  | File | Lines Missed | Illustrative Line | Coverage |
46
47
  |---|---|---|---:|
47
- | src/lib.rs | 196/504 | [1040] `// ---- GLSL Decompiler Support (docs/11.b-decompile-theo...` | 61.11% 🟡 |
48
- | src/webgpu/backend.rs | 25/50 | [943] `}` | 50.00% 🟡 |
48
+ | src/lib.rs | 210/525 | [1040] `/// Get active attribute info.` | 60.00% 🟡 |
49
+ | src/naga_wasm_backend/expressions.rs | 105/170 | [1504] `for j in 0..count {` | 38.24% 🟠 |
50
+ | src/webgpu/backend.rs | 27/52 | [965] `}` | 48.08% 🟠 |
49
51
  | src/decompiler/lifter.rs | 21/38 | [455] `fn unary_op(&mut self, op: UnaryOp) {` | 44.74% 🟠 |
50
- | src/decompiler/simplifier.rs | 18/74 | [115] `let get_const = |id: &Id| egraph[*id].data.constant;` | 75.68% 🟡 |
package/daebug.md CHANGED
@@ -1,14 +1,13 @@
1
- # 👾 Daebug remote debugging REPL: SERVER SHUT DOWN 23:15:36
2
- > This debugging session has concluded.
1
+ # 👾 Daebug remote debugging REPL started 22:13:58
2
+ > Interactive debugging REPL sessions for live browser contexts
3
3
 
4
- The REPL server has been shut down. Total uptime was from 23:13:45 to 23:15:36.
4
+ This file tracks all active debugging sessions. Each entry represents a connected page or web worker where you can execute JavaScript code and see results in real-time.
5
5
 
6
6
 
7
- To begin a new debugging session:
7
+ ## Active Sessions
8
8
 
9
- ```
10
- npm start
11
- ```
9
+ * [18-quartz-2214-06-webworker](daebug/18-quartz-2214-06-webworker.md) (worker://18-quartz-2214-06-webworker) at 22:14:06: live
10
+ * [18-quartz-2214-06](daebug/18-quartz-2214-06.md) (http://localhost:8907/) at 22:14:06: live
12
11
 
13
12
 
14
13
  ## How to Use
package/index.js CHANGED
@@ -221,10 +221,10 @@ async function initWASM({ debug } = {}) {
221
221
  const bytes = mem.subarray(ptr, ptr + len);
222
222
  console.log(new TextDecoder('utf-8').decode(bytes));
223
223
  },
224
- wasm_execute_shader: (ctx, type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) => {
224
+ wasm_execute_shader: (ctx, type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) => {
225
225
  const gl = WasmWebGL2RenderingContext._contexts.get(ctx);
226
226
  if (gl) {
227
- gl._executeShader(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
227
+ gl._executeShader(type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
228
228
  } else {
229
229
  // console.log(`DEBUG: wasm_execute_shader: ctx ${ctx} not found in _contexts`);
230
230
  }
@@ -243,6 +243,20 @@ async function initWASM({ debug } = {}) {
243
243
  now: () => {
244
244
  return performance.now();
245
245
  }
246
+ },
247
+ math: {
248
+ sin: Math.sin,
249
+ cos: Math.cos,
250
+ tan: Math.tan,
251
+ asin: Math.asin,
252
+ acos: Math.acos,
253
+ atan: Math.atan,
254
+ atan2: Math.atan2,
255
+ exp: Math.exp,
256
+ exp2: (x) => Math.pow(2, x),
257
+ log: Math.log,
258
+ log2: Math.log2,
259
+ pow: Math.pow
246
260
  }
247
261
  };
248
262
  instance = await WebAssembly.instantiate(wasmModule, importObject);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webgl2",
3
- "version": "1.1.18",
3
+ "version": "1.2.0",
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",
@@ -25,6 +25,7 @@ export class WasmWebGL2RenderingContext {
25
25
  FRAGMENT_SHADER = 0x8B30;
26
26
  VERTEX_SHADER = 0x8B31;
27
27
  TRIANGLES = 0x0004;
28
+ TRIANGLE_STRIP = 0x0005;
28
29
  COLOR_BUFFER_BIT = 0x00004000;
29
30
  DEPTH_BUFFER_BIT = 0x00000100;
30
31
  DEPTH_TEST = 0x0B71;
@@ -44,7 +45,6 @@ export class WasmWebGL2RenderingContext {
44
45
  INT = 0x1404;
45
46
  UNSIGNED_INT = 0x1405;
46
47
  FLOAT = 0x1406;
47
- RGBA = 0x1908;
48
48
  FLOAT_VEC2 = 0x8B50;
49
49
  FLOAT_VEC3 = 0x8B51;
50
50
  FLOAT_VEC4 = 0x8B52;
@@ -59,6 +59,7 @@ export class WasmWebGL2RenderingContext {
59
59
  FLOAT_MAT3 = 0x8B5B;
60
60
  FLOAT_MAT4 = 0x8B5C;
61
61
  SAMPLER_2D = 0x8B5E;
62
+ SAMPLER_3D = 0x8B5F;
62
63
  SAMPLER_CUBE = 0x8B60;
63
64
  ACTIVE_UNIFORMS = 0x8B86;
64
65
  ACTIVE_ATTRIBUTES = 0x8B89;
@@ -141,10 +142,18 @@ export class WasmWebGL2RenderingContext {
141
142
  FRONT_AND_BACK = 0x0408;
142
143
 
143
144
  TEXTURE_2D = 0x0DE1;
145
+ TEXTURE_3D = 0x806F;
146
+ TEXTURE_2D_ARRAY = 0x8C1A;
144
147
  TEXTURE_WRAP_S = 0x2802;
145
148
  TEXTURE_WRAP_T = 0x2803;
149
+ TEXTURE_WRAP_R = 0x8072;
146
150
  TEXTURE_MAG_FILTER = 0x2800;
147
151
  TEXTURE_MIN_FILTER = 0x2801;
152
+ RGBA = 0x1908;
153
+ RED = 0x1903;
154
+ RG = 0x8227;
155
+ UNSIGNED_BYTE = 0x1401;
156
+ FLOAT = 0x1406;
148
157
  NEAREST = 0x2600;
149
158
  LINEAR = 0x2601;
150
159
  NEAREST_MIPMAP_NEAREST = 0x2700;
@@ -212,14 +221,23 @@ export class WasmWebGL2RenderingContext {
212
221
  /** @type {Map<number, WasmWebGL2RenderingContext>} */
213
222
  static _contexts = new Map();
214
223
 
215
- _executeShader(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
224
+ _executeShader(type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
216
225
  if (!this._currentProgram) {
217
226
  return;
218
227
  }
228
+
229
+ if (tableIdx > 0 && this._sharedTable) {
230
+ const func = this._sharedTable.get(tableIdx);
231
+ if (func) {
232
+ func(this._ctxHandle, type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
233
+ return;
234
+ }
235
+ }
236
+
219
237
  const shaderInstance = type === this.VERTEX_SHADER ? this._currentProgram._vsInstance : this._currentProgram._fsInstance;
220
238
  if (shaderInstance && shaderInstance.exports.main) {
221
239
  // @ts-ignore
222
- shaderInstance.exports.main(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
240
+ shaderInstance.exports.main(this._ctxHandle, type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
223
241
  }
224
242
  }
225
243
 
@@ -292,8 +310,13 @@ export class WasmWebGL2RenderingContext {
292
310
  }
293
311
 
294
312
  let data = pixels;
295
- if (!data) data = new Uint8Array(width * height * 4);
296
- else if (!(data instanceof Uint8Array)) data = new Uint8Array(data);
313
+ if (!data) {
314
+ data = new Uint8Array(width * height * 4);
315
+ } else if (ArrayBuffer.isView(data)) {
316
+ data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
317
+ } else if (data instanceof ArrayBuffer) {
318
+ data = new Uint8Array(data);
319
+ }
297
320
 
298
321
  const len = data.length;
299
322
  const ptr = ex.wasm_alloc(len);
@@ -328,6 +351,56 @@ export class WasmWebGL2RenderingContext {
328
351
  }
329
352
  }
330
353
 
354
+ texImage3D(target, level, internalFormat, width, height, depth, border, format, type_, pixels) {
355
+ this._assertNotDestroyed();
356
+ const ex = this._instance.exports;
357
+ if (!ex || typeof ex.wasm_ctx_tex_image_3d !== 'function') {
358
+ throw new Error('wasm_ctx_tex_image_3d not found');
359
+ }
360
+
361
+ let data = pixels;
362
+ if (!data) {
363
+ data = new Uint8Array(width * height * depth * 4);
364
+ } else if (ArrayBuffer.isView(data)) {
365
+ data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
366
+ } else if (data instanceof ArrayBuffer) {
367
+ data = new Uint8Array(data);
368
+ }
369
+
370
+ const len = data.length;
371
+ const ptr = ex.wasm_alloc(len);
372
+ if (ptr === 0) throw new Error('Failed to allocate memory for pixel data');
373
+
374
+ try {
375
+ const mem = new Uint8Array(ex.memory.buffer);
376
+ mem.set(data, ptr);
377
+
378
+ const code = ex.wasm_ctx_tex_image_3d(
379
+ this._ctxHandle,
380
+ target >>> 0,
381
+ level >>> 0,
382
+ internalFormat >>> 0,
383
+ width >>> 0,
384
+ height >>> 0,
385
+ depth >>> 0,
386
+ border >>> 0,
387
+ format >>> 0,
388
+ type_ >>> 0,
389
+ ptr >>> 0,
390
+ len >>> 0
391
+ );
392
+ _checkErr(code, this._instance);
393
+
394
+ // Mirror texture data in JS for fast texel fetches by shader imports
395
+ this._textureData = this._textureData || new Map();
396
+ const handle = this._boundTexture || 0;
397
+ const copy = new Uint8Array(mem.slice(ptr, ptr + len));
398
+ this._textureData.set(handle, { width: width >>> 0, height: height >>> 0, depth: depth >>> 0, data: copy });
399
+ } finally {
400
+ ex.wasm_free(ptr);
401
+ }
402
+ }
403
+
331
404
  copyTexImage2D(target, level, internalFormat, x, y, width, height, border) {
332
405
  this._assertNotDestroyed();
333
406
  const ex = this._instance.exports;
@@ -478,9 +551,18 @@ export class WasmWebGL2RenderingContext {
478
551
  throw new Error('wasm_ctx_read_pixels not found');
479
552
  }
480
553
 
481
- const len = width * height * 4;
482
- if (!out || out.length < len) {
483
- throw new Error(`output buffer too small (need ${len}, have ${out ? out.length : 0})`);
554
+ let bpp = 4;
555
+ if (type_ === 0x1406) { // GL_FLOAT
556
+ if (format === 0x1908) bpp = 16; // GL_RGBA
557
+ else if (format === 0x8227) bpp = 8; // GL_RG
558
+ else if (format === 0x1903) bpp = 4; // GL_RED
559
+ } else if (type_ === 0x1401) { // GL_UNSIGNED_BYTE
560
+ if (format === 0x1908) bpp = 4;
561
+ }
562
+
563
+ const len = width * height * bpp;
564
+ if (!out || out.byteLength < len) {
565
+ throw new Error(`output buffer too small (need ${len} bytes, have ${out ? out.byteLength : 0})`);
484
566
  }
485
567
 
486
568
  const ptr = ex.wasm_alloc(len);
@@ -489,8 +571,8 @@ export class WasmWebGL2RenderingContext {
489
571
  try {
490
572
  const code = ex.wasm_ctx_read_pixels(
491
573
  this._ctxHandle,
492
- x >>> 0,
493
- y >>> 0,
574
+ x | 0,
575
+ y | 0,
494
576
  width >>> 0,
495
577
  height >>> 0,
496
578
  format >>> 0,
@@ -502,7 +584,8 @@ export class WasmWebGL2RenderingContext {
502
584
 
503
585
  const mem = new Uint8Array(ex.memory.buffer);
504
586
  const src = mem.subarray(ptr, ptr + len);
505
- out.set(src);
587
+ const out_bytes = new Uint8Array(out.buffer, out.byteOffset, len);
588
+ out_bytes.set(src);
506
589
  } finally {
507
590
  ex.wasm_free(ptr);
508
591
  }
@@ -708,9 +791,6 @@ export class WasmWebGL2RenderingContext {
708
791
  _checkErr(code, this._instance);
709
792
 
710
793
  // After linking, we need to instantiate the WASM modules on the host.
711
- // According to the WebGL 2.0 Spec (https://registry.khronos.org/webgl/specs/latest/2.0/#3.7.6),
712
- // linkProgram sets the LINK_STATUS parameter. If linking fails, no executable is generated.
713
- // We must check LINK_STATUS before attempting to instantiate the WASM, as getProgramWasm will return null.
714
794
  if (program && typeof program === 'object') {
715
795
  const linkStatus = this.getProgramParameter(program, this.LINK_STATUS);
716
796
  if (linkStatus) {
@@ -723,6 +803,10 @@ export class WasmWebGL2RenderingContext {
723
803
  const vsWasm = this.getProgramWasm(program, this.VERTEX_SHADER);
724
804
  const fsWasm = this.getProgramWasm(program, this.FRAGMENT_SHADER);
725
805
 
806
+ if (!vsWasm || !fsWasm) {
807
+ return;
808
+ }
809
+
726
810
  // Allocate table slots for both shaders
727
811
  const vsIdx = this._tableAllocator ? this._tableAllocator.allocate() : null;
728
812
  const fsIdx = this._tableAllocator ? this._tableAllocator.allocate() : null;
@@ -749,7 +833,6 @@ export class WasmWebGL2RenderingContext {
749
833
  return {
750
834
  debug_step: (line, funcIdx, resultPtr) => {
751
835
  if (line === 999999) {
752
- console.log(`DEBUG LOG: val=${funcIdx} (0x${(funcIdx >>> 0).toString(16)})`);
753
836
  return;
754
837
  }
755
838
  const func = stubFuncs[line - 1];
@@ -775,13 +858,26 @@ export class WasmWebGL2RenderingContext {
775
858
  const vsInstanceRef = { current: null };
776
859
  const vsDebugEnv = createDebugEnv(this.VERTEX_SHADER, vsInstanceRef);
777
860
 
861
+ const env = {
862
+ memory: this._instance.exports.memory,
863
+ __indirect_function_table: this._sharedTable,
864
+ ...vsDebugEnv
865
+ };
778
866
 
779
- program._vsInstance = new WebAssembly.Instance(vsModule, {
780
- env: {
781
- memory: this._instance.exports.memory,
782
- __indirect_function_table: this._sharedTable,
783
- ...vsDebugEnv
867
+ // Add math builtins from renderer (skipping host)
868
+ const mathFuncs = [
869
+ 'gl_sin', 'gl_cos', 'gl_tan', 'gl_asin', 'gl_acos', 'gl_atan', 'gl_atan2',
870
+ 'gl_exp', 'gl_exp2', 'gl_log', 'gl_log2', 'gl_pow',
871
+ 'gl_sinh', 'gl_cosh', 'gl_tanh', 'gl_asinh', 'gl_acosh', 'gl_atanh'
872
+ ];
873
+ for (const name of mathFuncs) {
874
+ if (this._instance.exports[name]) {
875
+ env[name] = this._instance.exports[name];
784
876
  }
877
+ }
878
+
879
+ program._vsInstance = new WebAssembly.Instance(vsModule, {
880
+ env
785
881
  });
786
882
  vsInstanceRef.current = program._vsInstance;
787
883
 
@@ -796,13 +892,20 @@ export class WasmWebGL2RenderingContext {
796
892
  const fsInstanceRef = { current: null };
797
893
  const fsDebugEnv = createDebugEnv(this.FRAGMENT_SHADER, fsInstanceRef);
798
894
 
895
+ const fsEnv = {
896
+ memory: this._instance.exports.memory,
897
+ __indirect_function_table: this._sharedTable,
898
+ ...fsDebugEnv
899
+ };
799
900
 
800
- program._fsInstance = new WebAssembly.Instance(fsModule, {
801
- env: {
802
- memory: this._instance.exports.memory,
803
- __indirect_function_table: this._sharedTable,
804
- ...fsDebugEnv
901
+ for (const name of mathFuncs) {
902
+ if (this._instance.exports[name]) {
903
+ fsEnv[name] = this._instance.exports[name];
805
904
  }
905
+ }
906
+
907
+ program._fsInstance = new WebAssembly.Instance(fsModule, {
908
+ env: fsEnv
806
909
  });
807
910
  fsInstanceRef.current = program._fsInstance;
808
911
 
@@ -879,7 +982,7 @@ export class WasmWebGL2RenderingContext {
879
982
  throw new Error('wasm_ctx_delete_program not found');
880
983
  }
881
984
  const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
882
-
985
+
883
986
  // Free table indices
884
987
  if (program && typeof program === 'object') {
885
988
  if (program._vsTableIndex !== undefined && this._tableAllocator) {
@@ -889,7 +992,7 @@ export class WasmWebGL2RenderingContext {
889
992
  this._tableAllocator.free(program._fsTableIndex);
890
993
  }
891
994
  }
892
-
995
+
893
996
  const code = ex.wasm_ctx_delete_program(this._ctxHandle, programHandle);
894
997
  _checkErr(code, this._instance);
895
998
  if (program && typeof program === 'object') {
@@ -1087,6 +1190,7 @@ export class WasmWebGL2RenderingContext {
1087
1190
  stride >>> 0,
1088
1191
  offset >>> 0
1089
1192
  );
1193
+ if (code === 5) return; // ERR_GL
1090
1194
  _checkErr(code, this._instance);
1091
1195
  }
1092
1196
 
@@ -1104,6 +1208,7 @@ export class WasmWebGL2RenderingContext {
1104
1208
  stride >>> 0,
1105
1209
  offset >>> 0
1106
1210
  );
1211
+ if (code === 5) return; // ERR_GL
1107
1212
  _checkErr(code, this._instance);
1108
1213
  }
1109
1214
 
@@ -1282,6 +1387,12 @@ export class WasmWebGL2RenderingContext {
1282
1387
  }
1283
1388
 
1284
1389
  const len = bytes.length;
1390
+ if (len === 0) {
1391
+ const code = ex.wasm_ctx_buffer_data(this._ctxHandle, target >>> 0, 0, 0, usage >>> 0);
1392
+ _checkErr(code, this._instance);
1393
+ return;
1394
+ }
1395
+
1285
1396
  const ptr = ex.wasm_alloc(len);
1286
1397
  if (ptr === 0) throw new Error('Failed to allocate memory for bufferData');
1287
1398
 
@@ -1508,7 +1619,49 @@ export class WasmWebGL2RenderingContext {
1508
1619
  _checkErr(code, this._instance);
1509
1620
  }
1510
1621
  copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1511
- texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1622
+ texSubImage2D(target, level, xoffset, yoffset, width, height, format, type_, pixels) {
1623
+ this._assertNotDestroyed();
1624
+ const ex = this._instance.exports;
1625
+ if (!ex || typeof ex.wasm_ctx_tex_sub_image_2d !== 'function') {
1626
+ throw new Error('wasm_ctx_tex_sub_image_2d not found');
1627
+ }
1628
+
1629
+ let data = pixels;
1630
+ if (!data) return; // No-op if no data provided
1631
+ if (!(data instanceof Uint8Array)) {
1632
+ if (ArrayBuffer.isView(data)) {
1633
+ data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1634
+ } else {
1635
+ data = new Uint8Array(data);
1636
+ }
1637
+ }
1638
+
1639
+ const len = data.length;
1640
+ const ptr = ex.wasm_alloc(len);
1641
+ if (ptr === 0) throw new Error('Failed to allocate memory for sub-pixel data');
1642
+
1643
+ try {
1644
+ const mem = new Uint8Array(ex.memory.buffer);
1645
+ mem.set(data, ptr);
1646
+
1647
+ const code = ex.wasm_ctx_tex_sub_image_2d(
1648
+ this._ctxHandle,
1649
+ target >>> 0,
1650
+ level >>> 0,
1651
+ xoffset | 0,
1652
+ yoffset | 0,
1653
+ width >>> 0,
1654
+ height >>> 0,
1655
+ format >>> 0,
1656
+ type_ >>> 0,
1657
+ ptr >>> 0,
1658
+ len >>> 0
1659
+ );
1660
+ _checkErr(code, this._instance);
1661
+ } finally {
1662
+ ex.wasm_free(ptr);
1663
+ }
1664
+ }
1512
1665
 
1513
1666
  checkFramebufferStatus(target) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1514
1667
  blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) { this._assertNotDestroyed(); throw new Error('not implemented'); }
package/webgl2.debug.wasm CHANGED
Binary file
package/webgl2.wasm CHANGED
Binary file