emscripten-core / emscripten-core/emscripten

glTex(Sub)ImageX functions cannot upload float data from memory beyond 2GB address space

Open
#15,416 14 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Hi,
when using the "-s MAXIMUM_MEMORY=4GB" flag i have run into issues with the glTex(Sub)ImageX functions. As soon as an address beyond the 2GB address space is passed as the pixels parameter and the type parameter is GL_FLOAT the following error is reported: "WebGL: INVALID_OPERATION: texImage2D: ArrayBufferView not big enough for request".
The reason for this issue is the usage of the arithmetic right shift operator (>>) in the generated .js file. When passing an address into e.g. glTexImage2D it is being shifted by 2 bit by the javascript code if float data is supposed to be uploaded. Note that the address is stored as a signed 32 bit signed integer on the javascript side, so any address beyound 2GB will be a negative value. Right shifting negative values via >> will add 1 to the left and thus mess up the intention of the shift.
A potential fix to this problem is modifying the library_webgl.js and library_webgl2.js files in the emscripten repository by replacing several ">>" operators with ">>>" operators. These will be able to handle negative integer values as intended. So for example the line

`GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap));`

would have to be changed to

`GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, pixels >>> heapAccessShiftForWebGLHeap(heap));`

There are probably quite a few other places where this change would be necessary to properly support the "-s MAXIMUM_MEMORY=4GB" option. Basically all the texture data upload functions which accept data as something else than a simple byte array will be affected.

I have attached a simple demo program which illustrates this problem
[demo.zip](https://github.com/emscripten-core/emscripten/files/7466574/demo.zip)
It has been built by:
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.33 (0e68b98e85a1644a7224c360fa6cb21bea5dc33d)
clang version 14.0.0 (https://github.com/llvm/llvm-project 1c05c52de2177a328b7d2d07b697af67eb9f8122)
Target: wasm32-unknown-emscripten
Thread model: posix
```

To build it yourself use something like
`emcc -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB --memoryprofiler -o test.html test.cpp`

The program initializes opengl via egl, allocates 3GB of memory and then tries to upload float data into a texture which fails with the aforementioned error. If the float array used for upload is being allocated before allocating the 3GB of memory everything works as expected.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.