opengl

Does glTexImage2D() or glTexSubImage2D() break a bindless texture handle?


i'm using bindless textures with glGetTextureHandleARB() + glMakeTextureHandleResidentARB(), and trying to figure out if the handle becomes invalid after calling glTexImage2D() or glTexSubImage2D() (or glCompressedTexSubImage2D() etc).

i know if you delete the texture and create a new one, then yeah obviously you get a new handle. but what i'm not sure about is if just doing glTexImage2D() again on the same texture object, like maybe with a different width/height or format, causes the old handle to stop working. do i have to call glMakeTextureHandleResidentARB() again? or even glGetTextureHandleARB() again?

i tried a test with glTexSubImage2D(), and the handle seemed to still work after updating the texture data, but i’m not sure if that’s just on my driver (i tested on nvidia). not sure about amd/intel or what the spec really says about it. couldn’t find a clear answer.

this matters because i’m passing the handle into shaders and don’t want to redo all the resident/binding stuff unless really needed.

What is the actual rule? Or what do drivers do?


Solution

  • While textures that you want to make bindless do not have to be allocated with immutable storage (ie: using the glTexStorage functions), the act of creating a bindless handle from those textures causes their storage (and state) to become de-facto immutable.

    So if you get a handle to a texture, you cannot call glTexImage* on them again. The handle doesn't become invalid; the call gives an error.

    The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as well as other functions defined in terms of these, if the texture object to be modified is referenced by one or more texture or image handles.

    Note that glTexSubImage2D is different; those functions only upload data to the existing storage. That's fine. But glTexImage* allocates storage. And that's not allowed once you have a bindless handle.

    And you cannot "un-get" a bindless handle. Once you have acquired such a handle, the texture is forever immutable.