bool GLTransferBuffers::createBuffers(unsigned int uiNumBuffers, unsigned int uiBufferSize, unsigned int uiTarget, bool bUseP2P, AlignedMem *pPinnedMem )
{
    // Check if buffers were already allocated. If so delete them
    for (unsigned int i = 0; i < m_uiNumBuffers && m_pBufferMemory; i++)
    {
        if (m_pBufferMemory[i].pBasePointer)
            delete [] m_pBufferMemory[i].pBasePointer;

        glDeleteBuffers(1, &m_pBuffer[i]);
    }

    if (uiTarget != GL_PIXEL_PACK_BUFFER && uiTarget != GL_PIXEL_UNPACK_BUFFER)
        return false;

    m_pBufferMemory = NULL;

    m_uiNumBuffers = uiNumBuffers;
    m_uiBufferSize = uiBufferSize;  

    m_uiTarget = uiTarget;

    m_bUseP2P = bUseP2P;

    // Generate GL Buffers
    m_pBuffer = new unsigned int[m_uiNumBuffers];
    glGenBuffers(m_uiNumBuffers, m_pBuffer);

    GLenum nUsage = m_uiTarget == GL_PIXEL_PACK_BUFFER ? GL_DYNAMIC_READ : GL_DYNAMIC_DRAW;

    if (m_bUseP2P)
    {
        /////////////////////////////////////////////
        // Create bus addressable memory buffers
		
        m_pBufferBusAddress = new GLuint64[m_uiNumBuffers];
        m_pMarkerBusAddress = new GLuint64[m_uiNumBuffers];

        if (uiTarget == GL_PIXEL_UNPACK_BUFFER)
        {
            glGetError();

            // In the case of an unpack buffer, the memory is allocated on the
            // GPU visible framebuffer. 
            // In case of a pack buffer, memory is allocated on visible sdi
            // framebuffer, this needs to be done in the sdi thread and not here!
            // In this case only the buffer is generated and memory addressed will
            // be passed later.
            for (unsigned int i = 0; i < m_uiNumBuffers; i++)
            {
                glBindBuffer(GL_BUS_ADDRESSABLE_MEMORY_AMD, m_pBuffer[i]);
                glBufferData(GL_BUS_ADDRESSABLE_MEMORY_AMD, m_uiBufferSize, 0, nUsage);
            }

            // Call makeResident when all BufferData calls were submitted.
            glMakeBuffersResidentAMD(m_uiNumBuffers, m_pBuffer, m_pBufferBusAddress, m_pMarkerBusAddress);

            // Make sure that the buffer creation really succeed
            if (glGetError() != GL_NO_ERROR)
                return false;

            glBindBuffer(GL_BUS_ADDRESSABLE_MEMORY_AMD, 0);
        }
    }
    else
    {
        /////////////////////////////////////////////
        // Create pinned memory buffers
        /////////////////////////////////////////////
        if (!pPinnedMem)
        {
            m_pBufferMemory = new AlignedMem[m_uiNumBuffers];
            memset(m_pBufferMemory, 0, m_uiNumBuffers * sizeof(AlignedMem));

            // indicate that pinned mem was allocated and needs to be deleted.
            m_bAllocatedPinnedMem = true;
        }
        else
        {
            m_pBufferMemory = pPinnedMem;
        }

        for (unsigned int i = 0; i < m_uiNumBuffers; i++)
        {
            if (!m_pBufferMemory[i].pBasePointer)
            {
                m_pBufferMemory[i].pBasePointer = new char[m_uiBufferSize + 4096];
                memset(m_pBufferMemory[i].pBasePointer, 0, (m_uiBufferSize + 4096));

                // Align memory to 4K boundaries
                size_t addr = (size_t) m_pBufferMemory[i].pBasePointer;
                m_pBufferMemory[i].pAlignedPointer = (char*)((addr + 4095) & (~0xfff));
            }

            glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_AMD, m_pBuffer[i]);
            glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_AMD, m_uiBufferSize, m_pBufferMemory[i].pAlignedPointer, nUsage);
            glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_AMD, 0);
        }
    }

    m_bBufferReady = true;

    return true;
}
Example #2
0
bool GLSink::createDownStream(unsigned int w, unsigned int h, int nIntFormat, int nExtFormat, int nType)
{
    m_uiTextureWidth  = w;
    m_uiTextureHeight = h;

    m_nIntFormat = nIntFormat;
    m_nExtFormat = nExtFormat;
    m_nType      = nType;

    m_fAspectRatio = (float)w/(float)h;

    m_uiBufferSize = FormatInfo::getInternalFormatSize(m_nIntFormat) * m_uiTextureWidth * m_uiTextureHeight;

    if (m_uiBufferSize == 0)
        return false;

    // check if format is supported
    if (FormatInfo::getExternalFormatSize(m_nExtFormat, m_nType) == 0)
        return false;

    glBindBuffer(GL_BUS_ADDRESSABLE_MEMORY_AMD, 0);

    // Create texture that will be used to store frames from remote device
    glGenTextures(1, &m_uiTexture);

    glBindTexture(GL_TEXTURE_2D, m_uiTexture);

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

    glTexImage2D(GL_TEXTURE_2D, 0, m_nIntFormat, m_uiTextureWidth, m_uiTextureHeight, 0, m_nExtFormat, m_nType, NULL);

    glBindTexture(GL_TEXTURE_2D, 0);

    m_uiTextureSize = m_uiTextureWidth*m_uiTextureHeight*FormatInfo::getExternalFormatSize(m_nExtFormat, m_nType);


    m_pUnPackBuffer     = new unsigned int[NUM_BUFFERS];
    m_pBufferBusAddress = new unsigned long long[NUM_BUFFERS];
    m_pMarkerBusAddress = new unsigned long long[NUM_BUFFERS];

    glGenBuffers(NUM_BUFFERS, m_pUnPackBuffer);

    // Create buffers
    for (unsigned int i = 0; i < NUM_BUFFERS; i++)
    {
        glBindBuffer(GL_BUS_ADDRESSABLE_MEMORY_AMD, m_pUnPackBuffer[i]);
        glBufferData(GL_BUS_ADDRESSABLE_MEMORY_AMD, m_uiBufferSize, 0, GL_DYNAMIC_DRAW);
    }

    // Call makeResident when all BufferData calls were submitted. This call will make the
    // buffers resident in local visible memory.
    glMakeBuffersResidentAMD(NUM_BUFFERS, m_pUnPackBuffer, m_pBufferBusAddress, m_pMarkerBusAddress);
    
    // Create synchronization buffers
    m_pInputBuffer = new SyncedBuffer;

    m_pInputBuffer->createSyncedBuffer(NUM_BUFFERS);

    for (unsigned int i = 0; i < NUM_BUFFERS; i++)
    {
        FrameData* pFrameData = new FrameData;

        pFrameData->uiTransferId        = 0;
        pFrameData->ullBufferBusAddress = m_pBufferBusAddress[i];
        pFrameData->ullMarkerBusAddress = m_pMarkerBusAddress[i];

        m_pInputBuffer->setBufferMemory(i, (void*)pFrameData);
    }

    return true;
}