프로그래밍 2014. 10. 7. 13:25

 

d3d device lost, device reset

dx 디바이스 로스트, dx 디바이스 리셋

 

처리에 관한 간략한 코드입니다.

참고하시길....

 

 

bool g_bDeviceLost = false;

 

//렌더링이 끝난 시점일때

//디바이스의 상태를 받아 저장해 둡니다.

//이때는 디바이스 로스트의 상태만 체크해 두면 됩니다.

//매 프레임 수행됩니다.

HRESULT hr = D3DDevice->Present( NULL, NULL, NULL, NULL );
g_bDeviceLost = (hr == D3DERR_DEVICELOST);

 

 

 

//메인프레임 함수가 있을때

//이렇게 처리됩니다.

void Frame()

{

if( !D3D_DeviceCheck() )

return;

 

//디바이스 상태가 좋을때만 수행

update

render

}

 

//사용자가 화면전환을 시도한다면,

//먼저 devicelost 상태가 발생됩니다.

//그리고 dx화면이 숨겨진 상태거나, 최소화 되어 있는 상태에서는

//계속적으로 devicelost 상태가 발생됩니다.

//devicelost 상태에서는 리소스 해제에 대한 어떠한 작업도 하지 않습니다.

 

 

void (*g_D3DDeviceLostFunc)(void) = NULL;
void (*g_D3DDeviceResetFunc)(void) = NULL;

 

//디바이스체크 함수

//매프레임마다 호출됩니다.

//리턴값이 true 일때만 frame 과 render 등의 작업을 수행해주면 됩니다.

const bool D3D_DeviceCheck()
{
   if( g_bDeviceLost )
   {
      LPDIRECT3DDEVICE9 pDevice = GRAPHIC_DEVICE->GetD3DDevice();
      if( !pDevice )
        return false;

   

     //디바이스 상태를 다시 체크합니다

     HRESULT hr = pDevice->TestCooperativeLevel();
  

      // 디바이스가 소실되었고 아직 복구할 수 없는 상태이다. 복구할 수 있을때까지 대기한다. 

      if( hr == D3DERR_DEVICELOST )

      {
          Sleep( 100 ); // Yield some CPU time to other processes
          return false;
      }

      // 디바이스가 소실되었지만 지금 복구될수 있다.
      else if( hr == D3DERR_DEVICENOTRESET
     {

         //리소스 로스트 처리

       MGR_POLYTILE->DeviceLost();
        QUIMgr::I()->DeviceLost();
        NEffectMgr::I()->DeviceLost();
        stRShader::GetInst()->DeviceLost();
        QModel::RenVerDelete();

        if( g_D3DDeviceLostFunc )
             g_D3DDeviceLostFunc();
  

        //디바이스 리셋
      D3DPRESENT_PARAMETERS Param = *GRAPHIC_DEVICE->GetD3DParam();
      hr = pDevice->Reset( &Param );

       if( FAILED(hr) )
       {
          // reset failed, try again later
          Sleep( 100 );
   
          return false;
       }

  

       //리소스 리셋 처리
       MGR_POLYTILE->DeviceReset();  
       QUIMgr::I()->DeviceReset();
       NEffectMgr::I()->DeviceReset();
       stRShader::GetInst()->DeviceReset();
       QModel::RenVerCreate();

       if( g_D3DDeviceResetFunc )
           g_D3DDeviceResetFunc();

 

       //device reset 과 함께 dx 의 렌더링 상태값들이 초기화되기 때문에,

       //dx 의 렌더링 상태를 저장하는 처리를 하고 있었다면, 이것도 리셋

       //물론 이런 처리를 하고 있었을때만, 처리해 주시면 됩니다.   

       RENDEV->Init();
  
      return true;
   }
   else if( hr == D3DERR_DRIVERINTERNALERROR )
   {
      Sys_Error( "pDevice->Reset D3DERR_DRIVERINTERNALERROR!!" );
      return false;
   } 

 }

 

 //일반적인 상태
 return true;
}

 

 

void (*g_D3DDeviceLostFunc)(void) = NULL;
void (*g_D3DDeviceResetFunc)(void) = NULL;

는 추가적으로 수행되어야 할 작업이 있을때

함수포인터 형식으로 등록해 두시면 됩니다.

 

참고로

D3DPOOL_MANAGED 로 생성된 버퍼들은 아무것도 해주지 않아도 됩니다.

저의 경우는 모든 텍스쳐들은 D3DPOOL_MANAGED 로 생성해 주었기 때문에,

처리가 훅 줄어들었습니다.

 

동적 버텍스 버퍼들과 렌더타겟 텍스쳐는 D3DPOOL_DEFAULT 로 생성하기 때문에,

해제(Release)하고 새로 생성해주어야 합니다.

 

LPD3DXEFFECT 는

내부적으로 OnLostDevice(), OnResetDevice() 를 가지고 있습니다.

폰트와 스프라이트도 OnLostDevice(), OnResetDevice() 를 가지고 있습니다. 

 

 

 

'프로그래밍' 카테고리의 다른 글

셰이더로 구현한 화면 노이즈  (0) 2015.01.23
c++ tick  (0) 2014.11.23
셰이더 왜곡 distortion  (0) 2014.10.02
로그 log  (0) 2014.06.25
범프매핑 노말매핑 법선매핑  (0) 2014.06.10
posted by BK dddDang
: