none
Get contents of render target into CPU readable memory

    Domanda

  • I'm struggling to get the contents of my framebuffer into memory for use by the CPU. Has anyone else managed to do this?

    Here is my code so far - every call succeeds etc. but the final result is a black + zero alpha texture, which makes me believe I am doing something very wrong.

     ID3D11Texture2D* pSurface;
     HRESULT hr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &pSurface ) );
     if( pSurface )
     {
      const int width = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f);
      const int height = static_cast<int>(m_window->Bounds.Height * m_dpi / 96.0f);
      unsigned int size = width * height;
      if( m_captureData )
      {
       freeFramebufferData( m_captureData );
      }
      m_captureData = new unsigned char[ width * height * 4 ];

      ID3D11Texture2D* pNewTexture = NULL;

      D3D11_TEXTURE2D_DESC description =
      {
       width, height, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
       { 1, 0 }, // DXGI_SAMPLE_DESC
       D3D11_USAGE_STAGING,
       0, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, 0
      };

      HRESULT hr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture );
      if( pNewTexture )
      {
       m_d3dContext->CopyResource( pNewTexture, pSurface );
       D3D11_MAPPED_SUBRESOURCE resource;
       unsigned int subresource = D3D11CalcSubresource( 0, 0, 0 );
       HRESULT hr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );
       //resource.pData; // TEXTURE DATA IS HERE

       const int pitch = width << 2;
       const unsigned char* source = static_cast< const unsigned char* >( resource.pData );
       unsigned char* dest = m_captureData;
       for( int i = 0; i < height; ++i )
       {
        memcpy( dest, source, width * 4 );
        source += pitch;
        dest += pitch;
       }

       m_captureSize = size;
       m_captureWidth = width;
       m_captureHeight = height;

       return;
      }
          
      freeFramebufferData( m_captureData );
     }

    mercoledì 16 maggio 2012 17:59

Risposte

  • Fixed with the following:

    ID3D11Texture2D* pSurface;

    HRESULThr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), reinterpret_cast< void** >( &pSurface ) );

    if( pSurface )

    {

    constintwidth = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f);

    constintheight = static_cast<int>(m_window->Bounds.Height * m_dpi / 96.0f);

    unsignedintsize = width * height;

    if( m_captureData )

    {

    freeFramebufferData( m_captureData );

    }

    m_captureData =

    newunsignedchar[ width * height * 4 ];

    ID3D11Texture2D* pNewTexture = NULL;

    D3D11_TEXTURE2D_DESCdescription;

    pSurface->GetDesc( &description );

    description.BindFlags = 0;

    description.CPUAccessFlags =

    D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE;

    description.Usage =

    D3D11_USAGE_STAGING;

    HRESULThr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture );

    if( pNewTexture )

    {

    m_d3dContext->CopyResource( pNewTexture, pSurface );

    D3D11_MAPPED_SUBRESOURCEresource;

    unsignedintsubresource = D3D11CalcSubresource( 0, 0, 0 );

    HRESULThr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );

    //resource.pData; // TEXTURE DATA IS HERE


    constintpitch = width << 2;

    constunsignedchar* source = static_cast< constunsignedchar* >( resource.pData );

    unsignedchar* dest = m_captureData;

    for( inti = 0; i < height; ++i )

    {

    memcpy( dest, source, width * 4 );

    source += pitch;

    dest += pitch;

    }

    m_captureSize = size;

    m_captureWidth = width;

    m_captureHeight = height;

    return;

    }

          

    freeFramebufferData( m_captureData );

    }

    • Contrassegnato come risposta Semi Essessi mercoledì 16 maggio 2012 18:05
    mercoledì 16 maggio 2012 18:05

Tutte le risposte

  • Fixed with the following:

    ID3D11Texture2D* pSurface;

    HRESULThr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), reinterpret_cast< void** >( &pSurface ) );

    if( pSurface )

    {

    constintwidth = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f);

    constintheight = static_cast<int>(m_window->Bounds.Height * m_dpi / 96.0f);

    unsignedintsize = width * height;

    if( m_captureData )

    {

    freeFramebufferData( m_captureData );

    }

    m_captureData =

    newunsignedchar[ width * height * 4 ];

    ID3D11Texture2D* pNewTexture = NULL;

    D3D11_TEXTURE2D_DESCdescription;

    pSurface->GetDesc( &description );

    description.BindFlags = 0;

    description.CPUAccessFlags =

    D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE;

    description.Usage =

    D3D11_USAGE_STAGING;

    HRESULThr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture );

    if( pNewTexture )

    {

    m_d3dContext->CopyResource( pNewTexture, pSurface );

    D3D11_MAPPED_SUBRESOURCEresource;

    unsignedintsubresource = D3D11CalcSubresource( 0, 0, 0 );

    HRESULThr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );

    //resource.pData; // TEXTURE DATA IS HERE


    constintpitch = width << 2;

    constunsignedchar* source = static_cast< constunsignedchar* >( resource.pData );

    unsignedchar* dest = m_captureData;

    for( inti = 0; i < height; ++i )

    {

    memcpy( dest, source, width * 4 );

    source += pitch;

    dest += pitch;

    }

    m_captureSize = size;

    m_captureWidth = width;

    m_captureHeight = height;

    return;

    }

          

    freeFramebufferData( m_captureData );

    }

    • Contrassegnato come risposta Semi Essessi mercoledì 16 maggio 2012 18:05
    mercoledì 16 maggio 2012 18:05
  •  

    Thanks for sharing the solution.

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    giovedì 17 maggio 2012 07:21