In my understanding this code should always overwrite the very first row in my texture. But the real offset is taken from the glTexSubImage2D()-call, so I can pass whatever I want into glBufferSubData()?
No. What you feed glBufferSubData is the offset for the write into the buffer object. What you feed glTexSubImage2D is the offset for its read “from” the buffer object. Two separate operations.
Say you glBufferSubData 4 bytes at offset 0 with contents “ABCD” (silly example), then you point glTexSubImage2D at it with BUFFER_OFFSET(0). The texture will pull starting at the “A”. Or pass BUFFER_OFFSET(1), and it’ll start pulling at “B”.
Now let’s say after this you glBufferSubData 2 bytes at offset 1 with contents “ZZ”. This’ll update your buffer contents to be “AZZD”. Then if you point glTexSubImage2D at it with BUFFER_OFFSET(0), it’ll start pulling at “A”. Or pass BUFFER_OFFSET(1), and it’ll start pulling at the first “Z”.
glBufferSubData - update a portion of an existing buffer object
glTexSubImage2D - update a portion of a texture (e.g. from a portion of a buffer object)