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 |