webgl2 1.2.3 → 1.2.5

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,49 +4,48 @@
4
4
 
5
5
  | File | Lines Covered | Lines Missed | Total Lines | Coverage |
6
6
  |---|---|---|---|---:|
7
- | src/coverage.rs | 22 | 1 | 23 | 95.65% 🟢 |
7
+ | src/coverage.rs | 4 | 1 | 5 | 80.00% 🟢 |
8
8
  | src/decompiler/ast.rs | 4 | 0 | 4 | 100.00% 🟢 |
9
- | src/decompiler/emitter.rs | 19 | 4 | 23 | 82.61% 🟢 |
10
- | src/decompiler/lifter.rs | 19 | 10 | 29 | 65.52% 🟡 |
11
- | src/decompiler/mod.rs | 19 | 2 | 21 | 90.48% 🟢 |
12
- | src/decompiler/module.rs | 1 | 0 | 1 | 100.00% 🟢 |
13
- | src/decompiler/parser.rs | 9 | 10 | 19 | 47.37% 🟠 |
14
- | src/decompiler/simplifier.rs | 35 | 1 | 36 | 97.22% 🟢 |
15
- | src/error.rs | 35 | 4 | 39 | 89.74% 🟢 |
16
- | src/lib.rs | 109 | 310 | 419 | 26.01% 🟠 |
17
- | src/naga_wasm_backend/backend.rs | 107 | 9 | 116 | 92.24% 🟢 |
18
- | src/naga_wasm_backend/call_lowering.rs | 30 | 2 | 32 | 93.75% 🟢 |
19
- | src/naga_wasm_backend/control_flow.rs | 37 | 42 | 79 | 46.84% 🟠 |
20
- | src/naga_wasm_backend/debug/stub.rs | 10 | 0 | 10 | 100.00% 🟢 |
21
- | src/naga_wasm_backend/expressions.rs | 157 | 121 | 278 | 56.47% 🟡 |
22
- | src/naga_wasm_backend/function_abi.rs | 5 | 8 | 13 | 38.46% 🟠 |
23
- | src/naga_wasm_backend/functions/prep.rs | 10 | 0 | 10 | 100.00% 🟢 |
24
- | src/naga_wasm_backend/memory_layout.rs | 4 | 0 | 4 | 100.00% 🟢 |
25
- | src/naga_wasm_backend/mod.rs | 7 | 2 | 9 | 77.78% 🟡 |
9
+ | src/decompiler/emitter.rs | 17 | 4 | 21 | 80.95% 🟢 |
10
+ | src/decompiler/lifter.rs | 7 | 1 | 8 | 87.50% 🟢 |
11
+ | src/decompiler/mod.rs | 4 | 0 | 4 | 100.00% 🟢 |
12
+ | src/decompiler/module.rs | 0 | 2 | 2 | 0.00% 🟡 |
13
+ | src/decompiler/parser.rs | 24 | 2 | 26 | 92.31% 🟢 |
14
+ | src/decompiler/simplifier.rs | 34 | 0 | 34 | 100.00% 🟢 |
15
+ | src/error.rs | 31 | 4 | 35 | 88.57% 🟢 |
16
+ | src/lib.rs | 84 | 325 | 409 | 20.54% 🟠 |
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 | 120 | 151 | 271 | 44.28% 🟠 |
22
+ | src/naga_wasm_backend/function_abi.rs | 28 | 11 | 39 | 71.79% 🟡 |
23
+ | src/naga_wasm_backend/functions/prep.rs | 6 | 3 | 9 | 66.67% 🟡 |
24
+ | src/naga_wasm_backend/functions/registry.rs | 3 | 0 | 3 | 100.00% 🟢 |
25
+ | src/naga_wasm_backend/mod.rs | 5 | 1 | 6 | 83.33% 🟢 |
26
26
  | src/naga_wasm_backend/output_layout.rs | 10 | 1 | 11 | 90.91% 🟢 |
27
- | src/naga_wasm_backend/types.rs | 6 | 1 | 7 | 85.71% 🟢 |
28
- | src/wasm_gl_emu/device.rs | 32 | 4 | 36 | 88.89% 🟢 |
29
- | src/wasm_gl_emu/framebuffer.rs | 3 | 3 | 6 | 50.00% 🟡 |
30
- | src/wasm_gl_emu/rasterizer.rs | 17 | 46 | 63 | 26.98% 🟠 |
31
- | src/wasm_gl_emu/transfer.rs | 13 | 44 | 57 | 22.81% 🟠 |
32
- | src/webgl2_context/drawing.rs | 1 | 1 | 2 | 50.00% 🟡 |
33
- | src/webgl2_context/registry.rs | 9 | 1 | 10 | 90.00% 🟢 |
34
- | src/webgl2_context/shaders.rs | 164 | 17 | 181 | 90.61% 🟢 |
35
- | src/webgl2_context/state.rs | 58 | 6 | 64 | 90.63% 🟢 |
36
- | src/webgl2_context/textures.rs | 11 | 0 | 11 | 100.00% 🟢 |
37
- | src/webgl2_context/types.rs | 45 | 20 | 65 | 69.23% 🟡 |
38
- | src/webgpu/adapter.rs | 4 | 5 | 9 | 44.44% 🟠 |
39
- | src/webgpu/backend.rs | 106 | 25 | 131 | 80.92% 🟢 |
40
- | src/webgpu/buffer.rs | 3 | 2 | 5 | 60.00% 🟡 |
41
- | src/webgpu/command.rs | 4 | 1 | 5 | 80.00% 🟢 |
42
- | src/webgpu/shader.rs | 7 | 0 | 7 | 100.00% 🟢 |
43
- | **Total** | **1132** | **703** | **1835** | **61.69% 🟡** |
27
+ | src/naga_wasm_backend/types.rs | 19 | 3 | 22 | 86.36% 🟢 |
28
+ | src/wasm_gl_emu/device.rs | 2 | 0 | 2 | 100.00% 🟢 |
29
+ | src/wasm_gl_emu/framebuffer.rs | 3 | 0 | 3 | 100.00% 🟢 |
30
+ | src/wasm_gl_emu/transfer.rs | 10 | 13 | 23 | 43.48% 🟠 |
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 | 180 | 33 | 213 | 84.51% 🟢 |
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 | 0 | 11 | 100.00% 🟢 |
38
+ | src/webgpu/adapter.rs | 7 | 0 | 7 | 100.00% 🟢 |
39
+ | src/webgpu/backend.rs | 115 | 33 | 148 | 77.70% 🟡 |
40
+ | src/webgpu/command.rs | 3 | 0 | 3 | 100.00% 🟢 |
41
+ | src/webgpu/pipeline.rs | 2 | 1 | 3 | 66.67% 🟡 |
42
+ | **Total** | **1049** | **688** | **1737** | **60.39% 🟡** |
44
43
 
45
44
  ## Top Missed Files
46
45
 
47
46
  | File | Lines Missed | Illustrative Line | Coverage |
48
47
  |---|---|---|---:|
49
- | src/lib.rs | 310/419 | [1994] `data_ptr: *const u8,` | 26.01% 🟠 |
50
- | src/naga_wasm_backend/expressions.rs | 121/278 | [33] `let expr = &ctx.module.global_expressions[expr_handle];` | 56.47% 🟡 |
51
- | src/wasm_gl_emu/rasterizer.rs | 46/63 | [1015] `if state.color_mask.r {` | 26.98% 🟠 |
52
- | src/wasm_gl_emu/transfer.rs | 44/57 | [387] `dest[dst_off] = (r5 << 3) | (r5 >> 2);` | 22.81% 🟠 |
48
+ | src/lib.rs | 325/409 | [1994] `) -> u32 {` | 20.54% 🟠 |
49
+ | src/naga_wasm_backend/expressions.rs | 151/271 | [1500] `ctx.wasm_func.instruction(&Instruction::LocalTee(temp_a));` | 44.28% 🟠 |
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.3",
3
+ "version": "1.2.5",
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;
@@ -172,9 +243,9 @@ export class WasmWebGL2RenderingContext {
172
243
  RGB32I = 0x8D83;
173
244
  RGBA32I = 0x8D82;
174
245
  RED_INTEGER = 0x8D94;
175
- RG_INTEGER = 0x8D95;
176
- RGB_INTEGER = 0x8D96;
177
- RGBA_INTEGER = 0x8D99;
246
+ RG_INTEGER = 0x8228;
247
+ RGB_INTEGER = 0x8D98;
248
+ RGBA_INTEGER = 0x8D9E;
178
249
  R32F = 0x822E;
179
250
  RG32F = 0x8230;
180
251
  R16F = 0x822D;
@@ -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) {
@@ -608,6 +714,10 @@ export class WasmWebGL2RenderingContext {
608
714
  if (format === 0x1908) bpp = 16; // GL_RGBA
609
715
  else if (format === 0x8227) bpp = 8; // GL_RG
610
716
  else if (format === 0x1903) bpp = 4; // GL_RED
717
+ } else if (type_ === 0x1405 || type_ === 0x1404) { // GL_UNSIGNED_INT or GL_INT
718
+ if (format === 0x8D9E) bpp = 16; // GL_RGBA_INTEGER
719
+ else if (format === 0x8228) bpp = 8; // GL_RG_INTEGER
720
+ else if (format === 0x8D94) bpp = 4; // GL_RED_INTEGER
611
721
  } else if (type_ === 0x1401) { // GL_UNSIGNED_BYTE
612
722
  if (format === 0x1908) bpp = 4;
613
723
  }
@@ -1376,7 +1486,9 @@ export class WasmWebGL2RenderingContext {
1376
1486
  const msg = readErrorMessage(this._instance);
1377
1487
  throw new Error(`Failed to create buffer: ${msg}`);
1378
1488
  }
1379
- return new WasmWebGLBuffer(this, handle);
1489
+ const buf = new WasmWebGLBuffer(this, handle);
1490
+ this._bufferHandles.set(handle, buf);
1491
+ return buf;
1380
1492
  }
1381
1493
 
1382
1494
  bindBuffer(target, buffer) {
@@ -1390,6 +1502,35 @@ export class WasmWebGL2RenderingContext {
1390
1502
  _checkErr(code, this._instance);
1391
1503
  }
1392
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
+
1393
1534
  deleteBuffer(buffer) {
1394
1535
  this._assertNotDestroyed();
1395
1536
  const ex = this._instance.exports;
@@ -1398,7 +1539,9 @@ export class WasmWebGL2RenderingContext {
1398
1539
  }
1399
1540
  const handle = buffer && typeof buffer === 'object' && typeof buffer._handle === 'number' ? buffer._handle : (buffer >>> 0);
1400
1541
  const code = ex.wasm_ctx_delete_buffer(this._ctxHandle, handle);
1401
- _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') {
1402
1545
  try { buffer._handle = 0; buffer._deleted = true; } catch (e) { /* ignore */ }
1403
1546
  }
1404
1547
  }
@@ -1622,14 +1765,180 @@ export class WasmWebGL2RenderingContext {
1622
1765
  return res !== 0;
1623
1766
  }
1624
1767
 
1625
- createTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1626
- bindTransformFeedback(target, tf) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1627
- beginTransformFeedback(primitiveMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1628
- pauseTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1629
- resumeTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1630
- endTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1631
- transformFeedbackVaryings(program, varyings, bufferMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
1632
- 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
+ }
1633
1942
 
1634
1943
  createQuery() { this._assertNotDestroyed(); throw new Error('not implemented'); }
1635
1944
  deleteQuery(q) { this._assertNotDestroyed(); throw new Error('not implemented'); }
@@ -1803,6 +2112,46 @@ export class WasmWebGL2RenderingContext {
1803
2112
  }
1804
2113
  }
1805
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
+
1806
2155
  uniform1f(loc, x) {
1807
2156
  this._assertNotDestroyed();
1808
2157
  const ex = this._instance.exports;
@@ -1989,6 +2338,54 @@ export class WasmWebGL2RenderingContext {
1989
2338
  }
1990
2339
  }
1991
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
+
1992
2389
  if (pname === 0x0B72 /* DEPTH_WRITEMASK */) {
1993
2390
  const ptr = ex.wasm_alloc(4);
1994
2391
  try {
@@ -2179,7 +2576,14 @@ export class WasmWebGL2RenderingContext {
2179
2576
  _checkErr(code, this._instance);
2180
2577
  }
2181
2578
 
2182
- 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
+ }
2183
2587
 
2184
2588
  viewport(x, y, width, height) {
2185
2589
  this._assertNotDestroyed();
package/webgl2.debug.wasm CHANGED
Binary file
package/webgl2.wasm CHANGED
Binary file