Array Textures and Mipmaps

I’m working a bit of code that uses array textures, and I wanted to confirm if the behavior I’m seeing is correct. Basically, I’ve observed that the number of mip-map levels generated for an array texture is dependent on the Z dimension of the array. For example, if I define a 32x32x8 array, I only get 4 mip levels. But if I define a 32x32x32 array, I get 6. I would expect this for “normal” 3-D textures, but I am surprised to see it be the case for arrays. I’m running on an NVIDIA 460M (261.14). Any insights would be greatly appreciated. Thanks!

This is not right. The maximum number of MIP levels should have nothing to do with the number of slices (Z dimension) of the 2D texture array. Only the resolution of each slice (X,Y). Conceptually, each slice is like it’s own 2D texture.

What makes you say this? Can you post a code snippet?

How are you generating mipmaps? GL_GENERATE_MIPMAP? glGenerateMipmap? gluBuild2DMipmaps? By hand?

Yeah, I was surprised to see it myself. I used gDEBugger to verify what I was seeing and it showed this to be the case. I’m sure I’m doing something dumb, but it’s not jumping out at me. Here’s the code I’m using:

// Generate array texture
unsigned int texture_id = 0;

glGenTextures( 1, &texture_id );

glBindTexture( GL_TEXTURE_2D_ARRAY, texture_id );

glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_FALSE );

glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, width, height, num_slices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );

// ...Loop to upload slices using glTexSubImage3D...

// Generate mips
glGenerateMipmap( GL_TEXTURE_2D_ARRAY );

I also tried doing the mip generation with GL_GENERATE_MIPMAP and GL_TRUE, but I got the same result.

Perhaps try removing the above line and use glGenerateMipmap API call instead.

Checking it on an ATI card with recent drivers + NVidia card with old drivers, I get the correct 6 mipmap levels generated with your code for both 32x32x32 and 32x32x8. (Well, querying the widths for each level in my test app gives the right values after the glGenerateMipmap call)

Is the comment “// …Loop to upload slices using glTexSubImage3D…” just indicating where you would implement filling the levels if you removed glGenerateMipmap, or are you actually doing anything extra there that you haven’t shown?

Thanks for checking. There must be something I’m doing outside of this code that is affecting it. I’ll keep digging and report what I find. As far as the upload loop goes, the only GL call I’m making is to glTexSubImage3D.

Sorry for the false alarm. It looks like this is most likely a problem with gDEBugger. If I call glGetTexImage I am able to read back all the mip levels as expected. Thanks!