What are the limits of texture array size?
Asked Answered
C

1

9

I kinda sorta get a grip what texture arrays are about, but nowhere on the internet I can find info about what they actually are. Are they like one big texture atlas (singular continuous block of memory divided in parts of equal dimensions), or are they like texture units (completely separate textures that you can bind all at once)? The consequence of this question is, what are the size limits of a single texture array, and how to use them efficiently? If, for example, my GPU handles 4096x4096 textures and 64 units, can I create a texture array of 64 4096x4096 textures? Or is the actual limit 4096*4096 pixels per array? Or maybe something else? How to query the limit?

Commodore answered 10/6, 2014 at 16:18 Comment(0)
H
11

They are arrays of images (the concept is generally referred to as layered images, because there are multiple types of textures that actually store multiple images). An array texture is special in that it has equal dimensions for each of its layers. Additionally, though the memory is allocated the same way as a 3D texture, filtering across image layers is impossible for array textures and the mipmap chain for a 2D array texture remains 2D.

The very first form of array texture ever introduced was the cube map, it had 6 2D layers... but it also had a special set of lookup functions, so it was far from a generic 2D array texture.

Nevertheless, the limit you are discussing is per-image dimension in your array texture. That is, if your maximum texture size is 4096, that means a 2D texture is limited to 4096x4096 per-image for the highest detail mipmap level.

Layers in your array texture are not like Texture Image Units at all. They are separate images, but they all belong to a single texture object, which can be bound to a single Texture Image Unit.

The maximum number of layers in your array texture can be queried this way:

GLint max_layers;
glGetIntegerv (GL_MAX_ARRAY_TEXTURE_LAYERS, &max_layers);

On the topic of using array textures efficiently, you may consider a new feature called Sparse Array Textures (via GL_ARB_sparse_texture).

Say you wanted to reserve enough storage for a 4096 x 4096 x 64 array texture but only actually used 4 or 5 of those layers initially. Ordinarily that would be horribly wasteful, but with sparse textures, only the 4 or 5 layers in-use have to be resident (committed). The rest of the layers are handled like demand-paged virtual memory in operating systems; no backing storage is actually allocated until first use.

Heatherheatherly answered 10/6, 2014 at 16:46 Comment(4)
About sparse textures, I'm not confident enough about its compatibility with older hardware to use it - you know, I'm making a 2D game, and I'd rather not use anything that isn't 99% guaranteed to run on any hardware there is. Wouldn't it work if I initially made one-layer-deep texture array, and if I need another one, use glTexImage3D to resize it? I'm using OGL 3.2.Commodore
Yeah, I would not use it if your intention is to support older hardware. It is generally a DX11.2 class hardware feature, older GPUs can support it, but nothing that is not GL4.4 / DX11.2 compliant is required to support it. You can resize your array texture definitely, the convenient thing about a sparse array texture though is that you are not limited to indices that begin at 0 (for example with the 64 layer array texture discussed, you might have only 2 allocated images at 34 and 46 - to do that normally they would need to be at 0 and 1), so it can simplify things like atlas packing.Heatherheatherly
One more question. If I use glTexImage3D on existing texture array with null data (as in, just to resize), and use the same width and height, but different depth, is the data of lower layers guaranteed to stay intact?Commodore
Unfortunately, no. glTexImage* (...) functions are effectively equivalent to a combination of malloc (...) and free (...) in C. They will free the original texture memory when it is no longer being used by pending commands and will allocate new storage. To resize the texture while keeping data you would have to create a new texture and use glCopyTexSubImage3D (...) to transfer the old image data. It would be even more complicated than that, because glCopyTexSubImage3D (...) uses the read buffer, so your original texture would have to be attached to an FBO for that to work :-\Heatherheatherly

© 2022 - 2024 — McMap. All rights reserved.