3

When allocating textures using glTexImage* functions, I know that I need to set glTexParameteri(GL_TEXTURE_MAX_LEVEL) to a reasonable value and specify all the levels up to that value, as described here.

I didn't expect for this to be necessary in case of glTexStorage* functions too, since they accept the number of layers as a parameter and allocate memory for that number of layers up-front. Still, I noticed I couldn't sample an immutable texture defined this way - until I called glGenerateMipmap or specified GL_TEXTURE_MAX_LEVEL to levels-1.

I didn't find any official reason why it should be necessary and I expected immutable texture's parameters to be, well, immutable (and well-initialized). Can somebody confirm if (and why) this behaviour is correct? Or is it an AMD driver bug perhaps?

Kos
  • 70,399
  • 25
  • 169
  • 233

2 Answers2

3

OK, I think I got that:

The parameter levels of glTexStorage is indeed stored in the texture object, but as GL_TEXTURE_IMMUTABLE_LEVELS, not as GL_TEXTURE_MAX_LEVEL, as I thought.

The parameter GL_TEXTURE_MAX_LEVEL hence remains at the default large value. (It's possible to change it manually: the immutable flag of texture object only relates to the texture buffer and its format, but not buffer data or parameters).

The texture immutability should affect LOD calculation in the following way according to the spec:

if TEXTURE_IMMUTABLE_FORMAT is TRUE, then levelbase is clamped to the range [0; levelimmut - 1]

So leaving GL_TEXTURE_MAX_LEVEL intact (= 1000) for an immutable texture shall have the same effect as setting it to levels-1.

Verdict: driver bug; the driver apparently omits this clamping step.

Kos
  • 70,399
  • 25
  • 169
  • 233
2

I know that I need to set glTexParameteri(GL_TEXTURE_MAX_LEVEL) to a reasonable value and specify all the levels up to that value, as described here.

Well, you don't have to. The default value for GL_TEXTURE_MAX_LEVEL is 1000 and hence larger than any image pyramid you'll every reasonably use.

Still, I noticed I couldn't sample an immutable texture defined this way - until I called glGenerateMipmap or specified GL_TEXTURE_MAX_LEVEL to levels-1.

Yes, that's because image storage is independent of image sampling. The value of GL_TEXTURE_MAX_LEVEL is a parameter that affects image access at sampling time (you could set it into a Sampler Object as well) that's independent of the actual texture image storage. You can change the range of used image pyramid levels also after image specification, if you want to select only a subrange of images used during rendering, or only upload images into a subset of the allocated image pyramid.

EDIT reworded for clarification

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I kind of suspected this, but state tables list `TEXTURE_BASE_LEVEL` and `TEXTURE_MAX_LEVEL` as texture object state (while sampler object state has `TEXTURE_MIN_LOD` and `TEXTURE_MAX_LOD`). Can you confirm? – Kos Dec 13 '12 at 12:33
  • @Kos: Texture objects have TEXTURE_MIN_LOD and TEXTURE_MAX_LOD as well (just look into the OpenGL-2 spec, which didn't have sampler objects yet). Also remember that while the size of a texture image initialized with glTexStorage can not be changed the individual sub images can be changed at any time. So it's perfectly possible to replace a part of the image pyramid and set the base level and max level to the range of the images actually uploaded into the texture storage. – datenwolf Dec 13 '12 at 13:06
  • Yes, my point was that GL_TEXTURE_BASE/MAX_LEVEL might not be a sampling parameter since it's absent in sampler objects, unlike LOD params. – Kos Dec 13 '12 at 14:32