Binding textures in OpenGL
Asked Answered
R

4

16

So I'm rendering my scene in batches, to try and minimize state changes. Since my shaders usually need multiple textures, I have a few of them bound at the same time to different texture units. Some of these textures are used in multiple batches, so could even stay bound.

Now my question is, is it fine to just re-bind all of the textures that I need during a batch, even though some of them may already be bound? Or should I check which ones are bound, and only bind new ones? How expensive is glBindTexture? I'm using shaders, is it bad to have unused textures bound to texture units that the shader won't sample from, or should I unbind them?

I'm mostly asking "how to make it fast", not "how to".

EDIT: Would it help if I supplied code?

Rook answered 10/3, 2011 at 20:50 Comment(0)
U
5

The answer is difficult, because any strong GL implementation should make binding a already bound texture a no-op as an optimization. You should try benchmarking to see if putting a condition makes a difference or not.

The same applies to unused textures in texture units, since the GL implementation does know what texture units are finally used, it should not affect performance (as an optimization) to have unused texture units.

Ugh answered 10/3, 2011 at 23:33 Comment(4)
Don't count on the GL implementation doing this optimization.Modish
It's a valid assumption, though. GPUs usually have several sets of state these days which the driver juggles around (see Tom Forsynth's blog for a lengthy article). Which means that even changing textures does not necessarily a stall (this is a worst-case assumption that ony should do nevertheless). Such a kind of resource management can obviously only be done if the implementation keeps track of what is bound and does not apply changes redundantly. That doesn't guarantee anything, but it's a realistic assumption.Barytes
On a different note, there is the cache-miss problem when rebinding objects, which nVidia stated as the main reason for its bindless graphics extension ("the one new bottleneck"). There are reportedly a lot of cache misses going on because the driver has to fetch state to check what's bound and whether it's valid and whatnot for every bind. So, even if it is optimized in the driver, avoiding needless binds still is not a bad idea.Barytes
Does anyone know if OpenTK does this by default?Freshet
S
13

The holy rule of GPU programming is that less you talk to GPU, the more she loves you. glBindTexture is much more expensive than single condition check on CPU, so for frequent state changes, I think you should see if there is a need to transfer new texture index to GPU.

Spectral answered 10/3, 2011 at 20:56 Comment(3)
Display lists are deprecated anyway so you better don't use them at all.Wagonlit
glBindTexture is slow, just as any state change (glEnable, ...). Do whatever you can in your own code to avoid them. If not convinced, run your program through gDEBbugger and see what it says.Marjana
The advantage of rebinding all textures would be that I won't need to change shader uniforms (e.g I can always count on "metal_2" being in texture_2). I guess I'll have to profile it, I'm not sure on the performance of uniform sets vs. glBindTexture.Rook
U
5

The answer is difficult, because any strong GL implementation should make binding a already bound texture a no-op as an optimization. You should try benchmarking to see if putting a condition makes a difference or not.

The same applies to unused textures in texture units, since the GL implementation does know what texture units are finally used, it should not affect performance (as an optimization) to have unused texture units.

Ugh answered 10/3, 2011 at 23:33 Comment(4)
Don't count on the GL implementation doing this optimization.Modish
It's a valid assumption, though. GPUs usually have several sets of state these days which the driver juggles around (see Tom Forsynth's blog for a lengthy article). Which means that even changing textures does not necessarily a stall (this is a worst-case assumption that ony should do nevertheless). Such a kind of resource management can obviously only be done if the implementation keeps track of what is bound and does not apply changes redundantly. That doesn't guarantee anything, but it's a realistic assumption.Barytes
On a different note, there is the cache-miss problem when rebinding objects, which nVidia stated as the main reason for its bindless graphics extension ("the one new bottleneck"). There are reportedly a lot of cache misses going on because the driver has to fetch state to check what's bound and whether it's valid and whatnot for every bind. So, even if it is optimized in the driver, avoiding needless binds still is not a bad idea.Barytes
Does anyone know if OpenTK does this by default?Freshet
M
0

Track which textures you've bound (don't use glGet(GL_TEXTURE_BINDING_2D) ) and only rebind if it changes. Some drivers will do this for you, some won't.

If you know what platform you're targeting in advance, it's pretty easy to do a simple benchmark to see how much difference it makes.

You can also sort your batches by what textures they are using to minimize texture changes.

Modish answered 10/3, 2011 at 23:57 Comment(0)
R
0

I'd say the best way is to bind all the textures at once using glBindTextures https://www.khronos.org/opengl/wiki/GLAPI/glBindTextures . Or use bindless textures :)

Rant answered 11/8, 2020 at 10:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.