OpenGL Texture Slots and Vertex Texture Fetching

Started by
5 comments, last by OandO 7 years, 2 months ago

A couple of questions about how OpenGL uses textures across vertex and fragment shaders. I've been working on a materials system, and I'm currently implementing a simple list of textures that are in use, to reduce the number of texture binds done if sequential materials use the same textures. If I'm understanding this correctly, I've found that the vertex shader and fragment shader have access to different numbers of texture slots, however the information here seems to be self-contradictory:

https://www.khronos.org/opengl/wiki/Vertex_Texture_Fetch

GPUs that support VTF use the same TIUs as the fragment shader. This means that you can bind a texture to TIU 1 and sample that same texture in the vertex shader and also the fragment shader.

If in your VS and FS, you access the same texture, that counts like accessing 2 TIUs.

I don't understand why this would be the case, or how to work with it. If I wanted to use a texture in the vertex, I'd have to bind it to one of the slots accessible by the vertex shader, but there's some additional cost to then accessing it in the fragment shader as well? I'm hoping someone can clarify this, as these two points seem to be at odds with each other.

Advertisement

Yeah, that quote is completely confusing.

GL has

  • GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS - for vertex shaders
  • GL_MAX_TEXTURE_IMAGE_UNITS - for pixel shaders
  • Other similarly named for tesselation, geometry shaders and compute
  • GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS

To work properly:

  1. Your vertex shader must contain less than GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS textures
  2. Your pixel shader must contain less than GL_MAX_TEXTURE_IMAGE_UNITS textures
  3. The number of vs_textures + ps_textures must be less than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS. If a VS and PS use the same texture, it counts as 2 (1 for the VS, 1 for the PS)

So if GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16; GL_MAX_TEXTURE_IMAGE_UNITS = 16; but GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 25 and you use 14 textures in the VS, and 14 textures in the PS, the shader will fail. It passes the first and second tests (14 < 16) but not the third one (14 + 14 = 28 > 25).

Though in practice most modern cards will do GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS + ...all other stages... + GL_MAX_TEXTURE_IMAGE_UNITS = GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;

These stupid rules come from 2003 when GPUs had separate texture units for vertex and pixel shaders; where the VS had 4 TU chips and the PS separately had 16 TU chips. But in today GPUs everything just really gets processed by the same piece of hardware.

Thank you, that's very helpful.

One follow up question, does it matter which particular texture slots I use? For example, suppose GL_MAX_TEXTURE_IMAGE_UNITS = 2, would I be limited to the first two texture slots, or could I use say GL_TEXTURE5 and GL_TEXTURE6 so long as I'm not using more than two at once?

Thank you, that's very helpful.

One follow up question, does it matter which particular texture slots I use? For example, suppose GL_MAX_TEXTURE_IMAGE_UNITS = 2, would I be limited to the first two texture slots, or could I use say GL_TEXTURE5 and GL_TEXTURE6 so long as I'm not using more than two at once?

If you use texture0 and texture6, it counts as 2 textures.

Though for best performance avoid leaving too many gaps (specially large gaps).

The limit of functions that take GL_TEXTURE_0 + i as parameter (e.g. glActiveTexture) is [0..GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS-1]

So if GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is 2 you only can use GL_TEXTURE_0 and GL_TEXTURE_0 + 1 (or GL_TEXTURE_1). But non stone age hardware has way more texture slots.

Oh yeah, Osbios makes a good point. You can't use slot 7 if GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 2

Right, I see. Thank you!

This topic is closed to new replies.

Advertisement