gpujs / gpu.js

GPU Accelerated JavaScript
https://gpu.rocks
MIT License
15.04k stars 648 forks source link

Half precision support #605

Open RobinKa opened 4 years ago

RobinKa commented 4 years ago

Currently my electromagnetics simulator using GPU.js doesn't work on iPad 6 and other devices that don't support single precision because unsigned does not seem accurate enough. However I looked into how others support it and I saw this fluid simulation uses half precision textures which also worked on iPad 6. Is it possible to support this in GPU.js?

robertleeplummerjr commented 4 years ago

It could be, but I just haven't had time to add it. If someone wanted to add it (hint hint, you) I'd be up for guiding them.

This would also boost performance a great deal.

RobinKa commented 4 years ago

As an initial attempt / experiment I tried changing the texImage2D calls to use gl.getExtension("OES_texture_half_float").HALF_FLOAT_OES instead of gl.FLOAT where necessary (in kernel's _setupOutputTexture and kernel-values' updateValue). The last argument, where non-null, also needed to be converted to Uint16array first instead of Float32array. This seems to work fine on Desktop and on my phone (which already supported float32 textures anyway). On the iPad6 I now don't get the float32 support error anymore. However any texImage2D call with non-null data argument (such as in single-array.js updateValue()) fails with GL error invalid operation. I also tried using texSubImage2D instead but that yielded the same result. I checked the half-float conformance test and indeed a lot of these fail on the iPad. I also found a relevant ticket about this issue here. While the ticket is about Safari I was using Chrome but Safari didn't work either (although I haven't looked at the logs since it is a pretty annoying process).

// Edit: for my own use-case where I had everything as textures except for some things such as position that i passed as a number[] with 2 elements, I could just pass those 2 numbers as separate arguments and now it works on the iPad! Of course this isn't a solution for GPU.js itself though.