Search code examples
openglmipmaps

How to dynamically enable/disable texture mip-maps in OpenGL?


So, glGenerateMipMap is great. I'm wondering about a couple of things:

  • suppose the texture image is changed via glTexSubImage2D, another call to glGenerateMipMap is -- sufficient / required / unnecessary?
  • suppose end-users should be able to "enable/disable mip-maps" on the fly, of course GL_TEXTURE_MIN_FILTER has to be set accordingly to mipmap or not. However, the previously generated mip-maps remain in GPU VRAM, right? -- can the driver be "hinted" to delete those? Do I have to re-upload the original texture image (but now with min-filtering no longer set to mipmap) to clear the memory that contained the previously generated and now unneeded mip-maps?

Background -- among other use-cases also requiring more insights into the above questions, I'd also like to "keep track of approx. GPU VRAM consumed by the app" (for all kinds of reasons such as scalable arbitrary texture / vertex streaming) --- by tracking not only GL buffers being filled by the app but also textures uploaded (sure it's just an approximation but good enough). Tracking their mip-maps then is necessary too, so knowing how to clear them or when they get cleared by current-gen GL implementation would be highly useful.


Solution

  • suppose the texture image is changed via glTexSubImage2D, another call to glGenerateMipMap is -- sufficient / required / unnecessary?

    If you want the mipmaps to correctly reflected the uploaded base level, yes. glGenerateMipmaps is a one-time operation, not a switch you flip on the texture.

    However, the previously generated mip-maps remain in GPU VRAM, right? -- can the driver be "hinted" to delete those?

    Don't bother. Telling the driver to unallocate memory like that is always a bad idea. Indeed, calling glTexImage* more than once for the same mipmap level (unless you're uploading cubemap faces) is a bad idea.

    To explain more clearly why this is, consider the relatively new OpenGL function glTexStorage2D. The use of this function makes the texture's storage immutable. It has the number of mipmaps you say it does, forever (until you delete it of course).

    Why? Well, from the ARB_texture_storage extension:

    4: Should use of these entry-points make the metadata (format and dimensions) immutable?

    RESOLVED: Yes.

    DISCUSSION: The benefits of knowing metadata can't change will probably outweigh the extra cost of checking the TEXTURE_IMMUTABLE_FORMAT flag on each texture specification call.

    The ARB sees the benefits in this. Indeed, ARB_texture_view would likely be impossible (or at least very inefficient) without it. So clearly, that's what they want people to use.

    If you want the user to be able to flip that switch and actually regain some memory, then do it properly: create a new texture object that has the same contents as the old one.

    In any case, it doesn't matter anyway, because OpenGL has no way to deallocate a mipmap layer.