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

Jeff Gilbert ([email protected]) [email protected]
Mon Jul 20 13:39:09 PDT 2020


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
-----------------------------------------------------------





More information about the public_webgl mailing list