Switching textures slow?

I’m relatively new to OpenGL and it’s taken me quite a while to figure out where the performance bottlenecks in it are. I thought I had them charted pretty good, until recently I read on a few places that switching textures is a slow operation on PowerVR hardware. Texture atlasses should alleviate the need for switches, but from reading the Apple OpenGLES performance guidelines and PowerVR’s “3D Application Development Recommendations” I don’t really see a recommendation to use texture atlasses to avoid switching. The suggestion to use texture atlasses is merely to reduce OpenGL calls, not explicitly about texture switches being extremely slow. Can anyone here at ImgTec shed some light on this matter?

Added: here’s an example of the type of information I find:

http://stackoverflow.com/questions/3212442/about-the-texture-switch-in-opengleszmippie2011-02-19 11:07:15

Hi zmippie,

Using glBindTexture shouldn't make any difference in performance besides what we've mentioned in our documentation, there is a small overhead but not a huge one. Some information out there seems to mention texture switching when using glTexture2D to reload textures which IS a slow call and should only be done when first initialising the app, for example as mentioned here: http://stackoverflow.com/questions/2682261/optimizing-texture-swapping-on-opengles-for-the-iphone

This would generally be a slow operation on any device as the call loads texture data into graphics memory which is universally costly.


However, as per our documentation, reducing gl calls is always a good idea, and so Texture Atlases can be useful in this respect. It can be much quicker to have textures packed into one texture atlas rather than switching between multiple, smaller textures. This is generally most useful when using sprites but can save time in all applications and may be worth adding to your apps, especially if you have many textures.


Hope this answers your question? Thanks,

Tobias2011-02-22 11:26:46

As Tobias says, the point here is that glBind calls to switch textures are OpenGL calls and so should be avoided, if possible. The reason to use texture atlases is so that fewer (or none) of these texture bind calls need to be made between triangles and so it should be possible to render all sprites from an atlas in a single drawcall. At the extreme, a 2D game could render all its graphics with a single call.

In 3D games, models can use a texture atlas in order to draw all their parts in a single call or multiple models can share an atlas to avoid texture binds between drawing each of them (different wall sctions sharing a common brick texture, for instance).

Okay, that’s really interesting info guys.

using glTexture2D to reload textures which IS a slow call

I am aware of that, and I was indeed referring to glBindTexture (I should have mentioned that).

In theory, I would have sufficient texture space in a single 1024x1024 texture for all my sprites (in a single game level). But for most of the images, high quality is required (RGBA8888). For other parts, like for example, particles, I could easily use PVRTC4BPP, because the artifacts of that compression will not be easily discernible on the fast moving particles (and I have already determined that PVRTC2BPP and 4BPP are significantly faster to render).

So I guess I now have to determine what is the most efficient: a single "expensive" texture for everything, or multiple textures of which some can be "cheaper".

I'm afraid that I already know the answer though: "test it"...

Thanks again.zmippie2011-02-22 13:15:21

Hi zmippie,


Reducing the memory bandwidth is more useful than reducing gl calls, so in this case the best course of action would be to a texture atlas for each texture quality that you have. So whatever needs to be RGBA8888 could be in one atlas, and the PVRTC textures in another.


Hope that was more helpful than "test it" :)



Tobias2011-02-24 10:06:45
Hope that was more helpful than "test it" :)

Excellent Tobias, and it will save me work because what you suggest is how it works now. Thanks!