Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is glTexStorage2D imperative when auto generating mipmaps

I do update to a texture2D in OpenGL 4.0 using gltexSubImage2D().The texture has mipmaps auto generated using

 glGenerateMipmap(GL_TEXTURE_2D); 

My texture update was failing till I understood I had to regenerate mipmaps on update too (or remove mipmaps generation).Then I read this wiki where there is a usage of glTexStorage2D when generating mipmaps.I actually never paid attention to this method.So I wonder if I have to use it every time I generate a texture with mipmaps?

Update :

I see from the method specs that it

specifies the storage requirements for all levels of a two-dimensional texture or one-dimensional texture array simultaneously

I guess using it should improve the performance when generating mipmaps?Is it true?

like image 599
Michael IV Avatar asked Mar 14 '13 09:03

Michael IV


2 Answers

The two functions are completely orthogonal.

The choice is between glTexImage2D and glTexStorage2D. Both of these allocate storage for texture images; they just do it in different ways.

glTexImage2D is the old way of allocating storage. It creates mutable storage (there are other functions that create mutable storage too). If you want mipmaps, you have to allocate each mipmap level with a separate call to the function, manually computing the size of the mipmap image (see below for the exception to this).

glTexStorage2D allocates immutable storage for the image data. It allocates all of the mipmaps you want all at once.

Immutable storage, as the name suggests, cannot be changed. See, you can call glTexImage2D on the same mipmap level, with a different size. And if you do, OpenGL will destroy the original mipmap level and allocate storage for the new one. You can even change formats.

Immutable storage won't let you change any of that. You can upload new data, using functions like glTexSubImage2D. But those functions don't change the storage; they change the contents.

glTexImage2D and glTexStorage2D are like malloc. glTexSubImage2D is like memcpy; it only works for existing memory.

glGenerateMipmap is a function that will take the base layer of a texture and generate the data for all of the mipmaps from that base layer (given the mipmap range). It does this one time. Think of it like a rendering function; it does its job and then it's done.

For mutable storage textures, glGenerateMipmap will also allocate storage for any mipmaps in the mipmap range that were not previously allocated. That's why you can call glTexImage2D once, then call glGenerateMipmap to force it to make all of the other mipmaps without having to do it manually.

like image 199
Nicol Bolas Avatar answered Sep 24 '22 12:09

Nicol Bolas


Before there was glTexStorage, each mipmap level had to be initialized by a separate call to glTexImage. glTexImage triggers a lot of complex internal state changes, which are rather expensive. Every time glTexImage is called, the layout of the texture object is altered.

Hence you try to avoid using it, if possible. As you discovered, you must first initialize all desired mipmap levels before you can update them by glTexSubImage. glGenerateMipmap will create them, which introduce layout changes, which is, yes, expensive.

glTexStorage initializes the whole texture object once for a desired, immutable format. Yes, using glTexStorage improves performance when used together wigh glGenerateMipmap or data updates by glTexSubImage, but the improvements happen very early at texture object creation, and not so much when its data is changed.

like image 24
datenwolf Avatar answered Sep 24 '22 12:09

datenwolf