Ok, I don’t know whether the driver leaks, but I had to find a thread title.
Here’s the problem:
glTexImage2D allocates a hell of a lot of system RAM, and I have no clue why this happens.
Here’s the texture loading code:
int CTexture::Load (ubyte* buffer)
{
OglGenTextures (1, reinterpret_cast<GLuint*> (&m_info.handle));
m_info.prio = m_info.bMipMaps ? (m_info.h == m_info.w) ? 1.0f : 0.5f : 0.1f;
glPrioritizeTextures (1, (GLuint *) &m_info.handle, &m_info.prio);
Bind (); // basically calling glBindTexture
// setup mipmap generation
glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GLint (m_info.bMipMaps && gameStates.ogl.bNeedMipMaps));
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (m_info.bSmoothe) {
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gameStates.ogl.texMagFilter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gameStates.ogl.texMinFilter);
}
else {
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
// m_info.internalFormat: Component count (e.g. 4 for RGBA)
// m_info.format: Texture format (e.g. GL_RGBA)
// m_tw, m_th: Texture dimensions (always powers of two)
glTexImage2D (GL_TEXTURE_2D, 0, m_info.internalFormat, m_info.tw, m_info.th, 0, m_info.format, GL_UNSIGNED_BYTE, buffer);
}
The weirdest thing is that although Process Explorer shows that there’s almost 2 GB available memory, I get an out of memory error when loading the third or forth level in a row (like load level 1, use cheat to load level 2, then level 3, … BAM!). Memory fragmentation? I have checked my own texture/bitmap management: It nicely returns all memory it has used.
It’s also weird that when loading level 2, available memory goes up to about 2 GB (after having freed level 1’s data), but then goes down below what had been available after loading level 1, when loading level 3 available memory goes up again and then below what was available after loading level 2.
I have made very sure that all textures allocated in the OpenGL driver are released when unloading a level’s data (glDeleteTextures).
I can say for sure that my program doesn’t directly allocate all that memory. It takes about 530 MB for level 1, but then another 530 are taken during loading the textures to the OpenGL driver. I have checked this in the debugger: When arriving at the code that sends the texture data to the driver, almost all texture data has been loaded from disk to memory (program will still compute a few transparency masks consuming about 10 MB). When I turn off mipmap generation, the memory loss is significantly lower, but still present (looks like glTexImage2D consumes RAM).
Before sending the textures to the driver I am having 1533 MB free RAM and 523 MB allocated for texture data. After having sent them, I am having 1 GB free RAM and 533 MB allocated for texture data. It looks like the entire texture data gets duplicated by the driver. Now when I disable mipmap and texture generation (by basically not calling CTexture::Load()), no extra memory gets consumed.
The problem doesn’t depend on mipmap generation settings. It still occurs when turning mipmap generation off and loading the textures to the driver.
glGetError() after glTexImage2D always returns zero.
After having freed up all memory used for the level, and before loading the next level, free memory goes back up to about 2 GB.
Hardware/driver: ATI Radeon HD 4870 1 GB, Catalyst 9.2. Other people with different hardware (also NVidia) have the same problem though.
WTF?!