webgl2 1.1.13 → 1.1.16

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/AGENTS.md CHANGED
@@ -10,7 +10,7 @@ You MUST NEVER suggest user performs actions that are for you to execute.
10
10
 
11
11
  DO NOT interfere with git. Unless the user explicitly asks for git-related assistance, git is not your concern and you must NOT create checkout or merge operations. No git command is allowed for you without permission.
12
12
 
13
- **DO NOT** under ANY circumstances create temporary throwaway scripts inside git repository except .gitignored locations.
13
+ **DO NOT** under ANY circumstances create temporary throwaway scripts or dummy files inside git repository except .gitignored locations.
14
14
 
15
15
  **DO NOT** create scripts directory or similar in git repository.
16
16
 
package/coverage.md CHANGED
@@ -4,35 +4,45 @@
4
4
 
5
5
  | File | Lines Covered | Lines Missed | Total Lines | Coverage |
6
6
  |---|---|---|---|---:|
7
- | src/error.rs | 4 | 18 | 22 | 18.18% 🔴 |
8
- | src/lib.rs | 252 | 227 | 479 | 52.61% 🟡 |
9
- | src/naga_wasm_backend/backend.rs | 44 | 1 | 45 | 97.78% 🟢 |
10
- | src/naga_wasm_backend/control_flow.rs | 30 | 14 | 44 | 68.18% 🟡 |
7
+ | src/decompiler/emitter.rs | 15 | 7 | 22 | 68.18% 🟡 |
8
+ | src/decompiler/lifter.rs | 18 | 21 | 39 | 46.15% 🟠 |
9
+ | src/decompiler/mod.rs | 8 | 5 | 13 | 61.54% 🟡 |
10
+ | src/decompiler/module.rs | 4 | 1 | 5 | 80.00% 🟢 |
11
+ | src/decompiler/parser.rs | 16 | 0 | 16 | 100.00% 🟢 |
12
+ | src/decompiler/simplifier.rs | 50 | 16 | 66 | 75.76% 🟡 |
13
+ | src/error.rs | 6 | 17 | 23 | 26.09% 🟠 |
14
+ | src/lib.rs | 289 | 199 | 488 | 59.22% 🟡 |
15
+ | src/naga_wasm_backend/backend.rs | 54 | 1 | 55 | 98.18% 🟢 |
16
+ | src/naga_wasm_backend/call_lowering.rs | 9 | 0 | 9 | 100.00% 🟢 |
17
+ | src/naga_wasm_backend/control_flow.rs | 29 | 15 | 44 | 65.91% 🟡 |
11
18
  | src/naga_wasm_backend/debug/stub.rs | 21 | 0 | 21 | 100.00% 🟢 |
12
- | src/naga_wasm_backend/expressions.rs | 43 | 23 | 66 | 65.15% 🟡 |
19
+ | src/naga_wasm_backend/expressions.rs | 55 | 16 | 71 | 77.46% 🟡 |
20
+ | src/naga_wasm_backend/function_abi.rs | 23 | 0 | 23 | 100.00% 🟢 |
21
+ | src/naga_wasm_backend/functions/prep.rs | 4 | 0 | 4 | 100.00% 🟢 |
22
+ | src/naga_wasm_backend/functions/registry.rs | 4 | 0 | 4 | 100.00% 🟢 |
13
23
  | src/naga_wasm_backend/output_layout.rs | 2 | 2 | 4 | 50.00% 🟡 |
14
- | src/naga_wasm_backend/types.rs | 6 | 1 | 7 | 85.71% 🟢 |
24
+ | src/naga_wasm_backend/types.rs | 6 | 0 | 6 | 100.00% 🟢 |
15
25
  | src/wasm_gl_emu/framebuffer.rs | 1 | 0 | 1 | 100.00% 🟢 |
16
26
  | src/wasm_gl_emu/rasterizer.rs | 14 | 0 | 14 | 100.00% 🟢 |
17
27
  | src/webgl2_context/buffers.rs | 16 | 1 | 17 | 94.12% 🟢 |
18
- | src/webgl2_context/drawing.rs | 30 | 6 | 36 | 83.33% 🟢 |
28
+ | src/webgl2_context/drawing.rs | 31 | 6 | 37 | 83.78% 🟢 |
19
29
  | src/webgl2_context/framebuffers.rs | 8 | 0 | 8 | 100.00% 🟢 |
20
- | src/webgl2_context/registry.rs | 6 | 1 | 7 | 85.71% 🟢 |
30
+ | src/webgl2_context/registry.rs | 6 | 0 | 6 | 100.00% 🟢 |
21
31
  | src/webgl2_context/renderbuffers.rs | 10 | 0 | 10 | 100.00% 🟢 |
22
- | src/webgl2_context/shaders.rs | 87 | 15 | 102 | 85.29% 🟢 |
32
+ | src/webgl2_context/shaders.rs | 87 | 14 | 101 | 86.14% 🟢 |
23
33
  | src/webgl2_context/state.rs | 14 | 1 | 15 | 93.33% 🟢 |
24
34
  | src/webgl2_context/textures.rs | 10 | 0 | 10 | 100.00% 🟢 |
25
35
  | src/webgl2_context/types.rs | 9 | 1 | 10 | 90.00% 🟢 |
26
- | src/webgl2_context/vaos.rs | 37 | 0 | 37 | 100.00% 🟢 |
27
- | src/webgpu/adapter.rs | 2 | 0 | 2 | 100.00% 🟢 |
36
+ | src/webgl2_context/vaos.rs | 36 | 0 | 36 | 100.00% 🟢 |
37
+ | src/webgpu/adapter.rs | 2 | 1 | 3 | 66.67% 🟡 |
28
38
  | src/webgpu/backend.rs | 25 | 25 | 50 | 50.00% 🟡 |
29
- | **Total** | **671** | **336** | **1007** | **66.63% 🟡** |
39
+ | **Total** | **882** | **349** | **1231** | **71.65% 🟡** |
30
40
 
31
41
  ## Top Missed Files
32
42
 
33
43
  | File | Lines Missed | Illustrative Line | Coverage |
34
44
  |---|---|---|---:|
35
- | src/lib.rs | 227/479 | [1033] `};` | 52.61% 🟡 |
45
+ | src/lib.rs | 199/488 | [1042] `}` | 59.22% 🟡 |
36
46
  | src/webgpu/backend.rs | 25/50 | [919] `}` | 50.00% 🟡 |
37
- | src/naga_wasm_backend/expressions.rs | 23/66 | [941] `let var = &ctx.module.global_variables[*handle];` | 65.15% 🟡 |
38
- | src/error.rs | 18/22 | [52] `pub fn set_error(source: ErrorSource, code: u32, msg: imp...` | 18.18% 🔴 |
47
+ | src/decompiler/lifter.rs | 21/39 | [455] `fn unary_op(&mut self, op: UnaryOp) {` | 46.15% 🟠 |
48
+ | src/error.rs | 17/23 | [52] `pub fn set_error(source: ErrorSource, code: u32, msg: imp...` | 26.09% 🟠 |
package/index.js CHANGED
@@ -6,7 +6,9 @@ import {
6
6
  ERR_INVALID_HANDLE,
7
7
  readErrorMessage,
8
8
  getShaderModule,
9
- getShaderWat
9
+ getShaderWat,
10
+ getShaderGlsl,
11
+ decompileWasmToGlsl
10
12
  } from './src/webgl2_context.js';
11
13
  import { GPU, GPUBufferUsage, GPUMapMode, GPUTextureUsage } from './src/webgpu_context.js';
12
14
 
@@ -15,7 +17,7 @@ export const debug = {
15
17
  resetLcovReport
16
18
  };
17
19
 
18
- export { ERR_OK, ERR_INVALID_HANDLE, GPUBufferUsage, GPUMapMode, GPUTextureUsage, getShaderModule, getShaderWat };
20
+ export { ERR_OK, ERR_INVALID_HANDLE, GPUBufferUsage, GPUMapMode, GPUTextureUsage, getShaderModule, getShaderWat, getShaderGlsl, decompileWasmToGlsl };
19
21
 
20
22
  /**
21
23
  * WebGL2 Prototype: Rust-owned Context, JS thin-forwarder
@@ -194,6 +196,10 @@ async function initWASM({ debug } = {}) {
194
196
  } else {
195
197
  console.error("GPU.dispatchUncapturedError not available", msg);
196
198
  }
199
+ },
200
+ // Required by egg crate for timing measurements
201
+ now: () => {
202
+ return performance.now();
197
203
  }
198
204
  }
199
205
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webgl2",
3
- "version": "1.1.13",
3
+ "version": "1.1.16",
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",
@@ -155,14 +155,8 @@ export class WasmWebGL2RenderingContext {
155
155
  }
156
156
  const shaderInstance = type === this.VERTEX_SHADER ? this._currentProgram._vsInstance : this._currentProgram._fsInstance;
157
157
  if (shaderInstance && shaderInstance.exports.main) {
158
- try {
159
- // @ts-ignore
160
- shaderInstance.exports.main(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
161
- } catch (e) {
162
- console.error(`Shader execution error in ${type === this.VERTEX_SHADER ? 'VS' : 'FS'}:`, e);
163
- console.error(` attrPtr: ${attrPtr}, uniformPtr: ${uniformPtr}, varyingPtr: ${varyingPtr}, privatePtr: ${privatePtr}, texturePtr: ${texturePtr}`);
164
- throw e;
165
- }
158
+ // @ts-ignore
159
+ shaderInstance.exports.main(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
166
160
  }
167
161
  }
168
162
 
@@ -220,6 +214,11 @@ export class WasmWebGL2RenderingContext {
220
214
  const handle = tex && typeof tex === 'object' && typeof tex._handle === 'number' ? tex._handle : (tex >>> 0);
221
215
  const code = ex.wasm_ctx_bind_texture(this._ctxHandle, target >>> 0, handle);
222
216
  _checkErr(code, this._instance);
217
+ // Record bound texture in JS so we can map units to texture data for texel fetch
218
+ this._boundTexture = handle;
219
+ this._textureUnits = this._textureUnits || [];
220
+ const unit = this._activeTextureUnit || 0;
221
+ this._textureUnits[unit] = handle;
223
222
  }
224
223
 
225
224
  texImage2D(target, level, internalFormat, width, height, border, format, type_, pixels) {
@@ -255,6 +254,12 @@ export class WasmWebGL2RenderingContext {
255
254
  len >>> 0
256
255
  );
257
256
  _checkErr(code, this._instance);
257
+
258
+ // Mirror texture data in JS for fast texel fetches by shader imports
259
+ this._textureData = this._textureData || new Map();
260
+ const handle = this._boundTexture || 0;
261
+ const copy = new Uint8Array(mem.slice(ptr, ptr + len));
262
+ this._textureData.set(handle, { width: width >>> 0, height: height >>> 0, data: copy });
258
263
  } finally {
259
264
  ex.wasm_free(ptr);
260
265
  }
@@ -576,10 +581,12 @@ export class WasmWebGL2RenderingContext {
576
581
  };
577
582
  };
578
583
 
579
- const vsModule = new WebAssembly.Module(vsWasm);
584
+ let vsModule;
585
+ vsModule = new WebAssembly.Module(vsWasm);
580
586
  const vsInstanceRef = { current: null };
581
587
  const vsDebugEnv = createDebugEnv(this.VERTEX_SHADER, vsInstanceRef);
582
588
 
589
+
583
590
  program._vsInstance = new WebAssembly.Instance(vsModule, {
584
591
  env: {
585
592
  memory: this._instance.exports.memory,
@@ -588,10 +595,12 @@ export class WasmWebGL2RenderingContext {
588
595
  });
589
596
  vsInstanceRef.current = program._vsInstance;
590
597
 
591
- const fsModule = new WebAssembly.Module(fsWasm);
598
+ let fsModule;
599
+ fsModule = new WebAssembly.Module(fsWasm);
592
600
  const fsInstanceRef = { current: null };
593
601
  const fsDebugEnv = createDebugEnv(this.FRAGMENT_SHADER, fsInstanceRef);
594
602
 
603
+
595
604
  program._fsInstance = new WebAssembly.Instance(fsModule, {
596
605
  env: {
597
606
  memory: this._instance.exports.memory,
@@ -1223,6 +1232,9 @@ export class WasmWebGL2RenderingContext {
1223
1232
  }
1224
1233
  const code = ex.wasm_ctx_active_texture(this._ctxHandle, texture >>> 0);
1225
1234
  _checkErr(code, this._instance);
1235
+ // Track active texture unit in JS wrapper (GL_TEXTURE0 = 0x84C0)
1236
+ this._activeTextureUnit = (texture >>> 0) - 0x84C0;
1237
+ this._textureUnits = this._textureUnits || [];
1226
1238
  }
1227
1239
  texParameteri(target, pname, param) {
1228
1240
  this._assertNotDestroyed();
@@ -1682,3 +1694,124 @@ export function getShaderWat(ctxHandle, programHandle, shaderType) {
1682
1694
 
1683
1695
  return watText;
1684
1696
  }
1697
+
1698
+ /**
1699
+ * Decompile WASM bytes to GLSL source code.
1700
+ *
1701
+ * This uses the WASM-to-GLSL decompiler to convert compiled shader WASM
1702
+ * back into readable GLSL-like code.
1703
+ *
1704
+ * @param {number} ctxHandle - Context handle
1705
+ * @param {number} programHandle - Program handle
1706
+ * @param {number} shaderType - Shader type (VERTEX_SHADER or FRAGMENT_SHADER)
1707
+ * @returns {string | null} GLSL source code or null if not available
1708
+ */
1709
+ export function getShaderGlsl(ctxHandle, programHandle, shaderType) {
1710
+ const ctx = WasmWebGL2RenderingContext._contexts.get(ctxHandle);
1711
+ if (!ctx) {
1712
+ throw new Error('Invalid context handle');
1713
+ }
1714
+
1715
+ // First get the WASM bytes for the shader
1716
+ const wasmBytes = getShaderModule(ctxHandle, programHandle, shaderType);
1717
+ if (!wasmBytes) {
1718
+ return null;
1719
+ }
1720
+
1721
+ const ex = ctx._instance.exports;
1722
+ if (!ex || typeof ex.wasm_decompile_to_glsl !== 'function') {
1723
+ throw new Error('wasm_decompile_to_glsl not found');
1724
+ }
1725
+
1726
+ // Allocate memory in WASM for the input bytes
1727
+ const wasmBytesLen = wasmBytes.length;
1728
+ const wasmBytesPtr = ex.wasm_alloc(wasmBytesLen);
1729
+ if (wasmBytesPtr === 0) {
1730
+ throw new Error('Failed to allocate memory for WASM bytes');
1731
+ }
1732
+
1733
+ try {
1734
+ // Copy WASM bytes to linear memory
1735
+ const mem = new Uint8Array(ex.memory.buffer);
1736
+ mem.set(wasmBytes, wasmBytesPtr);
1737
+
1738
+ // Call the decompiler
1739
+ const resultLen = ex.wasm_decompile_to_glsl(wasmBytesPtr, wasmBytesLen);
1740
+
1741
+ if (resultLen === 0) {
1742
+ return null;
1743
+ }
1744
+
1745
+ // Get the decompiled GLSL
1746
+ const glslPtr = ex.wasm_get_decompiled_glsl_ptr();
1747
+ const glslLen = ex.wasm_get_decompiled_glsl_len();
1748
+
1749
+ if (glslPtr === 0 || glslLen === 0) {
1750
+ return null;
1751
+ }
1752
+
1753
+ // Read the GLSL string
1754
+ const glslBytes = new Uint8Array(ex.memory.buffer).subarray(glslPtr, glslPtr + glslLen);
1755
+ const decoder = new TextDecoder('utf-8');
1756
+ return decoder.decode(glslBytes);
1757
+ } finally {
1758
+ // Free the allocated memory
1759
+ ex.wasm_free(wasmBytesPtr);
1760
+ }
1761
+ }
1762
+
1763
+ /**
1764
+ * Decompile raw WASM bytes to GLSL source code.
1765
+ *
1766
+ * This is a lower-level API that takes raw WASM bytes directly.
1767
+ *
1768
+ * @param {WasmWebGL2RenderingContext} gl - WebGL2 context
1769
+ * @param {Uint8Array} wasmBytes - Raw WASM bytecode to decompile
1770
+ * @returns {string | null} GLSL source code or null on error
1771
+ */
1772
+ export function decompileWasmToGlsl(gl, wasmBytes) {
1773
+ if (!gl || !gl._instance) {
1774
+ throw new Error('Invalid WebGL2 context');
1775
+ }
1776
+
1777
+ const ex = gl._instance.exports;
1778
+ if (!ex || typeof ex.wasm_decompile_to_glsl !== 'function') {
1779
+ throw new Error('wasm_decompile_to_glsl not found');
1780
+ }
1781
+
1782
+ // Allocate memory in WASM for the input bytes
1783
+ const wasmBytesLen = wasmBytes.length;
1784
+ const wasmBytesPtr = ex.wasm_alloc(wasmBytesLen);
1785
+ if (wasmBytesPtr === 0) {
1786
+ throw new Error('Failed to allocate memory for WASM bytes');
1787
+ }
1788
+
1789
+ try {
1790
+ // Copy WASM bytes to linear memory
1791
+ const mem = new Uint8Array(ex.memory.buffer);
1792
+ mem.set(wasmBytes, wasmBytesPtr);
1793
+
1794
+ // Call the decompiler
1795
+ const resultLen = ex.wasm_decompile_to_glsl(wasmBytesPtr, wasmBytesLen);
1796
+
1797
+ if (resultLen === 0) {
1798
+ return null;
1799
+ }
1800
+
1801
+ // Get the decompiled GLSL
1802
+ const glslPtr = ex.wasm_get_decompiled_glsl_ptr();
1803
+ const glslLen = ex.wasm_get_decompiled_glsl_len();
1804
+
1805
+ if (glslPtr === 0 || glslLen === 0) {
1806
+ return null;
1807
+ }
1808
+
1809
+ // Read the GLSL string
1810
+ const glslBytes = new Uint8Array(ex.memory.buffer).subarray(glslPtr, glslPtr + glslLen);
1811
+ const decoder = new TextDecoder('utf-8');
1812
+ return decoder.decode(glslBytes);
1813
+ } finally {
1814
+ // Free the allocated memory
1815
+ ex.wasm_free(wasmBytesPtr);
1816
+ }
1817
+ }
package/webgl2.debug.wasm CHANGED
Binary file
package/webgl2.wasm CHANGED
Binary file