[Public WebGL] glReadPixels (to buffer object) and endianness

Kevin Rogovin ([email protected]) [email protected]
Mon Jul 20 15:57:26 PDT 2020


Hi,

I guess I did not explain the use case adequately: I get a 33%
performance improvement with using an index buffer because of post
vertex shader cache. 33% is nothing to sneeze at.

It sounds like the answer s what I had assumed but did not want to be
true: endianess checking is required if
GL_IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for a GL_R32UI is not
GL_RED_INTEGER/GL_UNSIGNED_INT.

-Kevin

On Mon, Jul 20, 2020 at 11:40 PM Jeff Gilbert ([email protected])
<[email protected]> wrote:
>
>
> Well you can use ReadPixels(GL_RED_INTEGER, GL_UNSIGNED_INT) where
> available, otherwise change your uint->RGBA packing shader based on
> host endianess.
>
> I think you should strongly consider vertex-pulling in your case,
> bypassing the fixed-function index fetch.
>
> On Mon, Jul 20, 2020 at 1:05 PM Kevin Rogovin
> ([email protected]) <[email protected]> wrote:
> >
> >
> > Hi,
> >
> > My use case is the reverse. A fragment shader does:
> >
> > uint varying_idx;
> > vec4 out_value;
> > void main(void)
> > {
> >    uvec4 raw;
> >
> >    raw.r = varying_idx >> 24u;
> >    raw.g = (varying_idx >> 16u) & 0xFF;
> >    raw.b = (varying_idx >> 8u) & 0xFF;
> >    raw.a = varying_idx & 0xFF;
> >
> >   // add a little fudge to make sure...
> >   out_value = (vec4(raw) + vec4(0.1)) / 255.0;
> > }
> >
> > and then the GL calls are something like:
> >
> > glBindBuffer(GL_PIXEL_PACK_BUFFER, m_index_bo);
> > glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
> >
> > which gives me an index buffer generated by the GPU. The catch is that
> > this assumes that the byte 0 corresponds to the highest 8 bits and so
> > on which appears to me to be a very endian specific thing. This is the
> > heart of the question, is portability actually guaranteed for this
> > use(or really abuse)?
> >
> > The only way I see to make it perfectly portable would be to make the
> > fragment shader render to an GL_R32UI buffer, and then do:
> >
> > // this will make what we want strided 4 essentially
> > glBindBuffer(GL_ARRAY_BUFFER, m_staging_buffer);
> > glReadPixels(0, 0, w, h, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NULL);
> >
> > //undo the strider
> > // shader is simple vertex shader that just echos a single scalar uint attribute
> > // and the VAO is set with glVertexAttribIPointer(0, count = 1, type =
> > GL_UNSIGNED_INT, GL_FALSE, 4 * sizeof(GLuint), NULL);
> > glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_index_buffer)
> > glBeginTransformFeedback(m_xf);
> > glDrawArrays(0, number_of_indices_to_capture);
> >
> > this is awful because it uses 8 or 12 times as much bandwidth as a
> > directly would give me (or if GLES3/WebGL2 guaranteed to support
> > glReadPixels(0, 0, w, h, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
> >
> > -Kevin
> >
> > On Mon, Jul 20, 2020 at 9:57 PM Jeff Gilbert ([email protected])
> > <[email protected]> wrote:
> > >
> > >
> > > FWIW, ES3 and WebGL2 potentially do support ReadPixels with
> > > GL_UNSIGNED_INT via GL_IMPLEMENTATION_COLOR_READ_FORMAT/TYPE, which
> > > you can query for your current READ_FRAMEBUFFER/ReadBuffer. (though
> > > this support is driver-dependent)
> > >
> > > If I understand your last question, it would work. E.g. you can pass
> > > your MSB in R (LSB in A) for RGBA/UNSIGNED_BYTE, then reassemble it as
> > > `(R * 0xff) << 24 | ...` in the shader.
> > >
> > > On Mon, Jul 20, 2020 at 6:40 AM Kevin Rogovin
> > > ([email protected]) <[email protected]> wrote:
> > > >
> > > >
> > > > Hi all,
> > > >
> > > >  This is a question on what is the guaranteed behaviour related to an
> > > > endianness. The situation: I plan to generate a LARGE index buffer and
> > > > using transform feedback is not suitable.  The plan is to essentially
> > > > rasterize the indices. For desktop GL, this is easy, the render target
> > > > would be GL_R32UI and glReadPixels would be passed GL_RED_INTEGER with
> > > > GL_UNSIGNED_INT. However, GLES3 and this WebGL2 do not allow that
> > > > combo in glReadPixels(); indeed for reading from such a buffer would
> > > > require GL_RGBA_INTEGER which would make one want to read the index
> > > > buffer with a stride of 4. What I'd like to do is to rasterize an
> > > > GL_RGBA8 fixed point buffer, do the right thing to convert each 8-bit
> > > > chunk into a vec4 tuple and then call glReadPixels with GL_RGBA,
> > > > GL_UNSIGNED_BYTE.  (Note that because of the rules associated to
> > > > GL_ELEMENT_ARRAY_BUFFER, the glReadPixels will write to a staging
> > > > buffer which is then copied to the index buffer). The question is:
> > > > will the "bit-casting" of the RGBA8-tuple data to GL_UNSIGNED_INT be
> > > > platform independent? I would really like to avoid the idea of reading
> > > > the 32-bit values as (GL_RGBA_INTEGER, RL_UNSIGNED_BYTE) and issuing
> > > > transform feedback as that adds a lot more data  copy and bandwidth.
> > > >
> > > > Best Regards,
> > > >  -Kevin Rogovin
> > > >
> > > > -----------------------------------------------------------
> > > > You are currently subscribed to [email protected]
> > > > To unsubscribe, send an email to [email protected] with
> > > > the following command in the body of your email:
> > > > unsubscribe public_webgl
> > > > -----------------------------------------------------------
> > > >
> > >
> > > -----------------------------------------------------------
> > > You are currently subscribed to [email protected]
> > > To unsubscribe, send an email to [email protected] with
> > > the following command in the body of your email:
> > > unsubscribe public_webgl
> > > -----------------------------------------------------------
> > >
> >
> > -----------------------------------------------------------
> > You are currently subscribed to [email protected]
> > To unsubscribe, send an email to [email protected] with
> > the following command in the body of your email:
> > unsubscribe public_webgl
> > -----------------------------------------------------------
> >
>
> -----------------------------------------------------------
> You are currently subscribed to [email protected]
> To unsubscribe, send an email to [email protected] with
> the following command in the body of your email:
> unsubscribe public_webgl
> -----------------------------------------------------------
>

-----------------------------------------------------------
You are currently subscribed to [email protected]
To unsubscribe, send an email to [email protected] with
the following command in the body of your email:
unsubscribe public_webgl
-----------------------------------------------------------





More information about the public_webgl mailing list