locked
How can I get the bytes from ID3D11Texture2D?

    Question

  • anyone who can help me ...

    Sunday, September 30, 2012 10:06 AM

Answers

  • Raptor K's post is just a snippet of code from the DirectXTex library. There is a full-featured set of texure I/O routines there primarily for use in tools.

    If you are simply trying to save a screenshot or dump out a texture for debugging, you may want to consider using the "ScreenGrab" module code. There is a 'stand-alone' version in the latest DirectxTex package, and there's a version integrated in the lastest DirectXTK library. This code is more suitable to 'runtime' environments such as in a game.

    • Marked as answer by istring Tuesday, October 09, 2012 9:04 AM
    Monday, October 08, 2012 5:49 PM
  • static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ const TexMetadata& metadata,
                             _In_ const ScratchImage& result )
    {
        if ( !pContext || !pSource || !result.GetPixels() )
            return E_POINTER;
    
        if ( metadata.dimension == TEX_DIMENSION_TEXTURE3D )
        {
            //--- Volume texture ----------------------------------------------------------
            assert( metadata.arraySize == 1 );
    
            size_t height = metadata.height;
            size_t depth = metadata.depth;
    
            for( size_t level = 0; level < metadata.mipLevels; ++level )
            {
                UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), 0, static_cast<UINT>( metadata.mipLevels ) );
    
                D3D11_MAPPED_SUBRESOURCE mapped;
                HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
                if ( FAILED(hr) )
                    return hr;
    
                const uint8_t* pslice = reinterpret_cast<const uint8_t*>( mapped.pData );
                if ( !pslice )
                {
                    pContext->Unmap( pSource, dindex );
                    return E_POINTER;
                }
    
                size_t lines = ComputeScanlines( metadata.format, height );
    
                for( size_t slice = 0; slice < depth; ++slice )
                {
                    const Image* img = result.GetImage( level, 0, slice );
                    if ( !img )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_FAIL;
                    }
    
                    if ( !img->pixels )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_POINTER;
                    }
    
                    const uint8_t* sptr = pslice;
                    uint8_t* dptr = img->pixels;
                    for( size_t h = 0; h < lines; ++h )
                    {
                        size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
                        memcpy_s( dptr, img->rowPitch, sptr, msize );
                        sptr += mapped.RowPitch;
                        dptr += img->rowPitch;
                    }
    
                    pslice += mapped.DepthPitch;
                }
    
                pContext->Unmap( pSource, dindex );
    
                if ( height > 1 )
                    height >>= 1;
                if ( depth > 1 )
                    depth >>= 1;
            }
        }
        else
        {
            //--- 1D or 2D texture --------------------------------------------------------
            assert( metadata.depth == 1 );
    
            for( size_t item = 0; item < metadata.arraySize; ++item )
            {
                size_t height = metadata.height;
    
                for( size_t level = 0; level < metadata.mipLevels; ++level )
                {
                    UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), static_cast<UINT>( item ), static_cast<UINT>( metadata.mipLevels ) );
    
                    D3D11_MAPPED_SUBRESOURCE mapped;
                    HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
                    if ( FAILED(hr) )
                        return hr;
    
                    const Image* img = result.GetImage( level, item, 0 );
                    if ( !img )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_FAIL;
                    }
    
                    if ( !img->pixels )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_POINTER;
                    }
    
                    size_t lines = ComputeScanlines( metadata.format, height );
    
                    const uint8_t* sptr = reinterpret_cast<const uint8_t*>( mapped.pData );
                    uint8_t* dptr = img->pixels;
                    for( size_t h = 0; h < lines; ++h )
                    {
                        size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
                        memcpy_s( dptr, img->rowPitch, sptr, msize );
                        sptr += mapped.RowPitch;
                        dptr += img->rowPitch;
                    }
    
                    pContext->Unmap( pSource, dindex );
    
                    if ( height > 1 )
                        height >>= 1;
                }
            }
        }
    
        return S_OK;
    }


    Win8 Developer QQ Group 95331609

    • Marked as answer by istring Monday, October 08, 2012 3:05 AM
    Wednesday, October 03, 2012 8:33 AM

All replies

  • or from a swapchain?
    Monday, October 01, 2012 9:01 AM
  • It really depends on what you are trying to do with those bytes.

    Are you trying to save out a screenshot, or do something else with them?

    Monday, October 01, 2012 9:28 PM
  • static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ const TexMetadata& metadata,
                             _In_ const ScratchImage& result )
    {
        if ( !pContext || !pSource || !result.GetPixels() )
            return E_POINTER;
    
        if ( metadata.dimension == TEX_DIMENSION_TEXTURE3D )
        {
            //--- Volume texture ----------------------------------------------------------
            assert( metadata.arraySize == 1 );
    
            size_t height = metadata.height;
            size_t depth = metadata.depth;
    
            for( size_t level = 0; level < metadata.mipLevels; ++level )
            {
                UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), 0, static_cast<UINT>( metadata.mipLevels ) );
    
                D3D11_MAPPED_SUBRESOURCE mapped;
                HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
                if ( FAILED(hr) )
                    return hr;
    
                const uint8_t* pslice = reinterpret_cast<const uint8_t*>( mapped.pData );
                if ( !pslice )
                {
                    pContext->Unmap( pSource, dindex );
                    return E_POINTER;
                }
    
                size_t lines = ComputeScanlines( metadata.format, height );
    
                for( size_t slice = 0; slice < depth; ++slice )
                {
                    const Image* img = result.GetImage( level, 0, slice );
                    if ( !img )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_FAIL;
                    }
    
                    if ( !img->pixels )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_POINTER;
                    }
    
                    const uint8_t* sptr = pslice;
                    uint8_t* dptr = img->pixels;
                    for( size_t h = 0; h < lines; ++h )
                    {
                        size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
                        memcpy_s( dptr, img->rowPitch, sptr, msize );
                        sptr += mapped.RowPitch;
                        dptr += img->rowPitch;
                    }
    
                    pslice += mapped.DepthPitch;
                }
    
                pContext->Unmap( pSource, dindex );
    
                if ( height > 1 )
                    height >>= 1;
                if ( depth > 1 )
                    depth >>= 1;
            }
        }
        else
        {
            //--- 1D or 2D texture --------------------------------------------------------
            assert( metadata.depth == 1 );
    
            for( size_t item = 0; item < metadata.arraySize; ++item )
            {
                size_t height = metadata.height;
    
                for( size_t level = 0; level < metadata.mipLevels; ++level )
                {
                    UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), static_cast<UINT>( item ), static_cast<UINT>( metadata.mipLevels ) );
    
                    D3D11_MAPPED_SUBRESOURCE mapped;
                    HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
                    if ( FAILED(hr) )
                        return hr;
    
                    const Image* img = result.GetImage( level, item, 0 );
                    if ( !img )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_FAIL;
                    }
    
                    if ( !img->pixels )
                    {
                        pContext->Unmap( pSource, dindex );
                        return E_POINTER;
                    }
    
                    size_t lines = ComputeScanlines( metadata.format, height );
    
                    const uint8_t* sptr = reinterpret_cast<const uint8_t*>( mapped.pData );
                    uint8_t* dptr = img->pixels;
                    for( size_t h = 0; h < lines; ++h )
                    {
                        size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
                        memcpy_s( dptr, img->rowPitch, sptr, msize );
                        sptr += mapped.RowPitch;
                        dptr += img->rowPitch;
                    }
    
                    pContext->Unmap( pSource, dindex );
    
                    if ( height > 1 )
                        height >>= 1;
                }
            }
        }
    
        return S_OK;
    }


    Win8 Developer QQ Group 95331609

    • Marked as answer by istring Monday, October 08, 2012 3:05 AM
    Wednesday, October 03, 2012 8:33 AM
  • just like Gray a image, Gauss fuzzy, or deal something of 2D pixel

    I can only use directx3D ...

    • Edited by istring Monday, October 08, 2012 3:04 AM
    Monday, October 08, 2012 2:58 AM
  • thanks for your response, i will try it.
    Monday, October 08, 2012 3:06 AM
  • Raptor K's post is just a snippet of code from the DirectXTex library. There is a full-featured set of texure I/O routines there primarily for use in tools.

    If you are simply trying to save a screenshot or dump out a texture for debugging, you may want to consider using the "ScreenGrab" module code. There is a 'stand-alone' version in the latest DirectxTex package, and there's a version integrated in the lastest DirectXTK library. This code is more suitable to 'runtime' environments such as in a game.

    • Marked as answer by istring Tuesday, October 09, 2012 9:04 AM
    Monday, October 08, 2012 5:49 PM