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

Re: [Public WebGL] Index Validation and using the same buffer for both GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER



On Wed, Jan 13, 2010 at 3:34 PM, Chris Marrin <cmarrin@apple.com> wrote:
>
> On Jan 13, 2010, at 3:09 PM, Vladimir Vukicevic wrote:
>
>>>> ...The case that will fail is:
>>>>
>>>>   - Bind the buffer to ARRAY_BUFFER
>>>>   - Use bufferData to upload unsigned byte or short data which will be treated as indices
>>>>   - Unbind the buffer
>>>>   - Bind the buffer to ELEMENT_ARRAY_BUFFER
>>>>   - Call drawElements, referring to the previously uploaded data as indices
>>>>
>>>> Because the buffer was bound to ARRAY_BUFFER when the data was uploaded, the WebKit index validation code won't keep a client-side copy.
>>>>
>>> I'm not sure what you've just done is valid. I believe (and my implementation reflects this) that ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER are two separate bind points and therefore constitute different buffer objects. For instance, if you do what you propose above, the ELEMENT_ARRAY_BUFFER you've bound would contain no data. Why else would you pass target to bufferData()?
>>>
>>
>> BufferData() takes the target argument to identify which buffer you want to modify: the VBO itself is bound to either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER, and then BufferData operates on either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.  The VBO (ARB_v_b_o extension) spec has this to say:
>>
>>>     Buffer objects created by binding an unused name to ARRAY_BUFFER_ARB
>>>     and to ELEMENT_ARRAY_BUFFER_ARB are formally equivalent, but the GL
>>>     may make different choices about storage implementation based on
>>>     the initial binding.  In some cases performance will be optimized
>>>     by storing indices and array data in separate buffer objects, and by
>>>     creating those buffer objects with the corresponding binding points."
>>
>> This implies to me that you really should use the right binding, but that using the wrong one has no effect other than a possible performance penalty.
>>
>>>> Possible solutions include:
>>>>
>>>>   1. Keep a client-side copy of *all* data uploaded to buffer objects. Very wasteful of memory.
>>>>   2. Lazily pull back data from buffer objects bound to ELEMENT_ARRAY_BUFFER using glMapBuffer when they are referenced from drawElements. Once client-side data exists for a buffer object, always keep it in sync during bufferData and bufferSubData calls.
>>>>   3. Forbid binding the same buffer object to the ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER points in the WebGL spec.
>>>>
>>>> We should keep in mind that hardware and drivers are moving in the direction where index clamping will be done in hardware.
>>>>
>>>> I'm not sure whether solution (3) would impact any real-world apps; I haven't seen any demos which would be affected.
>>>>
>>>> Personally I would prefer (3), with (2) as an alternative, but not (1).
>>>>
>>
>> I would be fine with 3; we can always figure out how to relax this in a future version if it becomes needed.
>
>
> Ok, let me understand. Will we forbid binding an object to both and ARRAY_BUFFER and an ELEMENT_ARRAY_BUFFER at the same time or ever? If it's the second case that means if I ever call bindBuffer(ARRAY_BUFFER, buf), I can never, ever call bindBuffer(ELEMENT_ARRAY_BUFFER, buf)? That's not so bad I suppose. We'd just need a flag in the WebGLBuffer object that starts out as NONE and then gets set to ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER on the first bindBuffer call. If you want to change, you'd need to toss that WebGLBuffer and create a new one.
>
> If we did that, would my current index validation scheme then work?

Yes, this is exactly the proposal and yes, if we did this, your
current index validation code would work.

If we make this restriction we should explicitly call it out with its
own subsection in the spec.

-Ken

-----------------------------------------------------------
You are currently subscribe to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: