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

Re: [Public WebGL] WebGL2 and no mapBuffer/mapBufferRange



If using WRITE without INVALIDATE is slow, people won't use it.

It actually seems like OoP implementations could get some good perf wins here with MAP_READ and (MAP_WRITE|MAP_INVALIDATE_*).

On Tue, Mar 17, 2015 at 10:35 AM, Zhenyao Mo <zmo@chromium.org> wrote:
On Mon, Mar 16, 2015 at 11:48 PM, Florian Bösch <pyalot@gmail.com> wrote:
> On Mon, Mar 16, 2015 at 11:47 PM, Zhenyao Mo <zmo@chromium.org> wrote:
>>
>> In such implementations, INVALIDATE flag means you don't have to read out
>> the
>> content of the buffer before writing to it, so it makes some
>> significant perf gain.
>
> I don't follow how you'd have to read back the (GPU residing) buffer at all,
> in fact, you're forbidden from doing so. You cannot map a buffer with
> MAP_READ_BIT and MAP_INVALIDATE_RANGE_BIT or MAP_INVALIDATE_BUFFER_BIT. If
> you set the invalidate flag, it just means that the driver is allowed to
> discard the previous backing store of either that range, or the entire
> buffer until data is written to it again. In practice that's not what
> drivers do, because the backing store is a continous chunk of VRAM and
> unless you deallocate it, it's just gonna hang around with whatever's been
> written to it. The specification is overly vague on the point of driver
> behavior for stuff it defines as "undefined".

With WRITE bit, without INVALIDATE bit, for out-of-process
implementations, we have to append READ bit internally, and read out
the whole buffer range, send it to the js, so it can be written to
partially.  Otherwise, how can you write back in unmap time? unless
you keep track of which elements in the buffer range have been written
to and which remain untouched.

>
>>
>> For in-process WebGL implementations, it's
>> more of a burden, that you have to initialize the entire returned
>> buffer range to avoid undefined values, unless it can be guaranteed
>> the entire buffer range will be written into.
>
> You could define the behavior as issuing an error if a drawing operation
> uses a piece of buffer that's been invalidated and hasn't been overwritten.
> Depending on how the users uses mapBuffer[Range] this can result in a large
> table of valid/invalid regions, checking against which at
> drawElements/Arrays would be expensive (although search can be accelerated
> with a suitable data structure).
>
> On the whole, I don't see a good usecase for the invalidate_range/buffer
> bits. If you don't care about the data already in the buffer, there's no
> reason to indicate with those bits that you don't care, you simply don't
> draw with it. I'd find it more palatable to drop the INVALIDATE_RANGE/BUFFER
> flags as a workaround to having to introduce expensive machinery to keep
> track of invalid ranges, than having to throw out the whole mapBuffer[Range]
> functionality (I actually haven't seen anybody use INVALIDATE_* in
> practice).

For out-of-process implementations, using the invalidate bit makes a
huge per difference.  for Map call, it doesn't have to wait for the
service side to return the buffer range, it can just allocate a buffer
and initialize to 0 and allow js to write to it.  Otherwise, it's a
blocking call until service side responded with the readback buffer
data.