For a 3D texture, it’s hard to say which would be better. For 2D, you can use render-to-texture (
glFrameBufferTexture*) to efficiently initialise portions of a texture, but for 3D you’d have to do it one layer at a time and the added cost may outweigh the benefits of using the GPU.
If you’re starting with (non-power-of-two) data in CPU memory, it would be better to create the texture with power-of-two dimensions then initialise portions using
glTexSubImage3D. Note that you have to provide data for each call; there’s no way to fill a region with a constant value. If you’re starting with a texture in GPU memory, keeping the data in GPU memory using
GL_PIXEL_PACK_BUFFER for reads and
GL_PIXEL_UNPACK_BUFFER for writes would be better than going through CPU memory.
For filling the unused portions with zeros, one option is to use
glTexSubImage3D with a sufficiently large block of zeroes which is already on the GPU. A compute shader (with
imageStore) could be used, but I don’t know whether a trivial compute shader will be efficient. If you aren’t doing the FFT in-place, accepting a non-power-of-two source texture and forcing out-of-texture values to zero in the first pass may be more efficient than padding.