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

Kevin Rogovin ([email protected]) [email protected]
Mon Jul 20 13:04:01 PDT 2020


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





More information about the public_webgl mailing list