PDA

View Full Version : Index Arrays... Should that memory be in GPU ?



neoideo
10-20-2009, 01:18 PM
Im using VBO and Index Arrays to map the faces to the vertexes,
its working ok, but after checking memory usage and a little debugging, i see that VBO data goes to GPU while the Index Array does not. im assuming this because is see the memory increase exactly at the instruction:


glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*numCaras*3 , indexBufferTriangles, GL_DYNAMIC_DRAW);


do you guys have idea why this is happening?

DmitryM
10-20-2009, 01:27 PM
glBufferData is the analog of 'malloc' on GPU.
You are specifying the new size of a buffer and possibly it's data.
So don't be surprised by it's video memory allocation ;)

Alfonse Reinheart
10-20-2009, 01:28 PM
Did you bind the buffer to GL_ELEMENT_ARRAY_BUFFER before trying to do indexed rendering?

neoideo
10-20-2009, 01:53 PM
this is the function:


void SimpleGLScene::createVBO(Vertex* verts, GLuint* indexBufferTriangles, unsigned int numVertexes, unsigned int numCaras){

unsigned int size = numVertexes * sizeof(Vertex);
if (&vbo) {
//VBO
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, size, verts);

//Element Array
glGenBuffers(1, &vboIndexId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndexId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*numCaras*3 , 0, GL_DYNAMIC_DRAW);

//free memory RAM
free(verts);
free(indexBuferTriangles);

}


}


when i check the memory usage of the Process, it does not increase when creating the VBO. and when i free the verts array my RAM memory returns back This is what i want :)

but when creating the Element Array my RAM usage increases and stays there after calling free to the indexes array..this is what i dont want :(
i dont think that Ubuntu would show my GPU memory used does it? so i should see my memory usage come back to a low number as with the VBO situation.

Alfonse Reinheart
10-20-2009, 01:57 PM
but when creating the Element Array my RAM usage increases, it should be GPU Memory but i dont think that Ubuntu would show my GPU memory used does it? so i should see my memory usage come back to a low number.

Ignore this. Everything that's happening is fine.

See, OpenGL implementations are allowed to make assumptions about the usage of a buffer object based on how you first bound that buffer object. So when you bound your buffer as "GL_ELEMENT_ARRAY_BUFFER", that means the implementation can assume that index data will go here.

Because of this, the implementation can allocate the memory from different locations. For example, older NVIDIA cards had a hangup of some kind about using GPU memory for index data. Current ones still might; I don't know. So if you create an "GL_ELEMENT_ARRAY_BUFFER", the implementation will make the assumption that you intend for this to be used for index data. The NVIDIA implementations that couldn't use GPU memory for index data would simply allocate those buffers on the CPU.

neoideo
10-20-2009, 02:09 PM
but when creating the Element Array my RAM usage increases, it should be GPU Memory but i dont think that Ubuntu would show my GPU memory used does it? so i should see my memory usage come back to a low number.

Ignore this. Everything that's happening is fine.

See, OpenGL implementations are allowed to make assumptions about the usage of a buffer object based on how you first bound that buffer object. So when you bound your buffer as "GL_ELEMENT_ARRAY_BUFFER", that means the implementation can assume that index data will go here.

Because of this, the implementation can allocate the memory from different locations. For example, older NVIDIA cards had a hangup of some kind about using GPU memory for index data. Current ones still might; I don't know. So if you create an "GL_ELEMENT_ARRAY_BUFFER", the implementation will make the assumption that you intend for this to be used for index data. The NVIDIA implementations that couldn't use GPU memory for index data would simply allocate those buffers on the CPU.

thank you for sharing the explanation.
ill keep the code as it is then :)

Dark Photon
10-20-2009, 06:47 PM
this is the function:


void SimpleGLScene::createVBO(Vertex* verts, GLuint* indexBufferTriangles, unsigned int numVertexes, unsigned int numCaras){

unsigned int size = numVertexes * sizeof(Vertex);
if (&vbo) {
//VBO
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
...
This looks fishy and may very well be the cause of your performance problem.

Assuming vbo is a GLuint, &vbo is always true. Therefore, every time you call this function, you're always generating a new buffer handle and allocating a new GL buffer. The no-op if-check suggests the logic may not be as you'd intended.

Right after your glGenBuffers() call above, try dropping a printf of the vbo handle in there. Ditto with glDeleteBuffers() right before it. You may be surprised.

neoideo
10-20-2009, 10:30 PM
i checked as you suggested, loading lots of 3D models in the same aplication instance.

i got:
BEFORE glGenBuffers() ..... vbo = 0
BEFORE glDeleteBuffers() .. vbo = 1

at least is what i imagined, nothing wrong i guess.

but i took your advice anyways and changed that "if" statement to "if(vbo==0)".

edit: i found a way to by-pass those MBytes that OpenGL mallocs on my RAM by default when creating the Element_Array. im loading the data of the Index Array using a simple CUDA kernel and when chossing big Meshes of 170MB of size, my RAM usage dropped from 70-80MB (which was for the index element_array) to 15-16MB, good!. its even better because on even bigger meshes i will still be using only that little RAM memory. the only restriction is of course GPU Video-Memory but im not sure if the chipset driver will take care of that using virtual memory, im not sure i dont think at least using CUDA which is realtime oriented.

i didnt post the cuda solution since this is OpenGL forum but if you guys want it just post here asking for it :)

Alfonse Reinheart
10-21-2009, 12:46 AM
If the OpenGL driver thought it was a good idea to allocate index buffers in system memory, then it probably was a good idea. The whole point of this kind of abstraction is to let the implementation do the best job that it can at optimizing things. Doing an end-run around its ideas with CUDA runs totally against this.