[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] Re: WEBGL_get_buffer_sub_data_async

Using MapBuffer to read back data from the GPU is problematic at least in Chrome. In this browser the graphics pipeline is very deep, and it's unworkable to synchronize _javascript_ execution with the GPU process.

The WebGL working group gave this some thought and came up with the idea to expose MapBuffer, but that GL_MAP_UNSYNCHRONIZED_BIT would be required if GL_MAP_READ_BIT were set, making the map operation asynchronous all the time, in all browsers. Unfortunately this is incompatible with the ES 3.0 spec; GL_MAP_READ_BIT is exclusive. We could paper over this difference, but there's a reason UNSYNCHRONIZED is incompatible with READ; drivers only know to invalidate caches when the MapBuffer call returns, not at some arbitrary later point. Cache invalidation wouldn't be necessary in _javascript_ or WebAssembly – a copy would be required into the destination TypedArray, which at that point is CPU-to-CPU – but it would still be a semantic difference compared to native ES 3.0. C++ code bases compiled with WebAssembly would have to be modified to add Emscripten-only code paths, defeating the purpose.

At this point the Chrome team has customers requesting WEBGL_get_buffer_sub_data_async so I am concretely requesting to move it to community approved. It is unlikely that other browsers will implement it, but that's the purpose of extensions. It will provide a tangible benefit for readbacks on Chrome, and the chance for users to write an alternative code path to take advantage of it.

In future specs of lower-level, more explicit APIs, the issues with mapping buffers for reading will have to be revisited.


On Sun, Feb 5, 2017 at 2:23 PM, Jukka Jylänki <jujjyl@gmail.com> wrote:
From the "web as a compilation target" side of the world, there's a couple of requests to WebGL and extensions like this:
   - have the entry points generate no garbage (like mentioned above already)
   - don't require yielding back from the GL render loop to use the feature (native apps like to spin their own render loops, which would be cool to get going in Web Workers one day, but needing to yield to event loop to receive a message from WebGL would hinder this)
   - have 1:1 mapping counterpart to native so code porting is easy (does native side have the same problem? if so, what did native do to solve this problem? if not, why does only the web have such a problem?)

I wonder about the original rationale and the underlying problem, which motivated crafting this extension? Would incorporating a mirror of an existing GLES3 extension to WebGL 2 solve the same problem?


2017-02-05 7:28 GMT+02:00 Maksims Mihejevs <max@playcanvas.com>:
+1 to non-promise approach.

On 4 Feb 2017 7:24 p.m., "Florian Bösch" <pyalot@gmail.com> wrote:
So anyway, I'm not against fences per se, can we drop the promise and go for fences for the obvious benefits of not having to create a promise for every single readback?

On Fri, Feb 3, 2017 at 8:28 PM, Florian Bösch <pyalot@gmail.com> wrote:
The problem of any GC'ing is that despite years of promises that GC'ing will get better, it's still in the realm of dropping several frames. This is a cheapening inconvenience for ordinary WebGL apps that just make them look unpolished, but it's a crushing burden on WebVR apps where frame drops are painfully obvious to every user all the time.

Everything the WebGL API does potentially one or multiple times per frame should have guarantees not to incur GC overhead. And by extension, everything you'd usually end up needing to do with those things that you'd do one or multiple times per frame should have guarantees to have no GC overhead (such as sticking things into lists).

It would've been easier if WebGL followed ES'es principle of returning integers instead of objects. Integers are nicely hashable, and they have no GC overhead. Also lists of integers are treated preferentially by the JIT...