Batching geometry using different textures in ES3

This topic contains 10 replies, has 3 voices, and was last updated by  Dark_Photon 2 years, 7 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #32000

    Slion
    Member

    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?

    #39523

    PaulL
    Admin

    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.

    #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?

    #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.)

    #44968

    Slion
    Member

    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.

    Something like:

    
    uniform sampler2D uTextures[8];
    varying vec3 vTexCoord;
    gl_FragColor=texture2D(uTextures[vTexCoord.z], vTexCoord);
    
    #45023

    PaulL
    Admin

    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.

    #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!

    #47416

    PaulL
    Admin

    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.

    #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?

    #47472

    PaulL
    Admin

    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.

    #47562

    Good to know — thanks!

Viewing 11 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic.