cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

sarbrita
Journeyman III

ATI Pinned memory extension crash

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);

   

}

0 Likes
7 Replies
gsellers
Staff

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

0 Likes

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?

0 Likes

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

0 Likes

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.

0 Likes

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

0 Likes

Thanks a ton Graham..it actually helped me and i am able to achieve fast data transfer rate.

0 Likes
sarbrita
Journeyman III

Thanks Graham..I will give it a shot.

0 Likes