glGenerateMipmap(GL_TEXTURE_2D_ARRAY)

Hello,

i’m trying to streaming textures for an out of core terrain rendering system. GL_TEXTURE_2D_ARRAY seems the way to go. I create a GL_TEXTURE_2D_ARRAY with for example 128 layer. Each frame i need to update them.
Here comes my problem: to avoid aliasing problems i need to create Mipmaps. So glGenerateMipmap(GL_TEXTURE_2D_ARRAY) would be good, but it seems that it creates mipmaps for ALL the layers for each call.

Is possible to affect only one layer of the texture array with glGenerateMipmap(GL_TEXTURE_2D_ARRAY) ?

No. An array texture is not X separate 2D textures that all use the same texture object name. Array textures are basically 3D textures where there is no filtering between depth layers and the depth of the texture doesn’t decrease in lower mipmaps.

I wouldn’t suggest using an array texture for streaming data the way you’re suggesting. Array textures are generally intended to solve texture atlas problems. The array of textures is treated as a single whole, not a number of pieces.

Thank you Alfonse.

Oh this is not a good news… Because i think that texture array are very good for terrain. You have to bind only one texture for each patch and you can improve further using instancing. With texture array and instancing rendering terrain is very GPU friendly:

Bind color texture array
Bind heightfield texture array
Bind Uniform buffer object for instance data
Rendering N instanced vbo patches of the culled quadtree
UnBind Uniform buffer object for instance data
UnBind color texture array
UnBind height texture array

Anyway, create ALL mipmaps of the texture array each time i call glGenerateMipmap(GL_TEXTURE_2D_ARRAY) is not so good.

I think it should be possibile to do that.

You can work-around by manually creating the mipmaps for the slice you just updated.

For that you would need 2 fbos and couple of blits.
GL would probably do something similar internally when you ‘glGenerateMipmap’ but you will probably synchronize harder, so your performance may not be that great (then again, it may be good).

With texture array and instancing rendering terrain is very GPU friendly:

And if you added, say, 10 texture state changes to that, do you think that this would be a significant impediment to rendering performance?

I highly doubt it. Render calls for terrain heightmaps are not going to be a significant factor in rendering overall.

Also, instancing is worse in terms of performance unless you have instance numbers in the thousands or so. So I doubt that what you have is as “GPU friendly” as you think.

Anyway, create ALL mipmaps of the texture array each time i call glGenerateMipmap(GL_TEXTURE_2D_ARRAY) is not so good.

Why are you calling this to begin with? In general, you’ll get better results from off-line mipmap generation. You’re already streaming textures, so just stream more data.

I’m using a wavelet compressed format like ecw and jpeg2000 from satellite image and dted data. The decompression is done on the cpu at run-time. So yes, i could work around generating each mipmap pyramid for each decompressed textures on the CPU and streaming them too but i would like to avoid it.

Further, the quadtree is deep ( 15 levels for now ) and, depending of the quality you want, it can becomes a 200 nodes of a culled quadtree. So there are not 10 textures bindings but 200 * 2!

So there are not 10 textures bindings but 200 * 2!

That’s still not enough to make instancing worthwhile. And if all you’re rendering is terrain and maybe a few meshes on top of that, then 400 state changes is pretty trivial.

Anyway, it doesn’t matter, since you have a choice to make. What you want is not possible and isn’t likely to be forthcoming in the near future for hardware. So you can:

1: use individual textures where you can control the mipmapping, and live with having potentially 400 state changes in your render loop.

2: use an array texture and accept that you will need to generate and upload mipmaps manually (unless you want to spend a lot of time in glGenerateMipmap).