glTextureStorage2D
Allocates immutable storage for a texture by ID (DSA glTexStorage2D).
Signature
void glTextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
How it works
Allocates every mip level at once, with a fixed size and format, and fills nothing: the pixels come next with glTextureSubImage2D. "Immutable" means the size and format can never change, which lets the driver check the texture once instead of at every draw, and rules out the classic bug of a texture that is incomplete because a mip level is missing.
The format must be a sized one (GL_RGBA8, not GL_RGBA). For colour images use an sRGB format such as GL_SRGB8_ALPHA8, so the GPU converts to linear when sampling.
Parameters
Texture from glCreateTextures.
Number of mip levels.
Sized format: GL_RGBA8, GL_SRGB8_ALPHA8, GL_RGBA16F, GL_DEPTH_COMPONENT32F…
Width of level 0.
Height of level 0.
Tips & pitfalls
Direct State Access (GL 4.5): the object is passed as a parameter, so nothing needs to be bound and no global state is disturbed.
Example
1int levels = 1 + (int)std::floor(std::log2(std::max(w, h)));
2glTextureStorage2D(tex, levels, GL_SRGB8_ALPHA8, w, h);