OpenGL texture/mipmapping question

Hi,

I will first describe my setup:

  1. create a 2D texture (1024x1024) and bind it
  2. set both GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAX_FILTER to GL_LINEAR
  3. render something to it using an FBO
  4. unbind the texture from the FBO
    [b]5. change its MIN_FILTER to be LINEAR_MIPMAP_LINEAR
  5. call glGenerateMipmaps [/b]
  6. draw the texture to the screen
  7. delete the texture

important note: this is done every frame.

Now the question: is this allowed by OpenGL? (changing the MIN_FILTER to a mode that requires mipmap levels that were not allocated before the first “use”?) I’ve searched the spec but could not find anything specified against it so I guess it should be allowed. Anybody with more OpenGL knowledge may say otherwise?

I have made a small program to test this setup and ran it on a NVidia GPU and an ATI GPU, both with latest drivers.
On the NVidia GPU the application worked fine, but on the ATI one it consistently crashes (I used error checking all over the place and got no error from the GL). If I call glGenerateMipmaps before first texture use (even if this is not needed as the minification filter is set to LINEAR) everything works fine on the ATI GPU.

thank you for any help clearing this out!

PS: this scenario was deliberately made like this to reproduce a crash we are getting in our software with ATI hardware (the application applies a series of shaders to a chain of textures and only one undetermined texture should be displayed so we can’t decide from the beginning which texture should have its mipmap levels allocated).

Good to know.
Even if it was forbidden by the spec, it should generate an error or white texture, not crash.

Time for a bug report to ATI/AMD, I guess.

You already have your workaround (call glGenerateMipmaps early).

The glGenerateMipmaps shall be called at least before changing the MIN_FILTER, however I’m unsure whether this is enough or not. There is no clear information about this in the specification, however it says that glGenerateMipmaps shall affect only subsequent operations.

Anyway, there is definitely a problem in the ATI/AMD driver. Unfortunately the Catalyst display drivers usually crash when some illegal OpenGL operations are executed, rather than reporting an error. I met the same problem several times, especially when having invalid stuff in my shaders.

The glGenerateMipmaps shall be called at least before changing the MIN_FILTER, however I’m unsure whether this is enough or not. There is no clear information about this in the specification, however it says that glGenerateMipmaps shall affect only subsequent operations.

Tryed also calling the glGenerateMipmaps before changing the MIN_FILTER. The crash occurs, but just a little later in this case:

  • MIN_FILTER change before glGenerateMipmaps the application runs for about 5 seconds before crashing;
  • glGenerateMipmaps and then MIN_FILTER change the crash occurs after about 25 seconds of running;

Well, that’s definitely a problem in the ATI drivers anyway.

However, after a bit thinking, I would consider the workaround as the correct behavior as if the spec would allow the changing of mipmap generation settings on-the-fly that would end up in inefficient allocation/deallocation procedures in the texture memory space.

If I were you, I would go with the workaround no matter ATI will correct the problem you’ve found or not, as the original code most probably has its performance drawbacks.

indeed, changing the min filter as in your sample code would trigger a reallocation and data copy. in the best case, the copy would happen from the previously allocated memory, but it could be a back and forth with a cpu memory copy…

the driver should not crash regardless, and we will look into it.

I don’t think that the filtering settings have any effect on mipmap generation at all.

The filtering settings only affect whether the mipmaps are used during texturing or not.

If the texture filter mode requires mipmap levels that haven’t been defined, then the spec says that the GL should act “as if texturing were disabled.”

indeed, changing the min filter as in your sample code would trigger a reallocation and data copy. in the best case, the copy would happen from the previously allocated memory, but it could be a back and forth with a cpu memory copy…

that is exactly what we are thinking to implement now in our application as a workaround.

i would like to also correct what I said in a previous post: calling glGenerateMipmaps before first texture use doesn’t help if the current MIN_FILTER mode does not use the mipmap levels. probably the driver ignores the generateMipmaps call if the filtering mode currently set does not use use the mipmap levels. but if the current MIN_FILTER mode uses the mipmap levels no crash occurs anymore.