Maximal WebGL2 ram a Rust/wasm32 program can use on latest Chrome?

Apologies if this is borderline off topic, but I suspect many Rust programmers doing graphics/compute intensive wasm32/webgl have run into this:

Questions:

  1. What is the maximal amount of RAM (measured in, say, vertex buffer objects) can a Rust/wasm32 program use in WebGL2 on latest Chrome ?

  2. Does this memory count towards the wasm32 4GB limit ?

  3. Does the upcoming wgpu (WebGPU - Chrome Platform Status ) change this ?

In short, what are the "gpu RAM" limits one runs into with Rust/wasm32 + WebGL2 in latest Chrome?

This isn't affected by wasm. Rather, web_sys is translated into glue that calls into the JS web API (for now at least)

More specifically, you can call get_parameter from web_sys: WebGl2RenderingContext in web_sys - Rust

Some useful parameters: WebGL1 and WebGL 2

As far as I am aware WASM has no direct API to any webgl, or pretty much anything else, in the browser. It just runs in it's own memory space and has to interact with the outside world via Javascript, Which has the actual API's.

For example here: Introduction - The `wasm-bindgen` Guide I read:

wasm-bindgen , a Rust library and CLI tool that facilitate high-level interactions between wasm modules and JavaScript.

and:

Notable features of this project includes:

I conclude that your WebGL has whatever memory it has via JS. Same as ever.

What impact that may have on the amount of memory that can be used by WASM I have no idea about.

Here's another angle to think about this...

You can load an ArrayBuffer, and pass that to buffer_data_with_array_buffer_view, all without allocating any memory in wasm itself. The limits here are going to be identical to whatever plain JS and WebGL can do.

Similarly, you can create texture objects from HtmlImageElements, within wasm code, without actually loading those images as bitmap data into wasm memory.

Otoh if you want to load a huge Vec<u8> on the Rust side, you are limited by wasm memory constraints, whether you intend to upload that as a WebGL buffer or not.

Based on this article...

  • The max texture size allowed

    2048 or 4096 seems to be reasonable limits. At least as of 2020 it looks like 99% of devices support 4096 but only 50% support > 4096.

    Note: the max texture size is the maximum dimension the GPU can process. It doesn't mean that GPU has enough memory for that dimension squared (for a 2D texture) or cubed (for a 3D texture). For example some GPUs have a max size of

    1. But a 3D texture 16384 on each side would require 16 terabytes of memory!!!
  • The maximum number of vertex attributes in a single program

    In WebGL1 the minimum supported is 8. In WebGL2 it's 16. If you're using more than that then your code will fail on a machine with only the minimum

  • The maximum number of uniform vectors

    These are specified separately for vertex shaders and fragment shaders.

    In WebGL1 it's 128 for vertex shaders and 16 for fragment shaders In WebGL2 it's 256 for vertex shaders and 224 for fragment shaders

@Michael-F-Bryan : I'm a big fan of webgl2fundamentals, and that particular article covers many interesting limits. However, I don't think there is enough information there to compute : "how much total RAM/data can we stuff in webgl2 vertex buffer objects"

Can you please confirm if I understand the high level bits you are stating ?

  1. we can upload to a VertexBufferObject from wasm memory (Vec<u8>) or non-wasm memory (plain js ArrayBuffer)

  2. ArrayBuffer do not count vs wasm limit.

  3. Even in the Vec<u8>, after the upload to vertex buffer object, we can free the Vec<u8> rust-side, at which point it no longer counts against wasm32 limit either.

@dakom: Please correct me if I am wrong, although many useful parameters are provided, we don't have enough information to compute how much total data we can stuff into vertex buffer objects.

Correct. Though the way you upload from wasm memory is by creating an TypedArray view, like Uint8Array in js_sys - Rust ... see the notes there, it's wildly unsafe, but doesn't do any unnecessary cpu-side copy. You'd use that to create a temporary wrapper for uploading wasm bytes to the GPU, so there's no real need to worry about keeping it around or adding a Drop wrapper.

I don't feel confident to say 100%, but that's my guess too. The parameter getters are more for loading the hardware specs or configuration, not so much the current available memory. You can see a lot of the info available at WebGL Report