GLTEXSTORAGE3D(3G)

πŸ¦‹ GLTEXSTORAGE3D(3G) πŸ¦‹

okay bestie, welcome to the GLTEXSTORAGE3D(3G) page from the [FIXME: manual] manual. it’s giving β€œtexture storage, but make it immutable” energy, and honestly? iconic. no cap, this one is about glTexStorage3D and glTextureStorage3D setting up storage for all levels at once. πŸ’…βœ¨

πŸ’– NAME πŸ’–

glTexStorage3D, glTextureStorage3D β€” bestie, they simultaneously specify storage for all levels of a three-dimensional, two-dimensional array or cube-map array texture. that’s the whole name vibe. 🫢

🌈 C SPECIFICATION 🌈

here’s the C spec, and yes, the signatures stay exactly like this:

void glTexStorage3D(GLenum target, GLsizei levels,
                    GLenum internalformat, GLsizei width,
                    GLsizei height, GLsizei depth);

void glTextureStorage3D(GLuint texture, GLsizei levels,
                        GLenum internalformat, GLsizei width,
                        GLsizei height, GLsizei depth);

πŸŽ€ PARAMETERS πŸŽ€

okay, parameter time β€” every single one of these matters, bestie:

  • target β€” for glTexStorage3D, this specifies the target to which the texture object is bound. it must be one of GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_2D_ARRAY or GL_PROXY_TEXTURE_CUBE_MAP_ARRAY. πŸ‘‘
  • texture β€” for glTextureStorage3D, this specifies the texture object name. the effective target of texture must be one of the valid non-proxy target values above. 🫢
  • levels β€” this specifies the number of texture levels. lowkey important. ✨
  • internalformat β€” this specifies the sized internal format to be used to store texture image data. πŸŽ€
  • width β€” this specifies the width of the texture, in texels. 🌸
  • height β€” this specifies the height of the texture, in texels. πŸ¦‹
  • depth β€” this specifies the depth of the texture, in texels. πŸ’œ

✨ DESCRIPTION ✨

okay so glTexStorage3D and glTextureStorage3D specify the storage requirements for all levels of a three-dimensional, two-dimensional array or cube-map array texture 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 glTexStorage3D depends on the target parameter. when target is GL_TEXTURE_3D, or GL_PROXY_TEXTURE_3D, calling glTexStorage3D is equivalent, assuming no errors are generated, to executing the following pseudo-code: 🧚

for (i = 0; i < levels; i++) {
    glTexImage3D(target, i, internalformat, width, height, depth, 0, format, type, NULL);
    width = max(1, (width / 2));
    height = max(1, (height / 2));
    depth = max(1, (depth / 2));
}

when target is GL_TEXTURE_2D_ARRAY, GL_PROXY_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, or GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, glTexStorage3D is equivalent to: 🌸

for (i = 0; i < levels; i++) {
    glTexImage3D(target, i, internalformat, width, height, depth, 0, format, type, NULL);
    width = max(1, (width / 2));
    height = max(1, (height / 2));
}

calling glTextureStorage3D 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 glTexImage3D. 🫢

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. πŸ‘‘

🚨 bestie, this is the serious part: using any command that might alter the dimensions or format of the texture object (such as glTexImage3D() or another call to glTexStorage3D) 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 big table and it's a whole moment, so let me set the scene. Every row gives you the Sized Internal Format, the Base Internal Format it maps to, then how many bits go to red, green, blue and alpha, plus a Shared Bits column. Heads up: the Shared Bits column is blank for literally every single row in the original, so I'm not gonna keep writing "and nothing shared" twenty-eight times. Also, wherever the original table leaves a bit-count cell empty, I just don't mention that channel. Everything else? Copied over exactly. πŸ’…

  • GL_R8 β€” base GL_RED; red 8 bits
  • GL_R8_SNORM β€” base GL_RED; red s8
  • GL_R16 β€” base GL_RED; red 16 bits
  • GL_R16_SNORM β€” base GL_RED; red s16
  • GL_RG8 β€” base GL_RG; red 8, green 8
  • GL_RG8_SNORM β€” base GL_RG; red s8, green s8
  • GL_RG16 β€” base GL_RG; red 16, green 16
  • GL_RG16_SNORM β€” base GL_RG; red s16, green s16
  • GL_R3_G3_B2 β€” base GL_RGB; red 3, green 3, blue 2
  • GL_RGB4 β€” base GL_RGB; red 4, green 4, blue 4
  • GL_RGB5 β€” base GL_RGB; red 5, green 5, blue 5
  • GL_RGB8 β€” base GL_RGB; red 8, green 8, blue 8
  • GL_RGB8_SNORM β€” base GL_RGB; red s8, green s8, blue s8
  • GL_RGB10 β€” base GL_RGB; red 10, green 10, blue 10
  • GL_RGB12 β€” base GL_RGB; red 12, green 12, blue 12
  • GL_RGB16_SNORM β€” base GL_RGB; red 16, green 16, blue 16
  • GL_RGBA2 β€” base GL_RGB; red 2, green 2, blue 2, alpha 2
  • GL_RGBA4 β€” base GL_RGB; red 4, green 4, blue 4, alpha 4
  • GL_RGB5_A1 β€” base GL_RGBA; red 5, green 5, blue 5, alpha 1
  • GL_RGBA8 β€” base GL_RGBA; red 8, green 8, blue 8, alpha 8
  • GL_RGBA8_SNORM β€” base GL_RGBA; red s8, green s8, blue s8, alpha s8
  • GL_RGB10_A2 β€” base GL_RGBA; red 10, green 10, blue 10, alpha 2
  • GL_RGB10_A2UI β€” base GL_RGBA; red ui10, green ui10, blue ui10, alpha ui2
  • GL_RGBA12 β€” base GL_RGBA; red 12, green 12, blue 12, alpha 12
  • GL_RGBA16 β€” base GL_RGBA; red 16, green 16, blue 16, alpha 16
  • GL_SRGB8 β€” base GL_RGB; red 8, green 8, blue 8
  • GL_SRGB8_ALPHA8 β€” base GL_RGBA; red 8, green 8, blue 8, alpha 8
  • GL_R16F β€” base GL_RED; red f16

And yeah, before anyone in the group chat comes for me β€” GL_RGBA2 and GL_RGBA4 really do list GL_RGB as their base internal format in the original table, not GL_RGBA. I'm not touching it. That's exactly what it says, bestie. 🫢

okay so picking right back up with the rest of the format table, bestie β€” same deal as before, just keep reading down the list πŸ’… each row is the sized internal format, then its base internal format, then the channel layout in order:

  • GL_RG16F β€” base GL_RG, channels f16, f16
  • GL_RGB16F β€” base GL_RGB, channels f16, f16, f16
  • GL_RGBA16F β€” base GL_RGBA, channels f16, f16, f16, f16
  • GL_R32F β€” base GL_RED, channel f32
  • GL_RG32F β€” base GL_RG, channels f32, f32
  • GL_RGB32F β€” base GL_RGB, channels f32, f32, f32
  • GL_RGBA32F β€” base GL_RGBA, channels f32, f32, f32, f32
  • GL_R11F_G11F_B10F β€” base GL_RGB, channels f11, f11, f10
  • GL_RGB9_E5 β€” base GL_RGB, channels 9, 9, 9, plus shared 5
  • GL_R8I β€” base GL_RED, channel i8
  • GL_R8UI β€” base GL_RED, channel ui8
  • GL_R16I β€” base GL_RED, channel i16
  • GL_R16UI β€” base GL_RED, channel ui16
  • GL_R32I β€” base GL_RED, channel i32
  • GL_R32UI β€” base GL_RED, channel ui32
  • GL_RG8I β€” base GL_RG, channels i8, i8
  • GL_RG8UI β€” base GL_RG, channels ui8, ui8
  • GL_RG16I β€” base GL_RG, channels i16, i16
  • GL_RG16UI β€” base GL_RG, channels ui16, ui16
  • GL_RG32I β€” base GL_RG, channels i32, i32
  • GL_RG32UI β€” base GL_RG, channels ui32, ui32
  • GL_RGB8I β€” base GL_RGB, channels i8, i8, i8
  • GL_RGB8UI β€” base GL_RGB, channels ui8, ui8, ui8
  • GL_RGB16I β€” base GL_RGB, channels i16, i16, i16
  • GL_RGB16UI β€” base GL_RGB, channels ui16, ui16, ui16
  • GL_RGB32I β€” base GL_RGB, channels i32, i32, i32
  • GL_RGB32UI β€” base GL_RGB, channels ui32, ui32, ui32
  • GL_RGBA8I β€” base GL_RGBA, channels i8, i8, i8, i8
  • GL_RGBA8UI β€” base GL_RGBA, channels ui8, ui8, ui8, ui8
  • GL_RGBA16I β€” base GL_RGBA, channels i16, i16, i16, i16
  • GL_RGBA16UI β€” base GL_RGBA, channels ui16, ui16, ui16, ui16

like… look at all those integer formats living their best life πŸ¦‹ and yes, the i / ui split is literally signed vs unsigned, no cap β€” keep scrolling, we're not done yet ✨

       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
       β”‚ GL_RGBA32I        β”‚ GL_RGBA  β”‚   i32    β”‚    i32     β”‚    i32    β”‚    i32     β”‚        β”‚
       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
       β”‚ GL_RGBA32UI       β”‚ GL_RGBA  β”‚   ui32   β”‚    ui32    β”‚   ui32    β”‚    ui32    β”‚        β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

and that's the whole table, bestie β€” she's done, she's complete, we can all go home πŸŽ€βœ¨


πŸ“ NOTES (the fine print era) 🧚

  • GL_STENCIL_INDEX8 is accepted for internalformat only if the GL version is 4.4 or higher. Like, it's invite-only, and the guest list starts at 4.4. No gatecrashing on 4.3, sorry babe πŸ’…

πŸ’€ ERRORS (aka the ways to break it, ngl) 😭

Listen β€” every single one of these is a little "no ma'am" from the driver. Learn them, love them, avoid them 🫢

  • GL_INVALID_OPERATION β€” generated by glTexStorage3D if zero is bound to target. Bestie. You have to have something bound. Zero is not a texture, it's a vibe, and not the good kind.
  • GL_INVALID_OPERATION β€” generated by glTextureStorage3D if texture is not the name of an existing texture object. If the name doesn't exist, we're not manifesting it into existence, that's not how this works ✨
  • GL_INVALID_ENUM β€” generated if internalformat is not a valid sized internal format. Sized, diva. The size is the whole point.
  • GL_INVALID_ENUM β€” generated if target or the effective target of texture is not one of the accepted targets described above. Color outside the accepted-targets lines and the enum gets mad.
  • GL_INVALID_VALUE β€” generated if width, height, depth or levels are less than 1. Anything below one is lowkey nothing, and nothing is not a dimension, periodt.
  • GL_INVALID_OPERATION β€” generated if target is GL_TEXTURE_3D or GL_PROXY_TEXTURE_3D and levels is greater than log 2 max width, height, depth + 1.
  • GL_INVALID_OPERATION β€” generated if target is GL_TEXTURE_2D_ARRAY, GL_PROXY_TEXTURE_2D_ARRAY, GL_TEXURE_CUBE_MAP_ARRAY, or GL_PROXY_TEXTURE_CUBE_MAP_ARRAY and levels is greater than log 2 max width, height + 1.
Ok real talk β€” yes, that last one says GL_TEXURE_CUBE_MAP_ARRAY, and no, I did not misspell it, that is character for character what the page says. Not me fixing it, not my job, we keep it exactly as written πŸ™ˆπŸ’€

🌈 VERSION SUPPORT (the "is this even available" chart) πŸ‘‘

       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚                    β”‚                OpenGL Version                                         β”‚
       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€
       β”‚ Function           β”‚ 2.0 β”‚ 2.1 β”‚ 3.0 β”‚ 3.1 β”‚ 3.2 β”‚ 3.3 β”‚ 4.0 β”‚ 4.1 β”‚ 4.2 β”‚ 4.3 β”‚ 4.4 β”‚ 4.5 β”‚
       β”‚ /                  β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚
       β”‚ Feature            β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚
       β”‚ Name               β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚
       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
       β”‚ glTexStorage3D     β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  βœ”  β”‚  βœ”  β”‚  βœ”  β”‚  βœ”  β”‚
       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
       β”‚ glTextureStorage3D β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  -  β”‚  βœ”  β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜

Read it and weep: glTexStorage3D shows up in 4.2 and stays for 4.2, 4.3, 4.4, 4.5 πŸ”₯ and glTextureStorage3D is a 4.5-only girlypop β€” literally one single check mark, main character energy, nobody else invited πŸ’…πŸ‘‘


πŸ¦‹ SEE ALSO (go read these next, iykyk) πŸ’œ

  • glTexImage3D()
  • glTexStorage1D()
  • glTexStorage2D()

Take one:

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/

Take two, the remix:

Copyright Β© 2011-2014 Khronos Group

Like, ok, iconic to list it twice β€” consistency queen 🫢✨ (both lines are legit, so here they both are, no cap.)


And that's a wrap on the whole page, bestie πŸ’– This gem is ripped from source [FIXME: source], dated 08/09/2021, and answers to the name GLTEXSTORAGE3D(3G) β€” go forth and allocate your 3D textures responsibly, mwah πŸ§šπŸ“β­

πŸ“¦ where this page comes from