Reputation: 491
I am trying to understand what happens when a new texture is created in OpenGL. I have always thought that when
glTexImage2D
is run, the texture was stored in the CPU, and it isn't until it is activated
glActiveTexture;
glBindTexture;
that the image is copied to the GPU. However after reading a bit, I feel like my understanding is wrong. I realized that it is impossible for many OpenGL versions to read back texture pixel values which made me think that the data is stored on the GPU which is why there isn't the ability to read back the pixels. And GLreadpixels is slow because it is copying information from GPU memory. Does glTexImage2D
create the memory on the GPU, while activate texture and bind texture just set the handles for the program to use the image? This would make sense because it would be too expensive to copy the image data back and forth each time the image is used. Is this something that is gl implementation specific? The documentation doesn't give any information about where the data is stored and I haven't been able to find any answers online.
Upvotes: 2
Views: 2508
Reputation: 645
Generally I assume it's up to the driver when it stores the data on the GPU, most OpenGL functions tend to push data towards the GPU VBO-s for example explicitly state that the resulting object is in GPU memory. In OpenGL you provide a pointer to the texture data then the implementation processes it but never owns the memory you provided so you can free it right after the call.
glTexImage and glTexSubImage do not directly use the buffer you provide:
void glTexImage2D( GLenum target,
GLint level,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const GLvoid * data);
internalFormat - is an interesting parameter since it denotes the internal storage however it is never guaranteed that it will be stored like this, I've read papers in the past that said that some ATI/AMD GPUS dont even support non-RGBA formats so if you say GL_RGB for internalFormat it will convert it to RGBA anyways because that's what it supports, this was fixed in Vulkan since you can query the actual supported formats and upload textures in the format it will be stored on the GPU. format, type, data is required since the implementation needs to know what it will get from you. Judging form the time it takes to perform a texture upload and no later hiccups when using it, I think it's safe to assume that a texture update most likely directly uploads to GPU memory.
Using PBOs ( pixel buffer objects ), changes nothing since you do the same thing, but you specify NULL for the data parameter and bind a PBO which is guaranteed to be in GPU memory to act as the upload source.
The glGenTextures call just creates objects on the CPU side, think of it as an array that holds information for texture "objects" that you get id-s to. Later you use these ids to initialize the texture via glTexImage where you specify the storage and essential parameters, using glTexSubImage then can be used to update whole or parts of the image. It's also faster to use glTexSubImage to update the texture than call tex glTexImage which shows that the implementation does something differently.
glReadPixels is slow because it reads the framebuffer that resides in the GPU into CPU memory space, because GPU makers tend to push loads as much as possible on the GPU side, for example transform feedback solves the problem of needing to feed the GPU from CPU space, you can just shuffle buffers without the need to touch them from CPU space and simulate 1M particles with ease which will die with a CPU bottleneck otherwise.
If your assumption was indeed true that information is uploaded when the textures are first used then the first time you render a massive scene you would get an astonishingly huge lag because all textures are being uploaded one after another. This you can test by uploading a lot of textures and measure how much time glTexImage takes and how much time it takes to first show them. As far as know the glTexImage call can take a lot of time depending on the texture size, of course this also depends on the device, but let's say 15 ms to upload a texture is a lot.
Upvotes: 3