[펌] 디바이스 소실시 텍스쳐 관리

이번장의 글은 gpgstudy의 seeper님의 답변글과 블로그의 참고 글입니다.

질문:

저는 D3DPOOL_DEFAULT를 어떻게 관리 할줄 몰라서 최대한 D3DPOOL_MANAGED로 해서 사용합니다. default로 잘 관리하면 Managed보다 더 좋으면 당연 default로 사용해야겠죠.
그 좋은 방법을 듣고 싶어요.

답변:

프레임워크에서
CD3DApplication 으로 따지자면
D3DPOOL_DEFAULT는 RestoreDeviceObjects() ~ InvalidateDeviceObjects() 에서 관리해줘야합니다. D3DPOOL_MANAGED는 InitDeviceObjects() ~ DeleteDeviceObjects() 에서 관리해줘도 됩니다.

InitDeviceObjects() ~ DeleteDeviceObjects() 는 디바이스가 생성 소멸될때이고
RestoreDeviceObjects() ~ InvalidateDeviceObjects() 는 surface lost 현상이 일어날때 호출됩니다.

DXUT라면 (콜백이라 마음대로 바꿀수있긴 하지만..)
InitDeviceObjects() ~ DeleteDeviceObjects() 는 OnCreateDevice() ~ OnDestroyDevice() 에 해당하고 RestoreDeviceObjects() ~ InvalidateDeviceObjects() 는 OnResetDevice() ~ OnLostDevice() 에 해당합니다.

처음 로드하는곳은 Render()보다는 (begin()~end()가 있으니까..) FrameMove()에서 해주는것이 좋겠지요.

아무래도 D3DPOOL_DEFAULT는 비디오램만 이용하니까 surface lost 현상이 일어날때 잘 매꾸어줘야합니다. 따라서 RestoreDeviceObjects() 에서 이미 로딩된 객체는 복구를 시켜줘야합니다. 반대로 InvalidateDeviceObjects() 에서는 이미 로딩된 객체를 삭제를 해줘야합니다.

D3DPOOL_MANAGED는 백업을 메모리에 갖고 있으므로 surface lost현상이 없습니다.
그냥 FrameMove() 에서 (필요할때) 로드하다가
DeleteDeviceObjects()에서 로딩된 객체들을 제거해주면 됩니다.

이거만 잘 되면 풀화면 <-> 윈도우화면 전환을 막해도 안뻗습니다.

참고하세요. ^^

참고: <seeper님의 참고>

   
CMyD3DApplication에서 다음 함수는 알아야 한다. (이것들은 짝을 이룬다.)

 

1. 무조건 한번씩 호출되는 함수 (이때 m_pd3dDevice는 초기화 되어있지 않음)
OneTimeSceneInit()
FinalCleanup()

 

2. m_pd3dDevice가 초기화 될때 호출되는 함수 (보통은 게임에 한번만 호출)
InitDeviceObjects()
DeleteDeviceObjects()

 

3. surface lost 현상이 일어나면 사라지는 데이터를 로딩할때 호출하는 함수 

(alt-tab이나 resize 등을 할때 호출)
RestoreDeviceObjects()
InvalidateDeviceObjects()

 

1번은 무조건 짝을 이룰 필요는 없다. 허나 상반된 개념이다.

2번은 보통 시작과 종료시 호출된다. (3D 디바이스를 바꾸지 않는다면)

3번은 surface lost는 화면전환등으로 인해 비디오 램에 손실이 가는 현상을 말한다. (다시설명)

 

그래서 결국 실행순서는 (프로그램을 짜야하는 부분만을 따짐)

1) OneTimeSceneInit() (프로그램 초기화시 호출)
2) InitDeviceObjects() (d3d 장치 초기화시 호출)
3) RestoreDeviceObjects() (처음시작하거나 리사이즈, alt-tab 사용시 복귀할때 호출)
4) FrameMove(), Render() (번갈아 가며 막 호출 -> 그림을 그리는데 있어서 중요한 부분)
5) InvalidateDeviceObjects() (리사이즈, alt-tab, 종료시 호출 )
6) DeleteDeviceObjects() (d3d 장치 종료시 호출)
7) FinalCleanup() (프로그램 종료시 호출)

이 된다.

 

화면전환을 4번한다면 보통 아래와 같이 된다.
1)-2)-3)-4)-5)-3)-4)-5)-3)-4)-5)-3)-4)-5)-3)-4)-5)-6)-7)
여기서 보면 5)-3) 으로 이어지는 구간은  전환을 시도하면 서피스 로스트 현상이 일어나
5)가 호출이 되는거고 복구가 되면서 3)이 호출되는 것임.

(alt-tab이건 resize건 간에 포함.. 5)-3) 구간이 4개 있음을 알 수 있다.)

게임이 종료되면 5)가 호출되고 6)이 호출되고 7)이 호출되면서 프로세스가 종료된다.


그러나 텍스쳐의 경우 D3DPOOL_MANAGED로 할 경우 굳이 처리해줄 필요는 없다.

하지만 D3DPOOL_DEFAULT를 이용하면 비디오램만을 이용할것이다.

기본 예제에서는 월드 매트릭스를 이용해 삼각형이 회전하는 것을 보여준다.

[펌]

http://www.gpgstudy.com

http://blog.naver.com/seeper0/120001420552