- March 6, 2015 at 2:13 pm #32000
Is there a recommended way to batch geometry using different textures?
Should I go for 2D texture arrays?
Should I try using multiple texture units and an array of sampler? Is there such a thing as a sampler array? Could I use an if/switch instead?March 10, 2015 at 3:01 pm #39523
Generally, in OpenGL you should aim to change render state as little as possible, as there is significant overhead in doing so.
Texture atlases and texture arrays are useful for this, since you can upload many textures to the graphics driver without rebinding. Use sampler2DArray to access the array in your shader.
Conditional branching in shaders can be unpredictable performance-wise on PowerVR hardware, so is generally best avoided. Particularly on Series 5 hardware, when sampling textures, as it can bypass texture prefetching resulting in a dependent texture read, which is very bad for performance.March 18, 2015 at 1:17 pm #43387
Related to your question on using 2D texture arrays Slion, if an application can’t pre-upload all layers (2D images) to a 2D texture array on startup and needs to upload slices dynamically…
Each time you update a slice in a texture array:
1) Is the warm-up cost that for the entire 2D texture array, or just for the updated layer(s)?
2) If you upload to layers which have not been used in the last 2-3 frames, but a draw referencing other layers has been issued in the last 2-3 frames, do you risk ghosting the entire texture array?
Trying to decide for some future work when to prefer texture arrays on PowerVR?March 18, 2015 at 1:25 pm #43392
Related: If entire 2D tex array ghosting and/or warm-ups for dynamic updates is a problem…
Is there some equivalent to bindless textures (see ARB_bindless_texture from OpenGL-land) for PowerVR? That would work as well.
(FWIW, bindless texture gets rid of concept of texture units and the indirect mapping they impose (texture handles -> texture units -> shader), which inhibits batching across many 2D textures, and allows shaders to sample from textures based on texture handle directly.)March 19, 2015 at 12:54 pm #44968
Conditional branching in shaders can be unpredictable performance-wise on PowerVR hardware, so is generally best avoided. Particularly on Series 5 hardware, when sampling textures, as it can bypass texture prefetching resulting in a dependent texture read, which is very bad for performance.
That’s why I was wondering if I could have an array of samplers each using a different unit. Thus I could batch my geometry by adding the expected index in the sampler array as an extra vertex attribute or in a third texture coordinate dimension.
uniform sampler2D uTextures; varying vec3 vTexCoord; gl_FragColor=texture2D(uTextures[vTexCoord.z], vTexCoord);March 19, 2015 at 5:08 pm #45023
You can think of texture arrays just as a group of textures allocated together, but the textures are still referenced as individual textures. glTexStorage will create the space on the GPU in one shot, but each texture must then DMA into a unique texture object.
So, after the initial allocation of the array, you shouldn’t have to worry about it, every call to glTex(Sub)Image will only incur the cost of upload into the slot in the array, and then the subsequent warm-up cost of copying into the texture object.March 21, 2015 at 1:14 am #45578
Ok, thanks Paul! So if uploads are per slot (layer), warm-ups are per layer as well — good!
How about ghosting when updating layers in a 2D texture array? Will the whole texture array ghost (in the example I mentioned above)? –Thanks!March 23, 2015 at 11:42 am #47416
Edit: What I had written previously was incorrect, please disregard.
Yes, it would ghost the entire array. Because the entire texture array is bound, it isn’t possible to know ahead of time which layers will be read by the shader.
You should think of updating texture arrays as having the same caveats as updating a plain 2D texture, the situations where ghosting would occur are the same but the cost would be far greater.March 23, 2015 at 3:34 pm #47467
Ok, thanks again Paul! I appreciate you checking into that. That’s very helpful info to know up-front!
So just to make sure my understanding is solid, if you upload a new layer to a 2D texture, would the warm-up/swizzle be done only on that layer, or would you incur a re-warmup on the entire array?March 23, 2015 at 5:06 pm #47472
I should add I was also incorrect about the warm-up behaviour. A call to glTexSubImage when backed by glTexStorage will perform the warm-up step immediately.
This warm-up is only on the updated layer rather than the entire array.
Additionally, after a call to glTexSubImage only the area of the texture that was updated needs to be twiddled again.