Reputation: 2770
I've been having a very weird issue with my project's texture generation. The first mipmapped texture works flawlessly but the next ones only draw the first level. While debugging I suddenly came to a hack that fixes it:
glGenTextures(1, &texture->textureID);
glBindTexture(GL_TEXTURE_2D, texture->textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexStorage2D(GL_TEXTURE_2D, 10, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
assert(glGetError() == GL_NO_ERROR); // Mipmapping fails if glGetError is not here
glBindTexture(GL_TEXTURE_2D, 0);
Why on earth is this only working when a glGetError (which, as you can see with this assert, is ALWAYS returning GL_NO_ERROR) function is called after the glGenerateMimap? Why does it have anything to do with it?
I'm currently using a GeForce GTX 670 with the latest GeForce 340.52 driver
Edit: A couple of images might help
With glGetError():
Without glGetError():
Upvotes: 4
Views: 1025
Reputation: 2770
Referring to Is iOS glGenerateMipmap synchronous, or is it possibly asynchronous?, it seems glGenerateMipmaps works asynchronously. My project uses shared contexts to create shaders, textures and meshes (sorry if I didn't mention this, I didn't think it would matter).
The thing is, whenever the texture generation finished the "textures generated" flag was risen and the shared context would get destroyed, it seems the last glGenerateMipmap was therefore not getting flushed through the pipeline. The call to glGetError needs to flush the operations from the pipeline to see whether there's been any error to report, and this is exactly why it was making everything work flawlessly.
So, in other words, if you're doing something on a separate, shared context, you need to explicitly call glFinish before killing that thread, or some operations will be left undone.
Upvotes: 2