9
votes

Question: Why does the same amount of pixels take dramatically less video memory if stored in a square texture than in a long rectangular texture?

Example: I'm creating 360 4x16384 size textures with the glTexImage2D command. Internal format is GL_RGBA. Video memory: 1328 MB.

If I'm creating 360 256x256 textures with the same data, the memory usage is less than 100MB.

Using an integrated Intel HD4000 GPU.

1
I'm not 100% sure but I think it has to do with how OpenGL handles the pixel data with their glTexture Calls. When the Images are square I think it has to do with power of 2 when it stores the data in the back buffer to be ready for rendering. - Francis Cugler
Are you generating mipmaps? I think you don't, but just to be sure ;) - Mars
@Mars: You're right, forgot to precise that I'm NOT using mipmaps. - Szak1
@FrancisCugler: As you suggest, the answer is probably implementation-specific, but looking at forums, the consensus seems to be that as long as the dimensions are powers of 2, there's no performance drawback of non-square textures. - Szak1
The easiest way would be to try it on machine with different hardware, preferably with dedicated GPU. Using which version of OpenGL are you testing this? 4.0? - Mars

1 Answers

9
votes

It's not about the texture being rectangular. It's about one of the dimensions being extremely small.

In order to select texels from textures in an optimal fashion, hardware will employ what's known as swizzling. The general idea is that it will restructure the bytes in the texture so that pixels that neighbor each other in 2 dimensions will be neighbors in memory too. But doing this requires that the texture be of a certain minimum size in both dimensions.

Now, the texture filtering hardware can ignore this minimum size and only fetch from pixels within the texture's actual size is. But that extra storage is still there, taking up space to no useful purpose.

Given what you're seeing, there's a good chance that Intel's swizzling hardware has a base minimum size of 32 or 64 pixels.

In OpenGL, there's not much you can do to detect this incongruity other than what you've done here.