【问题标题】:How to take CPU memory(UCHAR Buffer) in to GPU memory(ID3D11Texture2D Resource)如何将 CPU 内存(UCHAR 缓冲区)放入 GPU 内存(ID3D11Texture2D 资源)
【发布时间】:2017-11-17 01:05:44
【问题描述】:

这里的代码将在 GPU 中运行并捕获 windows 屏幕,它为我们提供ID3D11Texture2D 资源。使用ID3D11DeviceContext::Map,我将GPU resourceBYTEbuffer 到CPU 内存g_iMageBufferBYTE 缓冲区g_iMageBuffer 它是UCHAR

现在我想做逆向工程,我想把g_iMageBufferbuffer(CPU Memory) 转换成ID3D11Texture2D(GPU memory)。请有人帮我做这个逆向工程我是图形部分的新手。

//Variable Declaration
IDXGIOutputDuplication* IDeskDupl;
IDXGIResource*          lDesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO IFrameInfo;
ID3D11Texture2D*        IAcquiredDesktopImage;
ID3D11Texture2D*        lDestImage;
ID3D11DeviceContext*    lImmediateContext;
UCHAR*                  g_iMageBuffer=nullptr;

//Screen capture start here
hr = lDeskDupl->AcquireNextFrame(20, &lFrameInfo, &lDesktopResource);

// >QueryInterface for ID3D11Texture2D
hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&lAcquiredDesktopImage));
lDesktopResource.Release();

// Copy image into GDI drawing texture
lImmediateContext->CopyResource(lDestImage,lAcquiredDesktopImage);
lAcquiredDesktopImage.Release();
lDeskDupl->ReleaseFrame();  

// Copy GPU Resource to CPU
D3D11_TEXTURE2D_DESC desc;
lDestImage->GetDesc(&desc);
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
lImmediateContext->Map(lDestImage, subresource, D3D11_MAP_READ_WRITE, 0, &resource);

std::unique_ptr<BYTE> pBuf(new BYTE[resource.RowPitch*desc.Height]);
UINT lBmpRowPitch = lOutputDuplDesc.ModeDesc.Width * 4;
BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
BYTE* dptr = pBuf.get() + resource.RowPitch*desc.Height - lBmpRowPitch;
UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch);

for (size_t h = 0; h < lOutputDuplDesc.ModeDesc.Height; ++h)
{
    memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch);
    sptr += resource.RowPitch;
    dptr -= lBmpRowPitch;
}

lImmediateContext->Unmap(lDestImage, subresource);
long g_captureSize=lRowPitch*desc.Height;
g_iMageBuffer= new UCHAR[g_captureSize];
g_iMageBuffer = (UCHAR*)malloc(g_captureSize);

//Copying to UCHAR buffer 
memcpy(g_iMageBuffer,pBuf,g_captureSize);

【问题讨论】:

  • 比最后的mallocmemcpy 更好的解决方案是“移动”分配在std::unique_ptr&lt;&gt; 中的缓冲区,您可以通过调用release 获得。当然,这假设您使用删除而不是免费进行清理——或者更好的是只使用std::unique_ptr&lt;&gt;。如果您必须使用free,那么首先使用malloc 来初始化std::unique_ptr&lt;&gt;(并提供一个使用free 而不是delete 的自定义删除器).. 另请注意,您的new 紧随其后malloc 正在泄漏内存。
  • @ChuckWalbourn 是的,我明白了...谢谢。

标签: gpu directx-11 direct3d


【解决方案1】:

您不需要逆向工程。您所描述的称为“加载纹理”。

How to: Initialize a Texture Programmatically
How to: Initialize a Texture From a File

由于您似乎是 DirectX 编程的新手,请考虑使用 DirectX Tool Kit for DX11 tutorials。特别是,请确保您阅读了有关 ComPtrThrowIfFailed 的部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 2018-06-25
    • 2017-07-27
    • 1970-01-01
    • 2010-10-07
    相关资源
    最近更新 更多