Hi,
I am trying to use ATI's pinned memory extension to transfer data fast from GPU to CPU but I am getting crash while reading pixels.
Here is my code.
void getPixelDataFromATIGPU()
{
int dataDize = width * height * 4;
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_pinnedMemBuffer);
/* Getting crash here in glReadPixels */
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
GLsync s = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if(glIsSync(s))
{
glClientWaitSync(s, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 1000);
// Use memory here
}
// It is now safe to use 'memory'
}
/*****************************************************************************/
void initPinnedMemoryBuffer()
{
int dataDize = width * height * 4;
glGenBuffers(1, &m_pinnedMemBuffer);
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_pinnedMemBuffer);
char* memory_temp = new char[dataDize + 0x1000];
m_pinnedMemory = reinterpret_cast<char*>(unsigned(memory_temp + 0xfff) & (~0xfff));
glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, dataDize, m_pinnedMemory, GL_STREAM_READ);
}
Hi,
Once you have created the external memory buffer, you need to bind it to the GL_PIXEL_PACK_BUFFER target. Change these lines in getPixelDataFromATIGPU() from:
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_pinnedMemBuffer);
to
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pinnedMemBuffer);
Then your sample should work.
Thanks,
Graham
It definitely is not crashing but I still need to compare the data. Another followup question: I can now use the binded buffer to copy pixels from right? I can just use following code every frame:
char data[size];
memcpy(data, m_memory, size);
In other words..i will get pixel data of every frame in the binded memory buffer. I dont have to rebind new buffer every time?
Hi,
Yes, you can read from the pinned memory buffer and operate on the data.
I'm not sure what you mean by not having to bind. The buffer object must be bound to the GL_PIXEL_PACK_BUFFER target at the time you call glReadPixels. However, there is no reason to create a new buffer object each frame or to call glBufferData again for that buffer object.
Thanks,
Graham
What i meant was that I have to bind memory buffer once and every time a new frame is generated and I call getPixelDataFromATIGPU(), i will get updated pixel buffer in the same memory location.
You do not need to bind the buffer to the GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD target again once it has been initialized. It must be bound to the GL_PIXEL_PACK_ BUFFER target when glReadPixels is called in order to write to your application's memory. However, if you do not unbind it and never bind another buffer in its place, even this bind may be eliminated and the data will still be written to your application's memory.
Hope this helps.
Graham
Thanks a ton Graham..it actually helped me and i am able to achieve fast data transfer rate.
Thanks Graham..I will give it a shot.