If there’s a fixed stride between rows, call
glPixelStorei with the first parameter set to
GL_UNPACK_ROW_LENGTH before calling
glTexImage2D. Remember to set it back to zero afterwards if you have other textures.
If each row is at an arbitrary offset, call
glTexImage2D without anything bound to
GL_PIXEL_UNPACK_BUFFER and with a null pointer for the
data parameter to allocate storage without uploading data, then call
glTexSubImage2D to upload each row of data.
With OpenGL 4.2+, you can also use
glTexStorage2D to allocate storage without uploading data. That makes the texture an “immutable-format” texture; you can modify the texture data but not the format, dimensions or number of mipmap levels.
Do you need to control the transfer of data between client memory and the PBO, or between the PBO and the texture? For the former, you can call
glBufferData with a null data pointer to allocate storage without transferring data, then use
memcpy) to transfer portions of the data.