Search code examples
opengltextureview

OpenGL compressed texture views valid formats


What internal format combinations would work for this following code example, if my intention is to have raw storage allocated as a non compressed texture and the texture view interpreting this as BC5 / RGTC ?

GLuint texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_3D, texId);
glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA32UI, 4, 4, 16);
glBindTexture(GL_TEXTURE_3D, 0);

assertNoError();

GLuint viewId;
glGenTextures(1, &viewId);
glTextureView(viewId, GL_TEXTURE_3D, texId, GL_COMPRESSED_RG_RGTC2, 0, 1, 0, 1);
assertNoError();

glDeleteTextures(1, &viewId);
glDeleteTextures(1, &texId);
assertNoError();

This example failed with INVALID_OPERATION and the GL debug output message says:

Internal formats neither compatible nor identical.

To narrow my question by exclusion:

  • glCompressed* with pixel unpack buffer is not an option.
  • TexStorage cannot have the compressed internal format. This is GL 4.5 and that has been removed.
  • OpenGL spec says this following pair is compatible: GL_RGTC2_RG, GL_COMPRESSED_RG_RGTC2. However GL_RGTC2_RG is not a GL define or defined value in any header or the spec.

Solution

  • You cannot allocate storage of a non-compressed format and view it with a compressed format. Or vice-versa. You can copy between compressed and uncompressed formats via glCopyImageSubData. But you can't do the kind of "casting" that you're trying to do.

    Furthermore:

    TexStorage cannot have the compressed internal format. This is GL 4.5 and that has been removed.

    You cannot use generic compressed image formats, but specific formats (like GL_COMPRESSED_RG_RGTC2) are still available. Just not for 3D textures (BPTC can work with 3D textures, but not RGTC).


    Vulkan has a mechanism for creating a VkImage of a compressed format from which you can then create a VkImageView with an appropriate uncompressed format (the reverse isn't allowed, but that doesn't really matter all that much). To do this, the image has to be created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT creation flag, and the view must use a 32-bit unsigned int format, with sufficient components for each pixel of the view to correspond to the block byte size for the format.