14

I am working on a OpenGL ES 2.0 shader and I have tightly packed data e.g. three 5-bit unsigned integers within a block of two bytes. To unpack this data I obviously need bit-shifting, but this is not supported in OpenGL ES Shading Language (see page 29 http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf)

Consequently I perform a number of *2 and /2 operations to emulate bit shifting.

Does anyone know a more efficient/elegant way to do this? Is there a trick I am not aware of?

Thanks!

Lars Schneider
  • 5,530
  • 4
  • 33
  • 58
  • are you sure the compiler is not optimising *2 and /2 to shift operators? – Mitch Wheat Aug 12 '10 at 10:07
  • Given the two answers you have, can you define if you are looking for improved performance or improved readability? I have a feeling that you aren't going to be able to get both at the same time. – Thomas Owens Aug 12 '10 at 10:17
  • Readability is nice, but performance is the most important thing. – Lars Schneider Aug 12 '10 at 10:31
  • 1
    Your link goes to the full GLSL spec, however OpenGL ES actually uses GLSL ES as the shader language; the spec is at http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf - this doesn't affect your question, GLSL ES has even fewer features :) but you'll likely trip up elsewhere if you keep using the full spec – moonshadow Jun 08 '11 at 10:50

4 Answers4

6

If you are performing multiple shifts, you can use power operations. A bit shift is a multiplication or division by 2n, and a power operation would be more readable than multiple multiplication or division operations, I think, but I'm not sure about the performance. I suppose this is a more elegant solution, but probably not a more efficient one.

Thomas Owens
  • 114,398
  • 98
  • 311
  • 431
3

Depending on what you are doing, these threads may be of some use:

GLSL: packing a normal in a single float link

Packing multiple floats into a single float value link

Packing floats to various bit depth targets (have to search the OpenGL.org forum as Stack overflow does not allow more than 2 links for new users)

1

I've never used OpenGL, but the most efficient method would be a 16 bit lookup table for each type if your environment supports it. You would need to populate the table once on startup, but this should be very quick. You could use seperate tables for each type or a 2 dimensional table, eg, theTable[65536][3].

jacknad
  • 13,483
  • 40
  • 124
  • 194
0

From your question I'm not sure, but you can use & (bit-and), right? Then it should be pretty fast to write:

processing(variable & 11111); processing(variable & 1111100000); (...)

Those bit-masks should be saved as integral constants, of course.

Huge
  • 661
  • 7
  • 14