Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Memory leak when using glUniform?

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2017
    Posts
    8

    Memory leak when using glUniform?

    I have noticed a memory leak in my program, and seems like if i comment out the commented lines in the following code, the leak goes away.

    The code goes like this:
    Code :
    	groundShader->Use();
     
    	int	vertexLoc = glGetAttribLocation(groundShader->Program, "InVertex");
    	int	texCoord0Loc = glGetAttribLocation(groundShader->Program, "InTexCoord0");
     
    	glActiveTexture(GL_TEXTURE0 + 0);
    	glBindTexture(GL_TEXTURE_2D, c->AlphaMap->ID);
    //	glUniform1i(glGetUniformLocation(groundShader->Program, "AlphaMap"), 0);
     
    	/*glActiveTexture(GL_TEXTURE0 + 1);
    	glBindTexture(GL_TEXTURE_2D, GroundTextures[c->groundTexIDs[0]]);
    	glUniform1i(glGetUniformLocation(groundShader->Program, "groundRedTex"), 1);
     
    	glActiveTexture(GL_TEXTURE0 + 2);
    	glBindTexture(GL_TEXTURE_2D, GroundTextures[c->groundTexIDs[1]]);
    	glUniform1i(glGetUniformLocation(groundShader->Program, "groundGreenTex"), 2);
     
    	glActiveTexture(GL_TEXTURE0 + 3);
    	glBindTexture(GL_TEXTURE_2D, GroundTextures[c->groundTexIDs[2]]);
    	glUniform1i(glGetUniformLocation(groundShader->Program, "groundBlueTex"), 3);
     
    	glActiveTexture(GL_TEXTURE0 + 4);
    	glBindTexture(GL_TEXTURE_2D, GroundTextures[c->groundTexIDs[3]]);
    	glUniform1i(glGetUniformLocation(groundShader->Program, "groundAlphaTex"), 4);
     
    	glEnableVertexAttribArray(vertexLoc);
    	glEnableVertexAttribArray(texCoord0Loc);
     
    	glBindBuffer(GL_ARRAY_BUFFER, c->GroundMesh->VBO);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, c->GroundMesh->IBO);
     
    	glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCompound), 0);
    	glVertexAttribPointer(texCoord0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(VertexCompound), (const void*)(sizeof(float) * 3));
     
    	glEnableClientState(GL_VERTEX_ARRAY);
     
    	glDrawElements(GL_TRIANGLES, c->GroundMesh->IBOSize, GL_UNSIGNED_INT, 0);
     
    	glDisableClientState(GL_VERTEX_ARRAY);
     
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     
    	glDisableVertexAttribArray(vertexLoc);
    	glDisableVertexAttribArray(texCoord0Loc);*/
     
    	glUseProgram(0);
    However as soon as i uncomment the line "glUniform1i(glGetUniformLocation(groundShader->Program, "AlphaMap"), 0);", my program's memory usage slowly creeps up. Am i doing something wrong?
    (The code is for a shader that uses alpha-mapping to mix 4 different textures onto a mesh.)

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,728
    A couple of observations.

    Firstly, it's common enough for memory usage to gradually increase to a point, then level off and not increase any more. If you haven't run your program long enough to check if this is, in fact, what's happening, then I suggest that you do so and report back.

    Secondly, uniform values are per-program state in OpenGL. A consequence of this is that if a uniform value never needs to change (and sampler uniforms are exactly of this type) then you can set them just once after program creation, rather than each frame, and they will survive for ever after, including surviving multiple glUseProgram calls. So doing this will work around your observed leak.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2017
    Posts
    8
    Quote Originally Posted by mhagain View Post
    A couple of observations.

    Firstly, it's common enough for memory usage to gradually increase to a point, then level off and not increase any more. If you haven't run your program long enough to check if this is, in fact, what's happening, then I suggest that you do so and report back.

    Secondly, uniform values are per-program state in OpenGL. A consequence of this is that if a uniform value never needs to change (and sampler uniforms are exactly of this type) then you can set them just once after program creation, rather than each frame, and they will survive for ever after, including surviving multiple glUseProgram calls. So doing this will work around your observed leak.

    Thanks for the reply!

    Running my program without calling the render function (consisting of the above code), the memory usage flattens out at around 51000 Kb.
    How ever with the render function being called, the memory keeps going up without any signs of stopping. I ran it for ten minuts and it reached half a Gb!

    Anyways, i could change my program to only set the uniforms once, during startup, but this seems more like avoiding the problem then figuring out what it is. And if i decide to implement lights that move, i would end up having this problem again.

    Edit:
    Also, why can i not do something like: texture2D(<integer>, texture_coordinate) in my glsl shader? I always bind "AlphaMap" to GL_TEXTURE0 and "groundRedTex" to GL_TEXTURE0+1, so why do i have to use glUniform1i() to tell the shader that i have bounded it?
    Last edited by c4ooo123; 07-21-2017 at 03:44 PM.

  4. #4
    Junior Member Regular Contributor
    Join Date
    Sep 2013
    Posts
    172
    I would suggest stripping your program down bit by bit until you are left with the smallest possible program which still shows the problem. Finding the source of leaks in big development code can be very difficult.

  5. #5
    Junior Member Newbie
    Join Date
    Apr 2017
    Posts
    8
    Quote Originally Posted by Cornix View Post
    I would suggest stripping your program down bit by bit until you are left with the smallest possible program which still shows the problem. Finding the source of leaks in big development code can be very difficult.
    As i said, the leak does not happen if the render function is never called, so unless some outside code can have an effect, the problem stems from there

    Also, i just resized that i cant move the glUniform1i() outside my render function. My world is split into cells/chunks, and each cell has its own alphamap and its own 4 different ground textures that must be bound when that cell is rendered. (the alpha map's red channel tells how strong ground texture #1 should be in a fragment, green tells how strong ground texture #2 should be, and so on: gl_FragColor = (texture2D(groundRedTex, texture_coordinate) * AlphaMapFrag.r + texture2D(groundGreenTex, texture_coordinate) * AlphaMapFrag.g ... etc for all 4). Thus when i render a different cell, i need to bind that cell's alpha map and that cell's four ground textures.

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,728
    The glUniform1i call is nothing to do with which texture is bound. It's used for associating a texture unit with a sampler uniform. So changing the bound texture has no effect on it, and you absolutely can move it outside of your render function.

  7. #7
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    445
    Quote Originally Posted by c4ooo123 View Post
    ... why can i not do something like: texture2D(<integer>, texture_coordinate) in my glsl shader? I always bind "AlphaMap" to GL_TEXTURE0 and "groundRedTex" to GL_TEXTURE0+1, so why do i have to use glUniform1i() to tell the shader that i have bounded it?
    take a look at possible layout qualifiers
    you can directly in the shader source specify the texture unit to sample from:
    Code glsl:
    layout(binding = 3) uniform sampler2D mainTexture;

  8. #8
    Junior Member Newbie
    Join Date
    Apr 2017
    Posts
    8
    Quote Originally Posted by mhagain View Post
    The glUniform1i call is nothing to do with which texture is bound. It's used for associating a texture unit with a sampler uniform. So changing the bound texture has no effect on it, and you absolutely can move it outside of your render function.
    Thanks! I thought you had to set the uniform every time you bound a texture. (Cant use 'layout' becouse opengl 2.1 ):

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •