glTexImage* allocates a data block for a MIPmap, sets its format, and copies the data you provide into it (if any)
glTexSubImage* only copies the data you provide into the existing MIPmap data block
So after you call glTexImage* once for a texture MIPmap level, you should never call it again. Use glTexSubImage* to change the contents.
If you provide a data pointer to glTexImage* it must be for the whole MIPmap. But for glTexSubImage*, it can be for the whole MIPmap OR a subregion of the MIPmap.
Also note that if your texture has a compressed internal format and you provide uncompressed texels to these calls, they’ll cause the driver to do run-time texel compression which can be time consuming.
To clarify what strattonbrazil said, when you call glTexImage2D, you fix the internalFormat for the texture MIPmap and the layout (e.g. 2D, 3D, etc.) for the texture, and the driver allocates the data block for that MIPmap.
So in the future when you change the texels via glTexSubImage, you should use the same target.
The internalFormat as I said is fixed and you can’t change it via glTexSubImage – there’s no such argument.
And the format/type arguments can be whatever you need as they don’t describe the format of the texels in the texture, but rather the format of the texels in the data block you’re providing to glTexImage/glTexSubImage to copy into the texture.