webgl2 1.1.4 → 1.1.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/AGENTS.md +9 -2
- package/coverage.md +23 -19
- package/daebug.md +29 -0
- package/index.js +121 -80
- package/package.json +2 -2
- package/src/webgl2_context.js +349 -37
- package/src/webgpu_context.js +927 -0
- package/webgl2.debug.wasm +0 -0
- package/webgl2.wasm +0 -0
package/src/webgl2_context.js
CHANGED
|
@@ -35,14 +35,34 @@ export class WasmWebGL2RenderingContext {
|
|
|
35
35
|
ARRAY_BUFFER = 0x8892;
|
|
36
36
|
ELEMENT_ARRAY_BUFFER = 0x8893;
|
|
37
37
|
STATIC_DRAW = 0x88E4;
|
|
38
|
-
|
|
39
|
-
UNSIGNED_SHORT = 0x1403;
|
|
38
|
+
BYTE = 0x1400;
|
|
40
39
|
UNSIGNED_BYTE = 0x1401;
|
|
40
|
+
SHORT = 0x1402;
|
|
41
|
+
UNSIGNED_SHORT = 0x1403;
|
|
42
|
+
INT = 0x1404;
|
|
43
|
+
UNSIGNED_INT = 0x1405;
|
|
44
|
+
FLOAT = 0x1406;
|
|
41
45
|
RGBA = 0x1908;
|
|
42
46
|
VIEWPORT = 0x0BA2;
|
|
43
47
|
COLOR_CLEAR_VALUE = 0x0C22;
|
|
44
48
|
BUFFER_SIZE = 0x8764;
|
|
49
|
+
MAX_VERTEX_ATTRIBS = 0x8869;
|
|
45
50
|
NO_ERROR = 0;
|
|
51
|
+
INVALID_ENUM = 0x0500;
|
|
52
|
+
INVALID_VALUE = 0x0501;
|
|
53
|
+
INVALID_OPERATION = 0x0502;
|
|
54
|
+
OUT_OF_MEMORY = 0x0505;
|
|
55
|
+
|
|
56
|
+
CURRENT_VERTEX_ATTRIB = 0x8626;
|
|
57
|
+
VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
|
|
58
|
+
VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
|
|
59
|
+
VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
|
|
60
|
+
VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
|
|
61
|
+
VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
|
|
62
|
+
VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
|
|
63
|
+
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
|
|
64
|
+
VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
|
|
65
|
+
VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD;
|
|
46
66
|
|
|
47
67
|
RENDERBUFFER = 0x8D41;
|
|
48
68
|
FRAMEBUFFER = 0x8D40;
|
|
@@ -51,6 +71,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
51
71
|
RGBA4 = 0x8056;
|
|
52
72
|
RGB565 = 0x8D62;
|
|
53
73
|
RGB5_A1 = 0x8057;
|
|
74
|
+
RGBA8 = 0x8058;
|
|
54
75
|
STENCIL_INDEX8 = 0x8D48;
|
|
55
76
|
COLOR_ATTACHMENT0 = 0x8CE0;
|
|
56
77
|
DEPTH_ATTACHMENT = 0x8D00;
|
|
@@ -82,13 +103,68 @@ export class WasmWebGL2RenderingContext {
|
|
|
82
103
|
this._destroyed = false;
|
|
83
104
|
/** @type {import('./webgl2_resources.js').WasmWebGLProgram | null} */
|
|
84
105
|
this._currentProgram = null;
|
|
106
|
+
this._debugMode = 0; // 0=None, 1=Shaders, 2=Rust, 3=All
|
|
107
|
+
this._drawingBufferWidth = 640;
|
|
108
|
+
this._drawingBufferHeight = 480;
|
|
109
|
+
|
|
110
|
+
WasmWebGL2RenderingContext._contexts.set(ctxHandle, this);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
setDebugMode(mode) {
|
|
114
|
+
this._assertNotDestroyed();
|
|
115
|
+
const ex = this._instance.exports;
|
|
116
|
+
if (!ex || typeof ex.wasm_ctx_set_debug_mode !== 'function') {
|
|
117
|
+
console.warn('wasm_ctx_set_debug_mode not found');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let modeVal = 0;
|
|
122
|
+
if (mode === true || mode === 'all') modeVal = 3;
|
|
123
|
+
else if (mode === 'shaders') modeVal = 1;
|
|
124
|
+
else if (mode === 'rust') modeVal = 2;
|
|
125
|
+
else modeVal = 0;
|
|
126
|
+
|
|
127
|
+
this._debugMode = modeVal;
|
|
128
|
+
const code = ex.wasm_ctx_set_debug_mode(this._ctxHandle, modeVal);
|
|
129
|
+
_checkErr(code, this._instance);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
get drawingBufferWidth() {
|
|
133
|
+
return this._drawingBufferWidth;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
get drawingBufferHeight() {
|
|
137
|
+
return this._drawingBufferHeight;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
resize(width, height) {
|
|
141
|
+
this._assertNotDestroyed();
|
|
142
|
+
const ex = this._instance.exports;
|
|
143
|
+
if (!ex || typeof ex.wasm_ctx_resize !== 'function') {
|
|
144
|
+
throw new Error('wasm_ctx_resize not found');
|
|
145
|
+
}
|
|
146
|
+
const code = ex.wasm_ctx_resize(this._ctxHandle, width, height);
|
|
147
|
+
_checkErr(code, this._instance);
|
|
148
|
+
this._drawingBufferWidth = width;
|
|
149
|
+
this._drawingBufferHeight = height;
|
|
150
|
+
}
|
|
85
151
|
|
|
86
|
-
|
|
152
|
+
// Set the viewport for rendering
|
|
153
|
+
viewport(x, y, width, height) {
|
|
154
|
+
this._assertNotDestroyed();
|
|
155
|
+
const ex = this._instance.exports;
|
|
156
|
+
if (!ex || typeof ex.wasm_ctx_viewport !== 'function') {
|
|
157
|
+
throw new Error('wasm_ctx_viewport not found');
|
|
158
|
+
}
|
|
159
|
+
const code = ex.wasm_ctx_viewport(this._ctxHandle, x | 0, y | 0, width >>> 0, height >>> 0);
|
|
160
|
+
_checkErr(code, this._instance);
|
|
87
161
|
}
|
|
88
162
|
|
|
163
|
+
/** @type {Map<number, WasmWebGL2RenderingContext>} */
|
|
164
|
+
static _contexts = new Map();
|
|
165
|
+
|
|
89
166
|
_executeShader(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
|
|
90
167
|
if (!this._currentProgram) {
|
|
91
|
-
console.log("DEBUG: No current program");
|
|
92
168
|
return;
|
|
93
169
|
}
|
|
94
170
|
const shaderInstance = type === this.VERTEX_SHADER ? this._currentProgram._vsInstance : this._currentProgram._fsInstance;
|
|
@@ -101,17 +177,18 @@ export class WasmWebGL2RenderingContext {
|
|
|
101
177
|
console.error(` attrPtr: ${attrPtr}, uniformPtr: ${uniformPtr}, varyingPtr: ${varyingPtr}, privatePtr: ${privatePtr}, texturePtr: ${texturePtr}`);
|
|
102
178
|
throw e;
|
|
103
179
|
}
|
|
180
|
+
} else {
|
|
181
|
+
// console.log(`DEBUG: Shader instance or main missing for type ${type}. Instance: ${!!shaderInstance}`);
|
|
104
182
|
}
|
|
105
183
|
}
|
|
106
184
|
|
|
107
185
|
destroy() {
|
|
108
186
|
if (this._destroyed) return;
|
|
187
|
+
WasmWebGL2RenderingContext._contexts.delete(this._ctxHandle);
|
|
109
188
|
const ex = this._instance.exports;
|
|
110
|
-
if (ex && typeof ex.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
_checkErr(code, this._instance);
|
|
114
|
-
}
|
|
189
|
+
if (ex && typeof ex.wasm_destroy_context === 'function') {
|
|
190
|
+
const code = ex.wasm_destroy_context(this._ctxHandle);
|
|
191
|
+
_checkErr(code, this._instance);
|
|
115
192
|
}
|
|
116
193
|
this._destroyed = true;
|
|
117
194
|
}
|
|
@@ -466,32 +543,127 @@ export class WasmWebGL2RenderingContext {
|
|
|
466
543
|
const vsWasm = this.getProgramWasm(program, this.VERTEX_SHADER);
|
|
467
544
|
const fsWasm = this.getProgramWasm(program, this.FRAGMENT_SHADER);
|
|
468
545
|
|
|
546
|
+
const createDebugEnv = (type, instanceRef) => {
|
|
547
|
+
if (this._debugMode !== 1 && this._debugMode !== 3) return {};
|
|
548
|
+
|
|
549
|
+
const stubCode = this.getProgramDebugStub(program, type);
|
|
550
|
+
if (!stubCode) return {};
|
|
551
|
+
|
|
552
|
+
// // Add sourceURL for debugging
|
|
553
|
+
// const debugName = `shader_stub_program_${program._handle}_${type === this.VERTEX_SHADER ? 'vs' : 'fs'}.js`;
|
|
554
|
+
// const codeWithUrl = stubCode + `\n//# sourceURL=${debugName}`;
|
|
555
|
+
|
|
556
|
+
let stubFuncs;
|
|
557
|
+
try {
|
|
558
|
+
// Eval the stub array
|
|
559
|
+
stubFuncs = (0, eval)(stubCode);
|
|
560
|
+
} catch (e) {
|
|
561
|
+
console.error("Failed to eval debug stub:", e);
|
|
562
|
+
return {};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return {
|
|
566
|
+
debug_step: (line, funcIdx, resultPtr) => {
|
|
567
|
+
const func = stubFuncs[line - 1];
|
|
568
|
+
if (func) {
|
|
569
|
+
const ctx = {
|
|
570
|
+
go: () => {
|
|
571
|
+
// Trampoline logic would go here
|
|
572
|
+
// For now we rely on WASM calling the function after debug_step returns
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
try {
|
|
576
|
+
func.call(ctx);
|
|
577
|
+
} catch (e) {
|
|
578
|
+
console.error("Error in debug stub:", e);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
};
|
|
584
|
+
|
|
469
585
|
if (vsWasm) {
|
|
470
586
|
try {
|
|
471
587
|
const vsModule = new WebAssembly.Module(vsWasm);
|
|
588
|
+
const instanceRef = { current: null };
|
|
589
|
+
const debugEnv = createDebugEnv(this.VERTEX_SHADER, instanceRef);
|
|
590
|
+
|
|
472
591
|
program._vsInstance = new WebAssembly.Instance(vsModule, {
|
|
473
592
|
env: {
|
|
474
|
-
memory: this._instance.exports.memory
|
|
593
|
+
memory: this._instance.exports.memory,
|
|
594
|
+
...debugEnv
|
|
475
595
|
}
|
|
476
596
|
});
|
|
597
|
+
instanceRef.current = program._vsInstance;
|
|
477
598
|
} catch (e) {
|
|
478
|
-
console.log(`DEBUG: VS Instance creation failed: ${e}`);
|
|
599
|
+
// console.log(`DEBUG: VS Instance creation failed: ${e}`);
|
|
479
600
|
}
|
|
480
601
|
}
|
|
481
602
|
if (fsWasm) {
|
|
482
603
|
try {
|
|
483
604
|
const fsModule = new WebAssembly.Module(fsWasm);
|
|
605
|
+
const instanceRef = { current: null };
|
|
606
|
+
const debugEnv = createDebugEnv(this.FRAGMENT_SHADER, instanceRef);
|
|
607
|
+
|
|
484
608
|
program._fsInstance = new WebAssembly.Instance(fsModule, {
|
|
485
609
|
env: {
|
|
486
|
-
memory: this._instance.exports.memory
|
|
610
|
+
memory: this._instance.exports.memory,
|
|
611
|
+
...debugEnv
|
|
487
612
|
}
|
|
488
613
|
});
|
|
614
|
+
instanceRef.current = program._fsInstance;
|
|
489
615
|
} catch (e) {
|
|
490
|
-
console.log(`DEBUG: FS Instance creation failed: ${e}`);
|
|
616
|
+
// console.log(`DEBUG: FS Instance creation failed: ${e}`);
|
|
491
617
|
}
|
|
492
618
|
}
|
|
493
619
|
}
|
|
494
620
|
|
|
621
|
+
getProgramDebugStub(program, shaderType) {
|
|
622
|
+
this._assertNotDestroyed();
|
|
623
|
+
const ex = this._instance.exports;
|
|
624
|
+
if (!ex || typeof ex.wasm_ctx_get_program_debug_stub !== 'function') {
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
628
|
+
const len = ex.wasm_ctx_get_program_debug_stub(this._ctxHandle, programHandle, shaderType, 0, 0);
|
|
629
|
+
if (len === 0) return null;
|
|
630
|
+
|
|
631
|
+
const ptr = ex.wasm_alloc(len);
|
|
632
|
+
if (ptr === 0) return null;
|
|
633
|
+
|
|
634
|
+
try {
|
|
635
|
+
const actualLen = ex.wasm_ctx_get_program_debug_stub(this._ctxHandle, programHandle, shaderType, ptr, len);
|
|
636
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
637
|
+
const bytes = mem.subarray(ptr, ptr + actualLen);
|
|
638
|
+
return new TextDecoder().decode(bytes);
|
|
639
|
+
} finally {
|
|
640
|
+
ex.wasm_free(ptr);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
getProgramDebugStub(program, shaderType) {
|
|
645
|
+
this._assertNotDestroyed();
|
|
646
|
+
const ex = this._instance.exports;
|
|
647
|
+
if (!ex || typeof ex.wasm_ctx_get_program_debug_stub !== 'function') {
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
651
|
+
const len = ex.wasm_ctx_get_program_debug_stub(this._ctxHandle, programHandle, shaderType, 0, 0);
|
|
652
|
+
if (len === 0) return null;
|
|
653
|
+
|
|
654
|
+
const ptr = ex.wasm_alloc(len);
|
|
655
|
+
if (ptr === 0) return null;
|
|
656
|
+
|
|
657
|
+
try {
|
|
658
|
+
const actualLen = ex.wasm_ctx_get_program_debug_stub(this._ctxHandle, programHandle, shaderType, ptr, len);
|
|
659
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
660
|
+
const bytes = mem.subarray(ptr, ptr + actualLen);
|
|
661
|
+
return new TextDecoder().decode(bytes);
|
|
662
|
+
} finally {
|
|
663
|
+
ex.wasm_free(ptr);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
495
667
|
deleteProgram(program) {
|
|
496
668
|
this._assertNotDestroyed();
|
|
497
669
|
const ex = this._instance.exports;
|
|
@@ -526,7 +698,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
526
698
|
}
|
|
527
699
|
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
528
700
|
const val = ex.wasm_ctx_get_shader_parameter(this._ctxHandle, shaderHandle, pname >>> 0);
|
|
529
|
-
|
|
701
|
+
|
|
530
702
|
// WebGL returns boolean for status parameters
|
|
531
703
|
if (pname === 0x8B81 /* COMPILE_STATUS */ || pname === 0x8B80 /* DELETE_STATUS */) {
|
|
532
704
|
return !!val;
|
|
@@ -557,7 +729,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
557
729
|
throw new Error('wasm_ctx_get_shader_info_log not found');
|
|
558
730
|
}
|
|
559
731
|
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
560
|
-
|
|
732
|
+
|
|
561
733
|
const maxLen = 1024;
|
|
562
734
|
const ptr = ex.wasm_alloc(maxLen);
|
|
563
735
|
if (ptr === 0) throw new Error('Failed to allocate memory for getShaderInfoLog');
|
|
@@ -699,6 +871,23 @@ export class WasmWebGL2RenderingContext {
|
|
|
699
871
|
_checkErr(code, this._instance);
|
|
700
872
|
}
|
|
701
873
|
|
|
874
|
+
vertexAttribIPointer(index, size, type, stride, offset) {
|
|
875
|
+
this._assertNotDestroyed();
|
|
876
|
+
const ex = this._instance.exports;
|
|
877
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib_ipointer !== 'function') {
|
|
878
|
+
throw new Error('wasm_ctx_vertex_attrib_ipointer not found');
|
|
879
|
+
}
|
|
880
|
+
const code = ex.wasm_ctx_vertex_attrib_ipointer(
|
|
881
|
+
this._ctxHandle,
|
|
882
|
+
index >>> 0,
|
|
883
|
+
size >>> 0,
|
|
884
|
+
type >>> 0,
|
|
885
|
+
stride >>> 0,
|
|
886
|
+
offset >>> 0
|
|
887
|
+
);
|
|
888
|
+
_checkErr(code, this._instance);
|
|
889
|
+
}
|
|
890
|
+
|
|
702
891
|
vertexAttrib1f(index, v0) {
|
|
703
892
|
this._assertNotDestroyed();
|
|
704
893
|
const ex = this._instance.exports;
|
|
@@ -706,6 +895,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
706
895
|
throw new Error('wasm_ctx_vertex_attrib1f not found');
|
|
707
896
|
}
|
|
708
897
|
const code = ex.wasm_ctx_vertex_attrib1f(this._ctxHandle, index >>> 0, +v0);
|
|
898
|
+
if (code === 5) return; // ERR_GL
|
|
709
899
|
_checkErr(code, this._instance);
|
|
710
900
|
}
|
|
711
901
|
vertexAttrib2f(index, v0, v1) {
|
|
@@ -715,6 +905,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
715
905
|
throw new Error('wasm_ctx_vertex_attrib2f not found');
|
|
716
906
|
}
|
|
717
907
|
const code = ex.wasm_ctx_vertex_attrib2f(this._ctxHandle, index >>> 0, +v0, +v1);
|
|
908
|
+
if (code === 5) return; // ERR_GL
|
|
718
909
|
_checkErr(code, this._instance);
|
|
719
910
|
}
|
|
720
911
|
vertexAttrib3f(index, v0, v1, v2) {
|
|
@@ -724,6 +915,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
724
915
|
throw new Error('wasm_ctx_vertex_attrib3f not found');
|
|
725
916
|
}
|
|
726
917
|
const code = ex.wasm_ctx_vertex_attrib3f(this._ctxHandle, index >>> 0, +v0, +v1, +v2);
|
|
918
|
+
if (code === 5) return; // ERR_GL
|
|
727
919
|
_checkErr(code, this._instance);
|
|
728
920
|
}
|
|
729
921
|
vertexAttrib4f(index, v0, v1, v2, v3) {
|
|
@@ -733,9 +925,77 @@ export class WasmWebGL2RenderingContext {
|
|
|
733
925
|
throw new Error('wasm_ctx_vertex_attrib4f not found');
|
|
734
926
|
}
|
|
735
927
|
const code = ex.wasm_ctx_vertex_attrib4f(this._ctxHandle, index >>> 0, +v0, +v1, +v2, +v3);
|
|
928
|
+
if (code === 5) return; // ERR_GL
|
|
929
|
+
_checkErr(code, this._instance);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
vertexAttrib1fv(index, v) {
|
|
933
|
+
if (v && v.length >= 1) {
|
|
934
|
+
this.vertexAttrib1f(index, v[0]);
|
|
935
|
+
} else {
|
|
936
|
+
this._setError(0x0501);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
vertexAttrib2fv(index, v) {
|
|
940
|
+
if (v && v.length >= 2) {
|
|
941
|
+
this.vertexAttrib2f(index, v[0], v[1]);
|
|
942
|
+
} else {
|
|
943
|
+
this._setError(0x0501);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
vertexAttrib3fv(index, v) {
|
|
947
|
+
if (v && v.length >= 3) {
|
|
948
|
+
this.vertexAttrib3f(index, v[0], v[1], v[2]);
|
|
949
|
+
} else {
|
|
950
|
+
this._setError(0x0501);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
vertexAttrib4fv(index, v) {
|
|
954
|
+
if (v && v.length >= 4) {
|
|
955
|
+
this.vertexAttrib4f(index, v[0], v[1], v[2], v[3]);
|
|
956
|
+
} else {
|
|
957
|
+
this._setError(0x0501);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
vertexAttribI4i(index, v0, v1, v2, v3) {
|
|
962
|
+
this._assertNotDestroyed();
|
|
963
|
+
const ex = this._instance.exports;
|
|
964
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib_i4i !== 'function') {
|
|
965
|
+
throw new Error('wasm_ctx_vertex_attrib_i4i not found');
|
|
966
|
+
}
|
|
967
|
+
const code = ex.wasm_ctx_vertex_attrib_i4i(this._ctxHandle, index >>> 0, v0 | 0, v1 | 0, v2 | 0, v3 | 0);
|
|
968
|
+
if (code === 5) return; // ERR_GL
|
|
736
969
|
_checkErr(code, this._instance);
|
|
737
970
|
}
|
|
738
971
|
|
|
972
|
+
vertexAttribI4ui(index, v0, v1, v2, v3) {
|
|
973
|
+
this._assertNotDestroyed();
|
|
974
|
+
const ex = this._instance.exports;
|
|
975
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib_i4ui !== 'function') {
|
|
976
|
+
throw new Error('wasm_ctx_vertex_attrib_i4ui not found');
|
|
977
|
+
}
|
|
978
|
+
const code = ex.wasm_ctx_vertex_attrib_i4ui(this._ctxHandle, index >>> 0, v0 >>> 0, v1 >>> 0, v2 >>> 0, v3 >>> 0);
|
|
979
|
+
if (code === 5) return; // ERR_GL
|
|
980
|
+
_checkErr(code, this._instance);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
vertexAttribI4iv(index, v) {
|
|
984
|
+
if (v && v.length >= 4) {
|
|
985
|
+
this.vertexAttribI4i(index, v[0], v[1], v[2], v[3]);
|
|
986
|
+
} else {
|
|
987
|
+
this._setError(0x0501);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
vertexAttribI4uiv(index, v) {
|
|
992
|
+
if (v && v.length >= 4) {
|
|
993
|
+
this.vertexAttribI4ui(index, v[0], v[1], v[2], v[3]);
|
|
994
|
+
} else {
|
|
995
|
+
this._setError(0x0501);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
739
999
|
vertexAttribDivisor(index, divisor) {
|
|
740
1000
|
this._assertNotDestroyed();
|
|
741
1001
|
const ex = this._instance.exports;
|
|
@@ -779,9 +1039,10 @@ export class WasmWebGL2RenderingContext {
|
|
|
779
1039
|
}
|
|
780
1040
|
const handle = buffer && typeof buffer === 'object' && typeof buffer._handle === 'number' ? buffer._handle : (buffer >>> 0);
|
|
781
1041
|
const code = ex.wasm_ctx_delete_buffer(this._ctxHandle, handle);
|
|
782
|
-
_checkErr(code, this._instance);
|
|
1042
|
+
_checkErr(code, this._instance); if (buffer && typeof buffer === 'object') {
|
|
783
1043
|
try { buffer._handle = 0; buffer._deleted = true; } catch (e) { /* ignore */ }
|
|
784
|
-
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
785
1046
|
|
|
786
1047
|
bufferData(target, data, usage) {
|
|
787
1048
|
this._assertNotDestroyed();
|
|
@@ -1087,7 +1348,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
1087
1348
|
throw new Error('wasm_ctx_uniform_matrix_4fv not found');
|
|
1088
1349
|
}
|
|
1089
1350
|
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
1090
|
-
|
|
1351
|
+
|
|
1091
1352
|
let bytes;
|
|
1092
1353
|
if (value instanceof Float32Array) {
|
|
1093
1354
|
bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
@@ -1111,6 +1372,64 @@ export class WasmWebGL2RenderingContext {
|
|
|
1111
1372
|
getActiveUniform(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1112
1373
|
getActiveAttrib(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1113
1374
|
|
|
1375
|
+
getVertexAttrib(index, pname) {
|
|
1376
|
+
this._assertNotDestroyed();
|
|
1377
|
+
const ex = this._instance.exports;
|
|
1378
|
+
if (!ex || typeof ex.wasm_ctx_get_vertex_attrib !== 'function') {
|
|
1379
|
+
throw new Error('wasm_ctx_get_vertex_attrib not found');
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// Allocate memory for result.
|
|
1383
|
+
// Most params return 1 int (4 bytes).
|
|
1384
|
+
// CURRENT_VERTEX_ATTRIB returns 4 values (16 bytes) + type (4 bytes) = 20 bytes.
|
|
1385
|
+
const len = 20;
|
|
1386
|
+
const ptr = ex.wasm_alloc(len);
|
|
1387
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getVertexAttrib');
|
|
1388
|
+
|
|
1389
|
+
try {
|
|
1390
|
+
const code = ex.wasm_ctx_get_vertex_attrib(this._ctxHandle, index >>> 0, pname >>> 0, ptr, len);
|
|
1391
|
+
if (code === 5) { // ERR_GL
|
|
1392
|
+
return undefined;
|
|
1393
|
+
}
|
|
1394
|
+
_checkErr(code, this._instance);
|
|
1395
|
+
|
|
1396
|
+
const mem = new Int32Array(ex.memory.buffer, ptr, 5);
|
|
1397
|
+
const memU = new Uint32Array(ex.memory.buffer, ptr, 5);
|
|
1398
|
+
const memF = new Float32Array(ex.memory.buffer, ptr, 5);
|
|
1399
|
+
|
|
1400
|
+
if (pname === 0x8626 /* CURRENT_VERTEX_ATTRIB */) {
|
|
1401
|
+
// Check type at index 4
|
|
1402
|
+
const type = memU[4];
|
|
1403
|
+
if (type === 0x1404 /* INT */) {
|
|
1404
|
+
return new Int32Array([mem[0], mem[1], mem[2], mem[3]]);
|
|
1405
|
+
} else if (type === 0x1405 /* UNSIGNED_INT */) {
|
|
1406
|
+
return new Uint32Array([memU[0], memU[1], memU[2], memU[3]]);
|
|
1407
|
+
} else {
|
|
1408
|
+
// Default to float
|
|
1409
|
+
return new Float32Array([memF[0], memF[1], memF[2], memF[3]]);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
// Other params
|
|
1414
|
+
if (pname === 0x8622 /* ENABLED */ ||
|
|
1415
|
+
pname === 0x886A /* NORMALIZED */ ||
|
|
1416
|
+
pname === 0x88FD /* INTEGER */) {
|
|
1417
|
+
return mem[0] !== 0;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
if (pname === 0x889F /* BUFFER_BINDING */) {
|
|
1421
|
+
const handle = memU[0];
|
|
1422
|
+
if (handle === 0) return null;
|
|
1423
|
+
return new WasmWebGLBuffer(this, handle);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
return mem[0];
|
|
1427
|
+
} finally {
|
|
1428
|
+
ex.wasm_free(ptr, len);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
|
|
1114
1433
|
getParameter(pname) {
|
|
1115
1434
|
this._assertNotDestroyed();
|
|
1116
1435
|
const ex = this._instance.exports;
|
|
@@ -1142,6 +1461,10 @@ export class WasmWebGL2RenderingContext {
|
|
|
1142
1461
|
}
|
|
1143
1462
|
}
|
|
1144
1463
|
|
|
1464
|
+
if (pname === 0x8869 /* MAX_VERTEX_ATTRIBS */) {
|
|
1465
|
+
return 16;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1145
1468
|
throw new Error(`getParameter for ${pname} not implemented`);
|
|
1146
1469
|
}
|
|
1147
1470
|
getError() {
|
|
@@ -1152,6 +1475,14 @@ export class WasmWebGL2RenderingContext {
|
|
|
1152
1475
|
}
|
|
1153
1476
|
return ex.wasm_ctx_get_error(this._ctxHandle);
|
|
1154
1477
|
}
|
|
1478
|
+
|
|
1479
|
+
_setError(error) {
|
|
1480
|
+
const ex = this._instance.exports;
|
|
1481
|
+
if (ex && typeof ex.wasm_ctx_set_gl_error === 'function') {
|
|
1482
|
+
ex.wasm_ctx_set_gl_error(this._ctxHandle, error);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1155
1486
|
finish() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1156
1487
|
flush() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1157
1488
|
|
|
@@ -1252,25 +1583,6 @@ export class WasmWebGL2RenderingContext {
|
|
|
1252
1583
|
}
|
|
1253
1584
|
this._verbosity = level;
|
|
1254
1585
|
}
|
|
1255
|
-
|
|
1256
|
-
/**
|
|
1257
|
-
* Get LCOV coverage report.
|
|
1258
|
-
* @returns {string}
|
|
1259
|
-
*/
|
|
1260
|
-
getLcovReport() {
|
|
1261
|
-
// Coverage is global to the WASM module, so we can retrieve it even if context is destroyed.
|
|
1262
|
-
// this._assertNotDestroyed();
|
|
1263
|
-
const ex = this._instance.exports;
|
|
1264
|
-
if (ex && typeof ex.wasm_get_lcov_report_ptr === 'function' && typeof ex.wasm_get_lcov_report_len === 'function') {
|
|
1265
|
-
const ptr = ex.wasm_get_lcov_report_ptr();
|
|
1266
|
-
const len = ex.wasm_get_lcov_report_len();
|
|
1267
|
-
if (ptr === 0 || len === 0) return '';
|
|
1268
|
-
const mem = new Uint8Array(ex.memory.buffer);
|
|
1269
|
-
const bytes = mem.subarray(ptr, ptr + len);
|
|
1270
|
-
return new TextDecoder('utf-8').decode(bytes);
|
|
1271
|
-
}
|
|
1272
|
-
return '';
|
|
1273
|
-
}
|
|
1274
1586
|
}
|
|
1275
1587
|
|
|
1276
1588
|
/**
|