REV external formats

I’d like to confirm something I think I’m seeing in the spec and in driver behavior:


ORDER     FORMAT    TYPE
-------- ---------- -----------
RGBA      RGBA      UNSIGNED_BYTE
RGBA      RGBA      UINT_8_8_8_8_REV
BGRA      BGRA      UNSIGNED_BYTE
BGRA      BGRA      UINT_8_8_8_8_REV
ABGR      RGBA      UINT_8_8_8_8
ARGB      BGRA      UINT_8_8_8_8

Is this correct, if “ORDER” is the resulting memory order on a little-endian system (with GL_{PACK,UNPACK}_SWAP_BYTES = FALSE).

If so, I guess I’d always misunderstood the REV types. REV = reversed in memory, and non-REV = not reversed. Right?

…no, I’m thinking it’s not that simple. The non-REV types are laid out packed from msb -> lsb in the register, and then on little-endian the bytes are reversed when the word is written to memory. Same for REV types, except those are packed lsb -> msb in the register first.

So for instance, RGBA/UNSIGNED_INT_8_8_8_8 is

msb ----> RGBA <----- lsb

in the register, and then when written to memory, it’s flipped to:

low address —> ABGR <---- high-address.

So in this RGBA8 case (with type = UNSIGNED_INT_8_8_8_8*), REV is “not” byte reversed in memory (RGBA stays RGBA), while non-REV “is” byte-reversed in memory (RGBA becomes ABGR).

[QUOTE=Dark Photon;1287612]
So in this RGBA8 case (with type = UNSIGNED_INT_8_8_8_8*), REV is “not” byte reversed in memory (RGBA stays RGBA), while non-REV “is” byte-reversed in memory (RGBA becomes ABGR).[/QUOTE]
OpenGL 4.5 core profile specification, §8.4 (Pixel Rectangles), table 8.8 on p188.

Non-REV formats have the first component in the highest bits and the last component in the lowest bits, while REV formats are the the other way around.

So for 8_8_8_8, the REV/non-REV distinction corresponds to a big-endian architecture, i.e. 8_8_8_8_REV is byte-swapped on big-endian architectures, 8_8_8_8 is byte-swapped on little-endian architectures.

This might be a consequence of IRIX being big-endian. Or it might just be coincidence; the notion of packed formats being “byte-swapped” or not is only meaningful for 8_8_8_8; the other packed types don’t have a 1:1 mapping between fields and bytes (well, technically “octets”, but I don’t think there’s ever been an OpenGL implementation for architectures with other byte sizes).

Ok, thanks for the confirmation.

In order to prevent similar confusion in the future, I’ve updated the:

[ul]
[li]Pixel Transfer (OpenGL wiki) [/li][/ul]
page to better describe the how component and byte ordering works with format, type, *BYTE_ORDER, and client endianness (with examples).