[DX9] GPU 메모리의 사용 : GPU <--> CPU

GPU는 기본적으로 제한적인 메모리 access를 제공한다. 특히 메인 시스템에 독립적으로 구성된 그래픽스 하드웨어는 이를 사용하기 위한 API를 COM 구조로 제공하게 하고 있으며 이 '다른' 하드웨어 상의 리소스 사용에 심대한 제약을 준다. 이 리소스 사용에는 다양한 경우가 있을 수 있는데 이것은 다음과 같다.

1. GPU 내의 메모리 간 데이터 이동
2. GPU --> CPU 메모리로의 데이터 이동
3. CPU --> GPU 메모리로의 데이터 이동
4. 서로 다른 GPU에 대한 데이터 이동


현재 DX9 API 에서는 1번의 task 조차 복잡한 과정을 거치게 하고 있다. 서로 다른 리소스 pool로 정의된 같은 GPU 내의 리소스  간 이동에 대해서도 DX API는 내부적으로 Surface를 통해 (즉 Display memory interface) 가능하도록 하고 있다. 또한 2번 task의 경우 이를 위한 리소스풀로 지정된 GPU 리소스인 texture를 통해서만 가능하도록 제한되어 있다.

따라서 2번을 수행하기 위해선 해당 GPU 메모리에 저장된 Texture를 Display 메모리의 Surface로 연결 시키고, 이것을 D3DPOOL_SYSTEMMEM으로 지정된 GPU메모리의 Texture와 연결된 VGA 메모리의 Surface과 GetRenderTargetData 메소드를 이용하여 연결시킨다. 그리고 이 System_pool로 지정된 Surface에 Lock을 걸어 CPU (Main) System 메모리의 원하는 포인터로 데이터를 복사한다.

다음 코드는 GPU 메모리에 저장된 데이터를 옮기는 코드이다.

LPDIRECT3DSURFACE9 pSurfRenderTargetSysMem = NULL;
LPDIRECT3DSURFACE9 pSurfRenderTarget = NULL;
IDirect3DTexture9* pTex2DRenderTargetSysMem = NULL;


if(FAILED(m_pD3DDevice->CreateTexture(m_strDataInfo.iReconCubeSizeX, m_strDataInfo.iReconCubeSizeY, 1, 0,
           D3DFMT_A16B16G16R16F, D3DPOOL_SYSTEMMEM, &pTex2DRenderTargetSysMem, NULL)
))
      return FALSE;
pTex2DRenderTargetSysMem->GetSurfaceLevel(0, &pSurfRenderTargetSysMem);

D3DLOCKED_RECT LockedRect;


for(i = 0; i < m_iNumRTSlices; i++){
      m_ppTex2DRenderTargetArray[i]->GetSurfaceLevel(0, &pSurfRenderTarget);
      m_pD3DDevice->GetRenderTargetData(pSurfRenderTarget, pSurfRenderTargetSysMem); //고쳐야함!!!!

      pTex2DRenderTargetSysMem->LockRect(0, &LockedRect, NULL, D3DLOCK_READONLY);

      BYTE* pSlice = (BYTE*)LockedRect.pBits;
//  for(j = 0; j < m_strDataInfo.iReconCubeSizeY; j++){
//   memcpy(&m_ppResultImg[i][m_strDataInfo.iReconCubeSizeX*4*j], pSlice, sizeof(SHORT)
//                    *m_strDataInfo.iReconCubeSizeX*4/*ABGR*/);
//   pSlice = pSlice + LockedRect.Pitch;
//  }    // Pitch 단위로 복사
      memcpy(m_ppResultImg[i], pSlice, sizeof(SHORT)*m_strDataInfo.iReconCubeSizeX*
                        m_strDataInfo.iReconCubeSizeY*4);
// *4 means ABGR (4 channel)

      pTex2DRenderTargetSysMem->UnlockRect(0);
      SendMessage(m_hWndProcDlg, PBM_SETPOS, (FLOAT)i/m_iNumRTSlices*90 + 5, 0);
}

SAFE_RELEASE(pSurfRenderTarget);
SAFE_RELEASE(pSurfRenderTargetSysMem);
SAFE_RELEASE(pTex2DRenderTargetSysMem);

 
이상이다.

3번의 경우 일반적인 lock 메카니즘을 통해 리소스에 데이터를 등록하면 되고 4번의 경우 2, 3번을 통해 구현할 수 있다.

by dojo | 2007/07/02 18:47 | Programmings | 트랙백 | 덧글(0)

트랙백 주소 : http://dojo.egloos.com/tb/1309577
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶