GLTEXSTORAGE2D(3G)
okay so this is the GLTEXSTORAGE2D(3G) page β and yes, the header has a little [FIXME: manual] placeholder in it, we love a work-in-progress moment. Itβs giving βlock in texture storage for all the levels at once,β and honestly? Iconic.
π NAME π
glTexStorage2D, glTextureStorage2D β simultaneously specify storage for all levels of a two-dimensional or one-dimensional array texture.
π» C SPECIFICATION π»
void glTexStorage2D(GLenum target, GLsizei levels,
GLenum internalformat, GLsizei width,
GLsizei height);
void glTextureStorage2D(GLuint texture, GLsizei levels,
GLenum internalformat, GLsizei width,
GLsizei height);
πΈ PARAMETERS πΈ
targetβ specifies the target to which the texture object is bound forglTexStorage2D. Must be one ofGL_TEXTURE_2D,GL_TEXTURE_1D_ARRAY,GL_TEXTURE_RECTANGLE,GL_TEXTURE_CUBE_MAP,GL_PROXY_TEXTURE_2D,GL_PROXY_TEXTURE_1D_ARRAY,GL_PROXY_TEXTURE_RECTANGLE, orGL_PROXY_TEXTURE_CUBE_MAP.textureβ specifies the texture object name forglTextureStorage2D. The effective target oftexturemust be one of the valid non-proxy target values above.levelsβ specify the number of texture levels.internalformatβ specifies the sized internal format to be used to store texture image data.widthβ specifies the width of the texture, in texels.heightβ specifies the height of the texture, in texels.
β¨ DESCRIPTION β¨
glTexStorage2D and glTextureStorage2D specify the storage requirements for all levels of a two-dimensional texture or one-dimensional texture array simultaneously. Once a texture is specified with this command, the format and dimensions of all levels become immutable unless it is a proxy texture. The contents of the image may still be modified, however, its storage requirements may not change. Such a texture is referred to as an immutable-format texture. π
The behavior of glTexStorage2D depends on the target parameter. When target is GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D, GL_TEXTURE_RECTANGLE, GL_PROXY_TEXTURE_RECTANGLE or GL_PROXY_TEXTURE_CUBE_MAP, calling glTexStorage2D is equivalent, assuming no errors are generated, to executing the following pseudo-code:
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
height = max(1, (height / 2));
}
When target is GL_TEXTURE_CUBE_MAP, glTexStorage2D is equivalent to:
for (i = 0; i < levels; i++) {
for (face in (+X, -X, +Y, -Y, +Z, -Z)) {
glTexImage2D(face, i, internalformat, width, height, 0, format, type, NULL);
}
width = max(1, (width / 2));
height = max(1, (height / 2));
}
When target is GL_TEXTURE_1D_ARRAY or GL_PROXY_TEXTURE_1D_ARRAY, glTexStorage2D is equivalent to:
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
}
Calling glTextureStorage2D is equivalent to the above pseudo-code, where target is the effective target of texture and it is as if texture were bound to target for the purposes of glTexImage2D. π«Ά
Since no texture data is actually provided, the values used in the pseudo-code for format and type are irrelevant and may be considered to be any values that are legal for the chosen internalformat enumerant. internalformat must be one of the sized internal formats given in Table 1 below, one of the sized depth-component formats GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, or GL_DEPTH_COMPONENT16, one of the combined depth-stencil formats, GL_DEPTH32F_STENCIL8, or GL_DEPTH24_STENCIL8, or the stencil-only format, GL_STENCIL_INDEX8.
Upon success, the value of GL_TEXTURE_IMMUTABLE_FORMAT becomes GL_TRUE. The value of GL_TEXTURE_IMMUTABLE_FORMAT may be discovered by calling glGetTexParameter() with pname set to GL_TEXTURE_IMMUTABLE_FORMAT. No further changes to the dimensions or format of the texture object may be made. Using any command that might alter the dimensions or format of the texture object (such as glTexImage2D() or another call to glTexStorage2D) will result in the generation of a GL_INVALID_OPERATION error, even if it would not, in fact, alter the dimensions or format of the object. π¨
π Table 1. Sized Internal Formats π
okay bestie, this is THE table β every sized internal format, what base internal format it rides with, and how many bits each channel gets. Read it like a menu β¨
quick legend before you scroll: plain numbers are unsigned bits, s means signed, ui means unsigned integer, and f means float β iykyk π
GL_R8β base internal formatGL_RED, red bits8GL_R8_SNORMβ base internal formatGL_RED, red bitss8GL_R16β base internal formatGL_RED, red bits16GL_R16_SNORMβ base internal formatGL_RED, red bitss16GL_RG8β base internal formatGL_RG, red bits8, green bits8GL_RG8_SNORMβ base internal formatGL_RG, red bitss8, green bitss8GL_RG16β base internal formatGL_RG, red bits16, green bits16GL_RG16_SNORMβ base internal formatGL_RG, red bitss16, green bitss16GL_R3_G3_B2β base internal formatGL_RGB, red bits3, green bits3, blue bits2GL_RGB4β base internal formatGL_RGB, red bits4, green bits4, blue bits4GL_RGB5β base internal formatGL_RGB, red bits5, green bits5, blue bits5GL_RGB8β base internal formatGL_RGB, red bits8, green bits8, blue bits8GL_RGB8_SNORMβ base internal formatGL_RGB, red bitss8, green bitss8, blue bitss8GL_RGB10β base internal formatGL_RGB, red bits10, green bits10, blue bits10GL_RGB12β base internal formatGL_RGB, red bits12, green bits12, blue bits12GL_RGB16_SNORMβ base internal formatGL_RGB, red bits16, green bits16, blue bits16GL_RGBA2β base internal formatGL_RGB, red bits2, green bits2, blue bits2, alpha bits2GL_RGBA4β base internal formatGL_RGB, red bits4, green bits4, blue bits4, alpha bits4GL_RGB5_A1β base internal formatGL_RGBA, red bits5, green bits5, blue bits5, alpha bits1GL_RGBA8β base internal formatGL_RGBA, red bits8, green bits8, blue bits8, alpha bits8GL_RGBA8_SNORMβ base internal formatGL_RGBA, red bitss8, green bitss8, blue bitss8, alpha bitss8GL_RGB10_A2β base internal formatGL_RGBA, red bits10, green bits10, blue bits10, alpha bits2GL_RGB10_A2UIβ base internal formatGL_RGBA, red bitsui10, green bitsui10, blue bitsui10, alpha bitsui2GL_RGBA12β base internal formatGL_RGBA, red bits12, green bits12, blue bits12, alpha bits12GL_RGBA16β base internal formatGL_RGBA, red bits16, green bits16, blue bits16, alpha bits16GL_SRGB8β base internal formatGL_RGB, red bits8, green bits8, blue bits8GL_SRGB8_ALPHA8β base internal formatGL_RGBA, red bits8, green bits8, blue bits8, alpha bits8GL_R16Fβ base internal formatGL_RED, red bitsf16
ngl the Shared Bits column is just vibing empty for literally every row in this stretch π«Ά so there's nothing to report there, don't come for me π
and yes, GL_RGBA2 and GL_RGBA4 really do list GL_RGB as their base internal format β that's what the table says, no cap, I'm not touching it π
now the float ones start showing up and the list keeps going π
...and the parade of sized internal formats just keeps going, bestie π same column order as before β internal format, pixel format, then the per-channel sizes β so let's get into it π
GL_RG16Fβ pixel formatGL_RG, channels sizedf16,f16π«ΆGL_RGB16Fβ pixel formatGL_RGB, channels sizedf16,f16,f16β¨GL_RGBA16Fβ pixel formatGL_RGBA, channels sizedf16,f16,f16,f16πΈGL_R32Fβ pixel formatGL_RED, channel sizedf32πGL_RG32Fβ pixel formatGL_RG, channels sizedf32,f32π¦GL_RGB32Fβ pixel formatGL_RGB, channels sizedf32,f32,f32βGL_RGBA32Fβ pixel formatGL_RGBA, channels sizedf32,f32,f32,f32πGL_R11F_G11F_B10Fβ pixel formatGL_RGB, channels sizedf11,f11,f10β yes the name literally spells out the bit split, iconic honestly π₯GL_RGB9_E5β pixel formatGL_RGB, channels sized9,9,9, with shared exponent5π§
okay now we're entering the integer era and it's lowkey my favorite part π every one of these is channel-by-channel, no sharing, no crumbs:
GL_R8Iβ pixel formatGL_RED, channel sizedi8πGL_R8UIβ pixel formatGL_RED, channel sizedui8πGL_R16Iβ pixel formatGL_RED, channel sizedi16πGL_R16UIβ pixel formatGL_RED, channel sizedui16πGL_R32Iβ pixel formatGL_RED, channel sizedi32πGL_R32UIβ pixel formatGL_RED, channel sizedui32πGL_RG8Iβ pixel formatGL_RG, channels sizedi8,i8πGL_RG8UIβ pixel formatGL_RG, channels sizedui8,ui8πGL_RG16Iβ pixel formatGL_RG, channels sizedi16,i16πGL_RG16UIβ pixel formatGL_RG, channels sizedui16,ui16πGL_RG32Iβ pixel formatGL_RG, channels sizedi32,i32πGL_RG32UIβ pixel formatGL_RG, channels sizedui32,ui32πGL_RGB8Iβ pixel formatGL_RGB, channels sizedi8,i8,i8πGL_RGB8UIβ pixel formatGL_RGB, channels sizedui8,ui8,ui8πGL_RGB16Iβ pixel formatGL_RGB, channels sizedi16,i16,i16πGL_RGB16UIβ pixel formatGL_RGB, channels sizedui16,ui16,ui16πGL_RGB32Iβ pixel formatGL_RGB, channels sizedi32,i32,i32πGL_RGB32UIβ pixel formatGL_RGB, channels sizedui32,ui32,ui32πGL_RGBA8Iβ pixel formatGL_RGBA, channels sizedi8,i8,i8,i8πGL_RGBA8UIβ pixel formatGL_RGBA, channels sizedui8,ui8,ui8,ui8πGL_RGBA16Iβ pixel formatGL_RGBA, channels sizedi16,i16,i16,i16πGL_RGBA16UIβ pixel formatGL_RGBA, channels sizedui16,ui16,ui16,ui16π
and that's where we're gonna pause the list, because the format table is still going and we are absolutely not done yet π
GL_RGBA32Iβ the effective internal format isGL_RGBA, and every channel isi32,i32,i32,i32(and yeah, that last column is just blank, she's empty, she's thriving π«Ά)GL_RGBA32UIβ effective internal formatGL_RGBA, channels allui32,ui32,ui32,ui32(last column blank again, no thoughts head empty π )
β¨ NOTES β¨
okay tiny little footnote bestie, don't skip it: GL_STENCIL_INDEX8 is accepted for internalformat only if the GL version is 4.4 or higher. like, that's the whole vibe check. if you're on 4.3 it's a no. periodt.
π ERRORS π
this is the part where things go wrong and the driver yells at you. buckle up π
GL_INVALID_OPERATIONis generated byglTexStorage2Dif zero is bound to target β like, nothing's there, bestie, you can't texture a void πGL_INVALID_OPERATIONis generated byglTextureStorage2Dif texture is not the name of an existing texture object β she doesn't exist, don't @ herGL_INVALID_ENUMis generated if internalformat is not a valid sized internal format β sized, babe. sized.GL_INVALID_ENUMis generated if target or the effective target of texture is not one of the accepted targets described above (scroll up, they're all listed π)GL_INVALID_VALUEis generated if width, height or levels are less than 1 β no zero-size textures, no negative sizes, we don't do that here πGL_INVALID_OPERATIONis generated if target isGL_TEXTURE_1D_ARRAYorGL_PROXY_TEXTURE_1D_ARRAYand levels is greater thanlog 2 width + 1β that's too many levels for that width, sweetie, the mip pyramid literally does not go that high πGL_INVALID_OPERATIONis generated if target is notGL_TEXTURE_1D_ARRAYorGL_PROXY_TEXTURE_1D_ARRAYand levels is greater thanlog 2 max width , height + 1β again, too deep, the pyramid caps out β¨
π VERSION SUPPORT π
the "am I even allowed to call this" chart. here it is, translated from table-ese into a format your eyeballs will forgive π
glTexStorage2Dβ not supported (-) in 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0 and 4.1; supported (β) in 4.2, 4.3, 4.4 and 4.5. so she showed up to the party in 4.2 and never left π₯glTextureStorage2Dβ not supported (-) in 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0, 4.1, 4.2, 4.3 and 4.4; supported (β) only in 4.5. late bloomer, main character energy, arrived fashionably late and slayed π
πΈ SEE ALSO πΈ
go read these next, i'm not kidding, they're literally right there:
glTexImage2D()glTexStorage1D()glTexStorage3D()
it's giving "one-dimensional bestie" and "three-dimensional bestie" and the classic two-dee icon herself. trio of icons π¦
π COPYRIGHT π
Copyright Β© 2011-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.
Copyright Β© 2011-2014 Khronos Group
and that's the whole page, bestie, you ate that πβ¨ no cap, that's the tea from [FIXME: source], dated 08/09/2021, living under the name GLTEXSTORAGE2D(3G) β hug your textures, take your mip levels seriously, and go forth and glTexStorage2D ππ
π¦ where this page comes from
- centos-stream 9: gl-manpages 1.1-24.20190306.el9 Β· MIT and Open Publication
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms