AMD: glGenerateMipmap weirdnesses

Hi

This is just to let some people know, maybe for AMD to look into this:

glGenerateMipmap on AMD cards acts kinda weird. First of all, you definitely MUST have the filtering mode set to something to use mipmaps (min filter = GL_XYZ_MIPMAP_ABC …). Otherwise glGenerateMipmap seems to ignore that request entirely.

This is annoying, as one might use glGenerateMipmap just to setup everything for mipmapping and the filtering mode gets set “sometime later”. The driver should not ignore this only because the filtering mode is not yet decided (one wouldn’t call it, if one didn’t intend to use mipmaps).

Some other thread also mentioned that additionally glEnable(GL_TEXTURE_XY) has to be enabled for the same reason. This would be even more stupid, as this state doesn’t really have any use today anymore, but as far as I can tell, it isn’t needed atm.

Apart from that, glGenerateMipmap seems to clear the alpha-channel of the texture to 1 the first or second time it is called on a texture. This is quite an irritating behavior.

Basically I cleared my texture to green, with alpha set to 0. Then I rendered to it, setting alpha to 1 where pixels were drawn. Afterwards I called glGenerateMipmap and got a texture where RGB was correct but alpha was set to all 1. The next time I repeated this action, alpha was correct everywhere.
The interesting thing here is, that alpha was correct for all texels that were somehow touched by the rasterizer. I am rendering a tree mesh and all around the branches 4x4 pixel blocks where correct (meaning the actually rendering pixels had alpha = 1 and the masked out pixels had alpha = 0). However everything that the rasterizer did not touch (where there were no polygons at all) had alpha = 1.

So I added one additional glGenerateMipmap call after the texture creation (the first glGenerateMipmap call actually CREATED the mipmap chain, the second now should fix ATI’s strange behavior). That did the trick. Now every rendering to the texture creates correct results.

Took me several hours to find and fix this. Hopefully my description will help others in the future to figure out similar problems faster.

Bye,
Jan.

From your description it sounds like you creating a mipmapped “render target” texture. And then drawing to it. And then regenerating the mipmaps. Is that correct?

If you are using any of the older generation ATI cards they can’t handle non power of two textures (even though it’s required in the spec). So make sure your textures are power of two … then glGenerateMipmap works.

Sounds similar to my experience with AMD and glGenerateMipmap. I had to do something like calling glGenerateMipmap once at texture creation just to get things into a good state, and then again later when I actually needed to create the mipmaps from rendered data. If I didn’t do the extra glGenerateMipmap at texture creation time, it would crash when I tried to create the mipmaps for real later. Not sure if/when this problem was fixed.

Sorry for not replying earlier, my internet connection gave up on me…

@michagl: Yes, that’s exactly what I’m doing.

@dukey: My render target is square and power-of-two (usually 512*512). I tested this on a AMD Fusion processor, I assume it’s the HD 6250 GPU. Drivers should be from some time in the last 2-3 months.

@AlexN: That sounds very much like my problem, too, but I actually have to call glGenerateMipmap twice after texture creation. Though I do the second one after the texture is already set as a render-target on an FBO. Not sure yet, whether that has any influence.

I think the real interesting aspect is, that the resulting image is correct everywhere where the rasterizer touched the texture, at all, but incorrect where not a single pixel in some 4x4 group was influenced by any polygon. To me this looks as if the driver would use some internal hierarchical structure for speedup, but doesn’t handle the alpha channel correctly, if not all 4x4 blocks get written to (RGB is correctly copied to the resulting mipmap, alpha is just set to 1, which of course, is a very common default for not-initialized data, so this might not get noticed so easily). So it might not have to do with the texture only, but it probably is a feature (with a bug) in the render-targets.