glCompressedTextureSubImage3D Usage When using an array texture I can call:

glTextureStorage3D(m_texture_array, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, m_num_billboards);
for (int i{}; i &lt; 4; ==i) {
    glTextureSubImage3D(m_texture_array, 0, 0, 0, i, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
}


Which results in a compressed image. So when do I need to use glCompressedTextureSubImage3D ?

Furthermore, the docs say:


  internalformat must be a known compressed image format (such as GL_RGTC) or an extension-specified compressed-texture format


Why can't it be a generic format?
OK, when you call the regular SubImage functions, you are passing pixel data. You are provoking a pixel unpack operation, where the implementation will read the pixels from your data in the format specified and convert them to the internal format of the image.

However, if already have compressed data, you don't want that conversion. You just want to pass the compressed data to the GL, and have it use it directly. That's what the Compressed functions are for.

If you want to compress uncompressed data, you use the non-Compressed functions. But you really, really, shouldn't. Indeed, with ASTC, you can't compress the data online. And even for other formats, the quality of the result will be rather sketchy.

Do you really want to rely on the quality of a compression algorithm written to be fast rather than good?

The format and type transfer parameters describe a single pixel's worth of data, and compressed formats don't generally store data in units of "pixels". Compressed formats usually use blocks of some size. Regular pixel transfers expect a 1:1 correspondence between a pixel in your data and a pixel in the GL-owned image. That simply isn't the case when dealing with compressed data.

So you need a new function, which just takes a block of bits of a known size, whose format is defined by the image's format, and jams it into the image.

The reason why you can't use a generic compressed format with the Compressed transfer functions should be obvious by now. These functions are for providing compressed data in a specific format; by definition, the generic formats are implementation defined. So there's no way you could possibly know what data to provide for generic compressed transfers.