webgl2/
lib.rs

1//! WebGL2 Shader Compiler and Emulator
2//!
3//! A complete toolchain for compiling GLSL shaders to WebAssembly with DWARF debugging,
4//! including a software rasterizer for shader emulation and TypeScript harness generation.
5//!
6//! # Modules
7//!
8//! - [`naga_wasm_backend`] - Compile Naga IR to WASM with DWARF debug information
9//! - [`wasm_gl_emu`] - Software rasterizer and WASM shader runtime
10//! - [`glsl_introspection`] - GLSL parser with annotation extraction
11//! - [`js_codegen`] - TypeScript harness code generator
12
13pub mod glsl_introspection;
14pub mod js_codegen;
15pub mod naga_wasm_backend;
16pub mod wasm_gl_emu;
17pub mod webgl2_context;
18
19#[cfg(feature = "coverage")]
20pub mod coverage;
21
22#[cfg(target_arch = "wasm32")]
23#[link(wasm_import_module = "env")]
24extern "C" {
25    fn print(ptr: *const u8, len: usize);
26    fn wasm_execute_shader(
27        type_: u32,
28        attr_ptr: i32,
29        uniform_ptr: i32,
30        varying_ptr: i32,
31        private_ptr: i32,
32        texture_ptr: i32,
33    );
34}
35
36#[cfg(not(target_arch = "wasm32"))]
37unsafe fn print(_ptr: *const u8, _len: usize) {}
38
39#[cfg(not(target_arch = "wasm32"))]
40unsafe fn wasm_execute_shader(
41    _type_: u32,
42    _attr_ptr: i32,
43    _uniform_ptr: i32,
44    _varying_ptr: i32,
45    _private_ptr: i32,
46    _texture_ptr: i32,
47) {
48}
49
50pub fn js_print(s: &str) {
51    unsafe {
52        print(s.as_ptr(), s.len());
53    }
54}
55
56pub fn js_log(level: u32, s: &str) {
57    // Level 0: Error, 1: Warning, 2: Info, 3: Debug
58    // For now, we just prefix and print.
59    // In the future, we can check a global verbosity level.
60    let prefix = match level {
61        0 => "ERROR: ",
62        1 => "WARN: ",
63        2 => "INFO: ",
64        3 => "DEBUG: ",
65        _ => "",
66    };
67    js_print(&format!("{}{}", prefix, s));
68}
69
70pub fn js_execute_shader(
71    type_: u32,
72    attr_ptr: u32,
73    uniform_ptr: u32,
74    varying_ptr: u32,
75    private_ptr: u32,
76    texture_ptr: u32,
77) {
78    unsafe {
79        wasm_execute_shader(
80            type_,
81            attr_ptr as i32,
82            uniform_ptr as i32,
83            varying_ptr as i32,
84            private_ptr as i32,
85            texture_ptr as i32,
86        );
87    }
88}
89
90// Re-export commonly used types
91pub use glsl_introspection::ResourceManifest;
92pub use js_codegen::generate_harness;
93pub use naga_wasm_backend::{BackendError, WasmBackend, WasmBackendConfig, WasmModule};
94pub use wasm_gl_emu::RuntimeError;
95#[cfg(feature = "cli")]
96pub use wasm_gl_emu::ShaderRuntime;
97
98// Legacy WebGL2 convenience helpers removed.
99// The implementation now lives in the `webgl2_context` module and is
100// exposed via the `wasm_ctx_*/wasm_*` exports defined below.
101//
102// Old, unsafe `static mut` helpers (framebuffer, texture arrays, etc.)
103// were intentionally removed to centralize the implementation in
104// `src/webgl2_context.rs` which provides a safe, handle-based API.
105
106// ============================================================================
107// NEW: WebGL2 Prototype Exports (Schema v2)
108// Follows docs/1.1.1-webgl2-prototype.md
109// ============================================================================
110
111// ---- Context Lifecycle ----
112
113/// Create a new WebGL2 context.
114/// Returns context handle (0 on failure; sets last_error).
115#[no_mangle]
116pub extern "C" fn wasm_create_context() -> u32 {
117    webgl2_context::create_context()
118}
119
120/// Destroy a WebGL2 context by handle.
121/// Returns errno (0 on success).
122#[no_mangle]
123pub extern "C" fn wasm_destroy_context(handle: u32) -> u32 {
124    webgl2_context::destroy_context(handle)
125}
126
127// ---- Memory Management ----
128
129/// Allocate memory from WASM linear memory.
130/// Returns pointer (0 on failure; sets last_error).
131#[no_mangle]
132pub extern "C" fn wasm_alloc(size: u32) -> u32 {
133    webgl2_context::wasm_alloc(size)
134}
135
136/// Free memory allocated by wasm_alloc.
137/// Returns errno (0 on success).
138#[no_mangle]
139pub extern "C" fn wasm_free(ptr: u32) -> u32 {
140    webgl2_context::wasm_free(ptr)
141}
142
143// ---- Error Reporting ----
144
145/// Get pointer to last error message (UTF-8).
146#[no_mangle]
147pub extern "C" fn wasm_last_error_ptr() -> u32 {
148    webgl2_context::last_error_ptr() as u32
149}
150
151/// Get length of last error message in bytes.
152#[no_mangle]
153pub extern "C" fn wasm_last_error_len() -> u32 {
154    webgl2_context::last_error_len()
155}
156
157// ---- Texture Operations ----
158
159/// Create a texture in the given context.
160/// Returns texture handle (0 on failure).
161#[no_mangle]
162pub extern "C" fn wasm_ctx_create_texture(ctx: u32) -> u32 {
163    webgl2_context::ctx_create_texture(ctx)
164}
165
166/// Delete a texture.
167/// Returns errno.
168#[no_mangle]
169pub extern "C" fn wasm_ctx_delete_texture(ctx: u32, tex: u32) -> u32 {
170    webgl2_context::ctx_delete_texture(ctx, tex)
171}
172
173/// Bind a texture.
174/// Returns errno.
175#[no_mangle]
176pub extern "C" fn wasm_ctx_bind_texture(ctx: u32, target: u32, tex: u32) -> u32 {
177    webgl2_context::ctx_bind_texture(ctx, target, tex)
178}
179
180/// Set texture parameters.
181/// Returns errno.
182#[no_mangle]
183pub extern "C" fn wasm_ctx_tex_parameter_i(ctx: u32, target: u32, pname: u32, param: i32) -> u32 {
184    webgl2_context::ctx_tex_parameter_i(ctx, target, pname, param)
185}
186
187/// Upload pixel data to a texture.
188/// ptr/len point to RGBA u8 pixel data in WASM linear memory.
189/// Returns errno.
190#[no_mangle]
191pub extern "C" fn wasm_ctx_tex_image_2d(
192    ctx: u32,
193    target: u32,
194    level: i32,
195    internal_format: i32,
196    width: u32,
197    height: u32,
198    border: i32,
199    format: i32,
200    type_: i32,
201    ptr: u32,
202    len: u32,
203) -> u32 {
204    webgl2_context::ctx_tex_image_2d(
205        ctx,
206        target,
207        level,
208        internal_format,
209        width,
210        height,
211        border,
212        format,
213        type_,
214        ptr,
215        len,
216    )
217}
218
219// ---- Framebuffer Operations ----
220
221/// Create a framebuffer in the given context.
222/// Returns framebuffer handle (0 on failure).
223#[no_mangle]
224pub extern "C" fn wasm_ctx_create_framebuffer(ctx: u32) -> u32 {
225    webgl2_context::ctx_create_framebuffer(ctx)
226}
227
228/// Delete a framebuffer.
229/// Returns errno.
230#[no_mangle]
231pub extern "C" fn wasm_ctx_delete_framebuffer(ctx: u32, fb: u32) -> u32 {
232    webgl2_context::ctx_delete_framebuffer(ctx, fb)
233}
234
235/// Bind a framebuffer.
236/// Returns errno.
237#[no_mangle]
238pub extern "C" fn wasm_ctx_bind_framebuffer(ctx: u32, target: u32, fb: u32) -> u32 {
239    webgl2_context::ctx_bind_framebuffer(ctx, target, fb)
240}
241
242/// Attach a texture to the bound framebuffer.
243/// Returns errno.
244#[no_mangle]
245pub extern "C" fn wasm_ctx_framebuffer_texture2d(
246    ctx: u32,
247    target: u32,
248    attachment: u32,
249    textarget: u32,
250    tex: u32,
251    level: i32,
252) -> u32 {
253    webgl2_context::ctx_framebuffer_texture2d(ctx, target, attachment, textarget, tex, level)
254}
255
256// ---- Pixel Operations ----
257
258/// Read pixels from the bound framebuffer into dest_ptr.
259/// dest_ptr/dest_len point to RGBA u8 buffer in WASM linear memory.
260/// Returns errno.
261#[no_mangle]
262pub extern "C" fn wasm_ctx_read_pixels(
263    ctx: u32,
264    x: i32,
265    y: i32,
266    width: u32,
267    height: u32,
268    format: u32,
269    type_: u32,
270    dest_ptr: u32,
271    dest_len: u32,
272) -> u32 {
273    webgl2_context::ctx_read_pixels(ctx, x, y, width, height, format, type_, dest_ptr, dest_len)
274}
275
276// ---- State Management ----
277
278/// Set the clear color.
279#[no_mangle]
280pub extern "C" fn wasm_ctx_clear_color(ctx: u32, r: f32, g: f32, b: f32, a: f32) -> u32 {
281    webgl2_context::ctx_clear_color(ctx, r, g, b, a)
282}
283
284/// Clear buffers.
285#[no_mangle]
286pub extern "C" fn wasm_ctx_clear(ctx: u32, mask: u32) -> u32 {
287    webgl2_context::ctx_clear(ctx, mask)
288}
289
290/// Set the viewport.
291#[no_mangle]
292pub extern "C" fn wasm_ctx_viewport(ctx: u32, x: i32, y: i32, width: u32, height: u32) -> u32 {
293    webgl2_context::ctx_viewport(ctx, x, y, width, height)
294}
295
296/// Set the scissor box.
297#[no_mangle]
298pub extern "C" fn wasm_ctx_scissor(ctx: u32, x: i32, y: i32, width: u32, height: u32) -> u32 {
299    webgl2_context::ctx_scissor(ctx, x, y, width, height)
300}
301
302/// Set the depth function.
303#[no_mangle]
304pub extern "C" fn wasm_ctx_depth_func(ctx: u32, func: u32) -> u32 {
305    webgl2_context::ctx_depth_func(ctx, func)
306}
307
308/// Set the active texture unit.
309#[no_mangle]
310pub extern "C" fn wasm_ctx_active_texture(ctx: u32, texture: u32) -> u32 {
311    webgl2_context::ctx_active_texture(ctx, texture)
312}
313
314/// Enable a capability.
315#[no_mangle]
316pub extern "C" fn wasm_ctx_enable(ctx: u32, cap: u32) -> u32 {
317    webgl2_context::ctx_enable(ctx, cap)
318}
319
320/// Disable a capability.
321#[no_mangle]
322pub extern "C" fn wasm_ctx_disable(ctx: u32, cap: u32) -> u32 {
323    webgl2_context::ctx_disable(ctx, cap)
324}
325
326/// Get the last GL error.
327#[no_mangle]
328pub extern "C" fn wasm_ctx_get_error(ctx: u32) -> u32 {
329    webgl2_context::ctx_get_error(ctx)
330}
331
332// ---- Buffer Operations ----
333
334/// Create a buffer.
335#[no_mangle]
336pub extern "C" fn wasm_ctx_create_buffer(ctx: u32) -> u32 {
337    webgl2_context::ctx_create_buffer(ctx)
338}
339
340/// Delete a buffer.
341#[no_mangle]
342pub extern "C" fn wasm_ctx_delete_buffer(ctx: u32, buf: u32) -> u32 {
343    webgl2_context::ctx_delete_buffer(ctx, buf)
344}
345
346/// Bind a buffer.
347#[no_mangle]
348pub extern "C" fn wasm_ctx_bind_buffer(ctx: u32, target: u32, buf: u32) -> u32 {
349    webgl2_context::ctx_bind_buffer(ctx, target, buf)
350}
351
352/// Upload data to the bound buffer.
353#[no_mangle]
354pub extern "C" fn wasm_ctx_buffer_data(
355    ctx: u32,
356    target: u32,
357    ptr: u32,
358    len: u32,
359    usage: u32,
360) -> u32 {
361    webgl2_context::ctx_buffer_data(ctx, target, ptr, len, usage)
362}
363
364/// Update a subset of the bound buffer's data.
365#[no_mangle]
366pub extern "C" fn wasm_ctx_buffer_sub_data(
367    ctx: u32,
368    target: u32,
369    offset: u32,
370    ptr: u32,
371    len: u32,
372) -> u32 {
373    webgl2_context::ctx_buffer_sub_data(ctx, target, offset, ptr, len)
374}
375
376// ---- Shader and Program Operations ----
377
378/// Create a shader.
379#[no_mangle]
380pub extern "C" fn wasm_ctx_create_shader(ctx: u32, type_: u32) -> u32 {
381    webgl2_context::ctx_create_shader(ctx, type_)
382}
383
384/// Delete a shader.
385#[no_mangle]
386pub extern "C" fn wasm_ctx_delete_shader(ctx: u32, shader: u32) -> u32 {
387    webgl2_context::ctx_delete_shader(ctx, shader)
388}
389
390/// Set shader source.
391#[no_mangle]
392pub extern "C" fn wasm_ctx_shader_source(ctx: u32, shader: u32, ptr: u32, len: u32) -> u32 {
393    webgl2_context::ctx_shader_source(ctx, shader, ptr, len)
394}
395
396/// Compile a shader.
397#[no_mangle]
398pub extern "C" fn wasm_ctx_compile_shader(ctx: u32, shader: u32) -> u32 {
399    webgl2_context::ctx_compile_shader(ctx, shader)
400}
401
402/// Get shader parameter.
403#[no_mangle]
404pub extern "C" fn wasm_ctx_get_shader_parameter(ctx: u32, shader: u32, pname: u32) -> i32 {
405    webgl2_context::ctx_get_shader_parameter(ctx, shader, pname)
406}
407
408/// Get shader info log.
409#[no_mangle]
410pub extern "C" fn wasm_ctx_get_shader_info_log(ctx: u32, shader: u32, ptr: u32, len: u32) -> u32 {
411    webgl2_context::ctx_get_shader_info_log(ctx, shader, ptr, len)
412}
413
414/// Create a program.
415#[no_mangle]
416pub extern "C" fn wasm_ctx_create_program(ctx: u32) -> u32 {
417    webgl2_context::ctx_create_program(ctx)
418}
419
420/// Delete a program.
421#[no_mangle]
422pub extern "C" fn wasm_ctx_delete_program(ctx: u32, program: u32) -> u32 {
423    webgl2_context::ctx_delete_program(ctx, program)
424}
425
426/// Attach a shader to a program.
427#[no_mangle]
428pub extern "C" fn wasm_ctx_attach_shader(ctx: u32, program: u32, shader: u32) -> u32 {
429    webgl2_context::ctx_attach_shader(ctx, program, shader)
430}
431
432/// Link a program.
433#[no_mangle]
434pub extern "C" fn wasm_ctx_link_program(ctx: u32, program: u32) -> u32 {
435    webgl2_context::ctx_link_program(ctx, program)
436}
437
438/// Get program parameter.
439#[no_mangle]
440pub extern "C" fn wasm_ctx_get_program_parameter(ctx: u32, program: u32, pname: u32) -> i32 {
441    webgl2_context::ctx_get_program_parameter(ctx, program, pname)
442}
443
444/// Get program info log.
445#[no_mangle]
446pub extern "C" fn wasm_ctx_get_program_info_log(ctx: u32, program: u32, ptr: u32, len: u32) -> u32 {
447    webgl2_context::ctx_get_program_info_log(ctx, program, ptr, len)
448}
449
450/// Get the length of the generated WASM for a program's shader.
451#[no_mangle]
452pub extern "C" fn wasm_ctx_get_program_wasm_len(ctx: u32, program: u32, shader_type: u32) -> u32 {
453    webgl2_context::ctx_get_program_wasm_len(ctx, program, shader_type)
454}
455
456/// Get the generated WASM for a program's shader.
457#[no_mangle]
458pub extern "C" fn wasm_ctx_get_program_wasm(
459    ctx: u32,
460    program: u32,
461    shader_type: u32,
462    ptr: u32,
463    len: u32,
464) -> u32 {
465    webgl2_context::ctx_get_program_wasm(ctx, program, shader_type, ptr, len)
466}
467
468/// Get attribute location.
469#[no_mangle]
470pub extern "C" fn wasm_ctx_get_attrib_location(ctx: u32, program: u32, ptr: u32, len: u32) -> i32 {
471    webgl2_context::ctx_get_attrib_location(ctx, program, ptr, len)
472}
473
474/// Bind attribute location.
475#[no_mangle]
476pub extern "C" fn wasm_ctx_bind_attrib_location(
477    ctx: u32,
478    program: u32,
479    index: u32,
480    ptr: u32,
481    len: u32,
482) -> u32 {
483    webgl2_context::ctx_bind_attrib_location(ctx, program, index, ptr, len)
484}
485
486/// Get uniform location.
487#[no_mangle]
488pub extern "C" fn wasm_ctx_get_uniform_location(ctx: u32, program: u32, ptr: u32, len: u32) -> i32 {
489    webgl2_context::ctx_get_uniform_location(ctx, program, ptr, len)
490}
491
492/// Set uniform 1f.
493#[no_mangle]
494pub extern "C" fn wasm_ctx_uniform1f(ctx: u32, location: i32, x: f32) -> u32 {
495    webgl2_context::ctx_uniform1f(ctx, location, x)
496}
497
498/// Set uniform 2f.
499#[no_mangle]
500pub extern "C" fn wasm_ctx_uniform2f(ctx: u32, location: i32, x: f32, y: f32) -> u32 {
501    webgl2_context::ctx_uniform2f(ctx, location, x, y)
502}
503
504/// Set uniform 3f.
505#[no_mangle]
506pub extern "C" fn wasm_ctx_uniform3f(ctx: u32, location: i32, x: f32, y: f32, z: f32) -> u32 {
507    webgl2_context::ctx_uniform3f(ctx, location, x, y, z)
508}
509
510/// Set uniform 4f.
511#[no_mangle]
512pub extern "C" fn wasm_ctx_uniform4f(
513    ctx: u32,
514    location: i32,
515    x: f32,
516    y: f32,
517    z: f32,
518    w: f32,
519) -> u32 {
520    webgl2_context::ctx_uniform4f(ctx, location, x, y, z, w)
521}
522
523/// Set uniform 1i.
524#[no_mangle]
525pub extern "C" fn wasm_ctx_uniform1i(ctx: u32, location: i32, x: i32) -> u32 {
526    webgl2_context::ctx_uniform1i(ctx, location, x)
527}
528
529/// Set uniform matrix 4fv.
530#[no_mangle]
531pub extern "C" fn wasm_ctx_uniform_matrix_4fv(
532    ctx: u32,
533    location: i32,
534    transpose: u32,
535    ptr: u32,
536    len: u32,
537) -> u32 {
538    webgl2_context::ctx_uniform_matrix_4fv(ctx, location, transpose != 0, ptr, len)
539}
540
541/// Use a program.
542#[no_mangle]
543pub extern "C" fn wasm_ctx_use_program(ctx: u32, program: u32) -> u32 {
544    webgl2_context::ctx_use_program(ctx, program)
545}
546
547/// Enable vertex attribute array.
548#[no_mangle]
549pub extern "C" fn wasm_ctx_enable_vertex_attrib_array(ctx: u32, index: u32) -> u32 {
550    webgl2_context::ctx_enable_vertex_attrib_array(ctx, index)
551}
552
553/// Disable vertex attribute array.
554#[no_mangle]
555pub extern "C" fn wasm_ctx_disable_vertex_attrib_array(ctx: u32, index: u32) -> u32 {
556    webgl2_context::ctx_disable_vertex_attrib_array(ctx, index)
557}
558
559/// Vertex attribute pointer.
560#[no_mangle]
561pub extern "C" fn wasm_ctx_vertex_attrib_pointer(
562    ctx: u32,
563    index: u32,
564    size: i32,
565    type_: u32,
566    normalized: u32,
567    stride: i32,
568    offset: u32,
569) -> u32 {
570    webgl2_context::ctx_vertex_attrib_pointer(
571        ctx,
572        index,
573        size,
574        type_,
575        normalized != 0,
576        stride,
577        offset,
578    )
579}
580
581/// Set vertex attribute default value (1f).
582#[no_mangle]
583pub extern "C" fn wasm_ctx_vertex_attrib1f(ctx: u32, index: u32, v0: f32) -> u32 {
584    webgl2_context::ctx_vertex_attrib1f(ctx, index, v0)
585}
586
587/// Set vertex attribute default value (2f).
588#[no_mangle]
589pub extern "C" fn wasm_ctx_vertex_attrib2f(ctx: u32, index: u32, v0: f32, v1: f32) -> u32 {
590    webgl2_context::ctx_vertex_attrib2f(ctx, index, v0, v1)
591}
592
593/// Set vertex attribute default value (3f).
594#[no_mangle]
595pub extern "C" fn wasm_ctx_vertex_attrib3f(ctx: u32, index: u32, v0: f32, v1: f32, v2: f32) -> u32 {
596    webgl2_context::ctx_vertex_attrib3f(ctx, index, v0, v1, v2)
597}
598
599/// Set vertex attribute default value (4f).
600#[no_mangle]
601pub extern "C" fn wasm_ctx_vertex_attrib4f(
602    ctx: u32,
603    index: u32,
604    v0: f32,
605    v1: f32,
606    v2: f32,
607    v3: f32,
608) -> u32 {
609    webgl2_context::ctx_vertex_attrib4f(ctx, index, v0, v1, v2, v3)
610}
611
612/// Vertex attribute divisor.
613#[no_mangle]
614pub extern "C" fn wasm_ctx_vertex_attrib_divisor(ctx: u32, index: u32, divisor: u32) -> u32 {
615    webgl2_context::ctx_vertex_attrib_divisor(ctx, index, divisor)
616}
617
618/// Get a parameter (vector version).
619#[no_mangle]
620pub extern "C" fn wasm_ctx_get_parameter_v(
621    ctx: u32,
622    pname: u32,
623    dest_ptr: u32,
624    dest_len: u32,
625) -> u32 {
626    webgl2_context::ctx_get_parameter_v(ctx, pname, dest_ptr, dest_len)
627}
628
629/// Get buffer parameter.
630#[no_mangle]
631pub extern "C" fn wasm_ctx_get_buffer_parameter(ctx: u32, target: u32, pname: u32) -> i32 {
632    webgl2_context::ctx_get_buffer_parameter(ctx, target, pname)
633}
634
635/// Draw arrays.
636#[no_mangle]
637pub extern "C" fn wasm_ctx_draw_arrays(ctx: u32, mode: u32, first: i32, count: i32) -> u32 {
638    webgl2_context::ctx_draw_arrays(ctx, mode, first, count)
639}
640
641/// Draw arrays instanced.
642#[no_mangle]
643pub extern "C" fn wasm_ctx_draw_arrays_instanced(
644    ctx: u32,
645    mode: u32,
646    first: i32,
647    count: i32,
648    instance_count: i32,
649) -> u32 {
650    webgl2_context::ctx_draw_arrays_instanced(ctx, mode, first, count, instance_count)
651}
652
653/// Draw elements.
654#[no_mangle]
655pub extern "C" fn wasm_ctx_draw_elements(
656    ctx: u32,
657    mode: u32,
658    count: i32,
659    type_: u32,
660    offset: u32,
661) -> u32 {
662    webgl2_context::ctx_draw_elements(ctx, mode, count, type_, offset)
663}
664
665/// Draw elements instanced.
666#[no_mangle]
667pub extern "C" fn wasm_ctx_draw_elements_instanced(
668    ctx: u32,
669    mode: u32,
670    count: i32,
671    type_: u32,
672    offset: u32,
673    instance_count: i32,
674) -> u32 {
675    webgl2_context::ctx_draw_elements_instanced(ctx, mode, count, type_, offset, instance_count)
676}
677
678/// Set verbosity level.
679#[no_mangle]
680pub extern "C" fn wasm_ctx_set_verbosity(ctx: u32, level: u32) -> u32 {
681    webgl2_context::ctx_set_verbosity(ctx, level)
682}
683
684// ---- Coverage Support (when enabled) ----
685
686#[cfg(feature = "coverage")]
687pub use coverage::{
688    wasm_get_lcov_report_len, wasm_get_lcov_report_ptr, wasm_init_coverage, COV_HITS_PTR,
689    COV_MAP_LEN, COV_MAP_PTR,
690};
691
692// ============================================================================
693// Vertex Array Object Exports
694// ============================================================================
695
696#[no_mangle]
697pub extern "C" fn wasm_ctx_create_vertex_array(ctx: u32) -> u32 {
698    webgl2_context::ctx_create_vertex_array(ctx)
699}
700
701#[no_mangle]
702pub extern "C" fn wasm_ctx_delete_vertex_array(ctx: u32, vao: u32) -> u32 {
703    webgl2_context::ctx_delete_vertex_array(ctx, vao)
704}
705
706#[no_mangle]
707pub extern "C" fn wasm_ctx_bind_vertex_array(ctx: u32, vao: u32) -> u32 {
708    webgl2_context::ctx_bind_vertex_array(ctx, vao)
709}
710
711#[no_mangle]
712pub extern "C" fn wasm_ctx_is_vertex_array(ctx: u32, vao: u32) -> u32 {
713    webgl2_context::ctx_is_vertex_array(ctx, vao)
714}
715
716// ============================================================================
717// Renderbuffer Exports
718// ============================================================================
719
720#[no_mangle]
721pub extern "C" fn wasm_ctx_create_renderbuffer(ctx: u32) -> u32 {
722    webgl2_context::ctx_create_renderbuffer(ctx)
723}
724
725#[no_mangle]
726pub extern "C" fn wasm_ctx_bind_renderbuffer(ctx: u32, target: u32, renderbuffer: u32) -> u32 {
727    webgl2_context::ctx_bind_renderbuffer(ctx, target, renderbuffer)
728}
729
730#[no_mangle]
731pub extern "C" fn wasm_ctx_delete_renderbuffer(ctx: u32, renderbuffer: u32) -> u32 {
732    webgl2_context::ctx_delete_renderbuffer(ctx, renderbuffer)
733}
734
735#[no_mangle]
736pub extern "C" fn wasm_ctx_renderbuffer_storage(
737    ctx: u32,
738    target: u32,
739    internal_format: u32,
740    width: i32,
741    height: i32,
742) -> u32 {
743    webgl2_context::ctx_renderbuffer_storage(ctx, target, internal_format, width, height)
744}
745
746#[no_mangle]
747pub extern "C" fn wasm_ctx_framebuffer_renderbuffer(
748    ctx: u32,
749    target: u32,
750    attachment: u32,
751    renderbuffertarget: u32,
752    renderbuffer: u32,
753) -> u32 {
754    webgl2_context::ctx_framebuffer_renderbuffer(
755        ctx,
756        target,
757        attachment,
758        renderbuffertarget,
759        renderbuffer,
760    )
761}