Are We Stuck At 16Bit Graphics?


Exophase said:
hedwards said:
Admittedly, I could be wrong, but I thought those extra 8 bits were used for alpha. Or is that just when it comes to graphics utilities as the extra bits aren't really being used anyways.

EDIT: 8 for red, 8 for green, 8 for blue and 8 for alpha.

A display doesn't usually have any use for an alpha channel. Framebuffers may have alpha bits if a renderer is using destination alpha for alpha blending operations. Also may have them if they're overlaid in hardware with per-pixel blending.
That would be my problem, I was thinking about the software side rather than the hardware end of things. Which aren't equal in may cases. And you're definitely correct about the 16bit words. I remember screwing around a bit with those previously, and you generally can pack a couple of them into 32bits rather than only getting 1 of them into 32 bits whether it's 17bit or 32.
 
Last edited by a moderator:
Exophase said:
32bpp will almost never be more efficient than 16bpp. Most 32-bit CPUs have the ability to to write individual 16bit words, and writes to areas like video memory are usually write buffered and often write combining (are in the case of Cortex-A8). So with 16bpp you don't have any overhead and you have a lower memory bandwidth footprint both in writing the framebuffer and for the display controller to read it, lower cache utilization for anything intermediate too. The difference will be minor though.

The only area in which 32bit may be more efficient is in doing pixel math using SIMD, since the channels align better with the vector words. But this is often negated again by higher data density.. all depends on how the operations are laid out.

I should know better than to doubt you in areas of code, but to my mind twiddling RGB values will be faster in 32bpp than in 16bpp. Copying pixels from one area to another would be quicker in 16bpp (Assuming you're copying an even number of pixels in each row), unless the rep instructions have gotten a lot more efficient in the last few years.

D.
 
Last edited by a moderator:
Dunny said:
I should know better than to doubt you in areas of code, but to my mind twiddling RGB values will be faster in 32bpp than in 16bpp.

It depends what you mean by twiddling values. Blending, for instance, is faster in 16bpp than what you have in mind. I imagine you're referring to the savings gained by byte addressing vs packing and unpacking values. We'll assume that packing 32bpp is never faster than packing 16bpp, at least on "normal" architectures (let's ignore the byte segmentation of registers on x86, because using them actually tends to be a pipeline hazard).

Consider the following blending example:

Code:
// Blend (pixel_a * blend_a) + (pixel_b * blend_B), blend_a and blend_b are 0 to 16, result is assumed to not saturate

// 16-bit RGB 565 version:
// source_a, source_b, and dest are u16 *
pixel_a = *source_a;
pixel_b = *source_b;
pixel_a_expand = (pixel_a & (0x1F | (0x1F << 11)) | ((pixel_a & (0x3F << 5)) << 16);
pixel_b_expand = (pixel_b & (0x1F | (0x1F << 11)) | ((pixel_b & (0x3F << 5)) << 16);
pixel = ((pixel_a_expand * blend_a) + (pixel_b_expand * blend_B) >> 4) & (0x1F | (0x1F << 11) | (0x3F << (5 + 16)));
*dest = pixel | (pixel >> 16);

// 8-bit 0RGB 8888 version, using byte addressing:
// source_a, source_b, and dest are u8 *
dest[0] = ((source_a[0] * blend) + (source_b[0] * blend)) >> 4;
dest[1] = ((source_a[1] * blend) + (source_b[1] * blend)) >> 4;
 dest[2] = ((source_a[2] * blend) + (source_b[2] * blend)) >> 4;

16-bit version is 2 loads, 5 ands, 3 ors, 3 shifts, 2 32x8 multiplies, and 1 store.
32-bit version is 6 loads, 3 adds, 3 shifts, 6 8x8 multiplies, and 3 stores.

On ARM two of the shifts in the 16-bit version can be folded. Of course, which one is faster depends on the architecture, but generally it'll be the 16-bit version, especially if the arch can't issue multiplies every cycle (although, you might get some faster issues multiplies down the 8x8 path). I won't look into data dependencies because you're probably not only doing one pixel in isolation.

Dunny said:
Copying pixels from one area to another would be quicker in 16bpp (Assuming you're copying an even number of pixels in each row), unless the rep instructions have gotten a lot more efficient in the last few years.

Any realistic case is going to be memory bandwidth bound (hopefully not memory latency bound, if the write buffering is any good). Block transfer instructions only really help you if there's no write combining on the write buffering.
 
Last edited by a moderator:
I do hope this is fixed before I get my Pandora - some of the non-emulator uses which I expect to use it for include viewing video, and images (such as pictures I just took).

I'm also surprised (and annoyed) that 16bpp was implemented first, even if it is slightly faster. 24bpp/32bpp has been the standard since video ram quotas got above 2MiB (such as 3MiB for 1024x768) in about the mid 1990s. (Come to think of it, how much v-ram does the Pandora have? is it shared with the system ram? adjustable?)
 
davidgro said:
I'm also surprised (and annoyed) that 16bpp was implemented first, even if it is slightly faster. 24bpp/32bpp has been the standard since video ram quotas got above 2MiB (such as 3MiB for 1024x768) in about the mid 1990s. (Come to think of it, how much v-ram does the Pandora have? is it shared with the system ram? adjustable?)

Shared/system RAM. How it's allocated probably depends on the X11 driver, but when using fbcon you can allocate over syscalls.
 
Last edited by a moderator:
paeryn said:
Also note that at the moment the PowerVR drivers for OGL:ES only work in 16 bit.
just wanted to note that the above may not be such a big deal, depending on the effective bpp of the SGX tile buffer in this case.

from what i remember, PVR have historically had true color tile buffers, so all fb blend operations work at 24/32bpp fidelity, and any color downgrading happens only at the stage of resolving the tile buffer to the frame buffer.
 
Last edited by a moderator:
Back
Top