2017-11-16 49 views
1

여기 코드는 GPU에서 실행되고 Windows 화면을 캡처하여 ID3D11Texture2D 리소스를 제공합니다. ID3D11DeviceContext::Map을 사용하여 GPT resourceBYTE 버퍼에 넣고 BYTE 버퍼에서 CPU 메모리 g_iMageBuffer의 버퍼를 UCHAR으로 가져옵니다.GPU 메모리 (ID3D11Texture2D 리소스)에 CPU 메모리 (UCHAR 버퍼)를 가져 오는 방법

이제 리버스 엔지니어링을하고 싶습니다. g_iMageBuffer 버퍼 (CPU 메모리)를 ID3D11Texture2D (GPU 메모리)에 가져 가고 싶습니다. 제발 누군가가이 역 공학을 수행하는 방법을 도와주세요. 저는 그래픽 부분에 익숙하지 않습니다.

//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); 
+0

끝에있는 "malloc"과 "memcpy"보다 나은 해결책은 얻을 수있는 "std :: unique_ptr <>"'에 할당 된 버퍼를 "이동"하는 것입니다 ''release''라고 부르면됩니다. 물론, 그것은 free 대신에 delete를 사용하여 정리하는 것을 전제로합니다 - 또는 더 나은 방법은''std :: unique_ptr <>''을 사용하는 것입니다. ''free''를 사용해야한다면,''std :: unique_ptr <>''을 초기화하는''malloc''을 사용하십시오 (그리고''free'' 대신에''free''를 사용하는 커스텀 deleter를 제공하십시오) 'delete''). 또한''new''와''malloc'' 다음에 메모리 누수가 있습니다. –

+0

@ChuckWalbourn 나중에 가져 왔습니다 ... 고마워요. – Krish

답변