memory problems

#1

Hi,

when I create a buffer using glBufferData, memory is used up on the CPU. When I change the data, because say the colours of the vertices change. I delete the Buffer using glDeleteBuffers, memory is not deleted from the cpu. Then when I generate a new buffer using the same array, with the new colours using glBufferData more memory is used up on the CPU. I have a memory problem and moving from version 1 to version 4 has not solved it, it seems.

Any help gratefully appreciated please


size_t szTemp;

	if (cClearVBOBuffer == 1)
	{
		glDeleteBuffers(1, &indexBufferID);
		glDeleteBuffers(1, &triangleVBO);
		if (cDebug == 'y')
		{
			GLenum GLenumError;
			GLenumError = glGetError();
			if (GLenumError != GL_NO_ERROR)
				OGLErrorCode(GLenumError);
		}
	}
	
	gluiNoOfPointCloudPoints = PointCloudVBO(hwnd);
 
	cClearVBOBuffer = 1;
	SetUpProcs();


	//glm::translate(glm::mat4(1.f), glm::vec3(glfHoriz, glfVert, -(glfZoom - (GLfloat)gldRadius)));// (glfHoriz, glfVert, -(glfZoom - (GLfloat)gldRadius));//100.0);
	polarViewVBO(((GLdouble)glfZoom), 0.0, (GLdouble)flatitude, (GLdouble)flongitude);

	//vbo stuff

	glGenBuffers(1, &triangleVBO);
	glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
	//glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);// sends data to the graphics card
	//GLMPOSCOL
	glBufferData(GL_ARRAY_BUFFER, (sizeof(POSCOL) * (size_t)gluiNoOfPointCloudPoints), mmvertex, GL_DYNAMIC_DRAW);// GL_STATIC_DRAW);//creates and initializes a buffer object's data store

	if (cDebug == 'y')
	{
		GLenum GLenumError;
		GLenumError = glGetError();
		if (GLenumError != GL_NO_ERROR)
			OGLErrorCode(GLenumError);
	}


	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);

	glEnableVertexAttribArray(1);//note the 1, is the first argument in the glvertexattribPointer which makes the connection
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (char*)(sizeof(GLfloat) * 3));//the char is a GL thing but essential
	

	//************ INDEX STUFF ****************
	GLuint indexBufferID;

	glGenBuffers(1, &indexBufferID);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);//part of the process sending data to the graphics card
	szTemp = sizeof(GLuint) * (size_t)gluiNoOfPointCloudPoints;
	//glBufferData(GL_ELEMENT_ARRAY_BUFFER, (size_t)(sizeof(GLuint) * (size_t)gluiNoOfPointCloudPoints), indecis, GL_STATIC_DRAW);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, (size_t)szTemp, indecis, GL_STATIC_DRAW);

	
	if (cDebug == 'y')
	{
		GLenum GLenumError;
		GLenumError = glGetError();
		if (GLenumError != GL_NO_ERROR)
			OGLErrorCode(GLenumError);
	}

	
	InstallShaders(hwnd);

	
}

#2

glDeleteBuffers() won’t recover the memory until any pending commands which use the data have finished. This might not occur until several frames after those commands were enqueued.

You can use fences (glFenceSync, glWaitSync) to wait until commands have actually completed, but overdoing this will hurt performance. You ideally want at least one full frame buffered, so you’ll end up with at least two copies of any buffer which is modified each frame.

Alternatively, using glBufferSubData() to overwrite part of an existing buffer will typically stall the CPU until the GPU has finished using the data being overwritten. Again, this will hurt performance if you don’t have enough additional storage (i.e. if you’re just overwriting the portion which you used on the previous frame).

See the wiki page on Buffer Object Streaming for advice on how to exert more control on memory usage without unnecessary synchronisation.

#3

A couple thoughts for you to consider.

The GL driver pools memory, and you typically don’t have any direct control of how it allocates it.

Before we go there though, the first thing is to verify that the memory consumption is in the GL driver and not in your application. It could be that CPU memory is being leaked in your app code. Try commenting out all of the GL calls. Does the memory growth go away?

If not, make sure you aren’t leaking GL resources. If your app loses track of a handle, it continues to consume space.

Also, when you say memory is “used up” on the CPU, what are you looking at? Total pageable size (working set), total pages unique to the process (private working set), total virtual size, pinned memory (non-paged), … ?

#4

Thank you for your help.

Dark Photon, the memory is used at the glbufferdata statements.
By using memory I mean that before the statement is reached Task manager tell me that the memory is say 100.0MB, after the statement is read, the memory is 105.2MB. The next time it is read, the memory increases to 110MB.

GClements,
I have tried this to try and stop the memory from increasing.



glBufferData(GL_ARRAY_BUFFER, (sizeof(POSCOL) * (size_t)gluiNoOfPointCloudPoints), NULL, GL_STREAM_DRAW);

	
	buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);// GL_WRITE_ONLY);
	
	memcpy(buffer, mmvertex, (sizeof(POSCOL) * (size_t)gluiNoOfPointCloudPoints));
	glUnmapBuffer(GL_ARRAY_BUFFER);

Similarly the memory increases by the same amount at memcpy.

I have tried free(buffer), but it did not like that.