Skip to main content
GameDev.net gamedev.net
🔒 Locked

BGRA As Pixel Format

Started by Deception666 Sep 13, 2008 at 1:51 AM 2 replies 19.3k views
Original Post
Deception666
Deception666
Because I've been tasked to try and increase performance out of our application at work, I've been doing some reading and found that OpenGL on Windows would prefer a call to upload a texture to look something like the following:

glTexImage2d(GL_TEXTURE_2D,
             0,
             GL_RGBA8,
             512, 512,
             0,
             GL_BGRA8,
             GL_UNSIGNED_BYTE,
             pData);

I understand that the card's driver would have to swizzle the incoming data if the format was specified as GL_RGBA8. This is where GL_BGRA8 gives you maximum throughput. Our application uses quite a bit of texture memory that not all of it is going to fit in VRAM. If GL_RGBA8 was used instead, does the driver only penalize your throughput once for uploading the data to the card since a swizzle is required, or does it penalize you if the texture has to be swapped out to system memory to make room for other data on the VRAM? I would assume that driver would continue to store the texture as the internal format while in system memory, but I just wanted to make sure.
Brother Bob
Brother Bob
Your question and statement about just changing parameters makes me believe you don't really understand the purpose of the third parameter and seventh and eighth parameter pair.

Third parameter specified only what color components you want the internal texture format to have. GL_RGBA only means you want four color channels. It doesn't say anything about HOW the internal texture is stored. It could very well be BGRA order.

Seventh and eighth parameter pair describes HOW the data is stored in system memory. GL_RGBA and GL_UNSIGNED_BYTE means that every component is an unsigned byte, and the image is stored in R, G, B and A order. GL_BGR and GL_SHORT means that each component is a signed short, and stored in B, G and R order.

Now, changing parameters the way I get the impression you are asking about makes no sense to me. Changing the third parameter is not an option, as the only valid four-channel format is GL_RGBA (ignoring numbers, as they only hint on the precision, not format). Changing seventh and eighth parameter pair also makes no sense, as it describes the physical data you pass. Change it, and you change the way OpenGL treats the image. For exaple, change GL_RGBA to GL_BGRA and blue will turn red, and vice versa, becuase that is the result of telling OpenGL the colors are stored in another order.

If you want to speed up the texture upload you need to match the external format (the one you pass to glTexImage) with the internal format, which you do mention. But that requires you to not only pass a different constants to the seventh and eighth parameter pair, but also change the image data itself to match this new parameter pair. You cannot pass a RGBA image and just say it's a BGRA and expect it to work.
Deception666
Deception666
I am basing my information off of what NVidia's technical briefs are stating.

Quote:

For 8-bit textures, NVIDIA graphics cards are built to match the Microsoft GDI
pixel layout, so make sure the pixel format in system memory is BGRA.
Why are these formats important? Because if the texture in system memory is laid
out in RGBA, the driver has to swizzle the incoming pixels to BGRA, which slows
down the transfer rate. For example, in the case of glTexImage2D(), the
format argument specifies how to interpret the data that is laid out in memory (such
as GL_BGRA, GL_RGBA, or GL_RED); the internalformat argument
specifies how the graphics card internally stores the pixel data in terms of bits
(GL_RGB16, GL_RGBA8, and GL_R3_G3_B2, to name a few). To make matters
more confusing, OpenGL allows you to specify GL_RGBA as an internal format,
but this is taken to mean GL_RGBA8. It is always best to explicitly specify the
number of bits in the internal format. Refer to Table 1 to see the performance
impact of using non-optimal texture formats. Note, this is not the case with 16-bit
and 32-bit floating point formats.


http://http.download.nvidia.com/developer/Papers/2005/Fast_Texture_Transfers/Fast_Texture_Transfers.pdf

The paper might be a bit old, but I am assuming that technology has not changed that much.

I understand that the third parameter is an indication of what type of texture format internally you would like represented. NVidia or ATI could decide one day that GL_RGBA8 maps to something like GL_ABGR8. We ultimately do not know.

I am not a complete idiot and it sounds like you really did not read the question I was posing. I understand that I would need the data to match the internal format of the graphics card. The external data would need to be saved as BGRA if it were to match that of the internal format stated by NVidia. Not a big deal.

What I would like to know is if the graphics card needs to swap an image out to system memory, is the swap to system memory going to be as optimal as it gets and vice versa? I would assume so, and as I think about it now it would not make much sense for the swap to do anything other than be optimal.

Thanks
V-man
V-man
This is more important if you are updating the texture often or if you have lots of textures to upload, so if you want your startup time to be low, use GL_BGRA.
If GPU runs out of VRAM, it will swap out to RAM but I see no reason for it to swizzle to make it RGBA.

You made the mistake of calling it GL_BGRA8 which doesn't exist. You need GL_BGRA.

glTexImage2d(GL_TEXTURE_2D,             0,             GL_RGBA8,             512, 512,             0,             GL_BGRA,             GL_UNSIGNED_BYTE,             pData);

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.