분실 디바이스(Direct3D 9)

Direct3D 디바이스는 작동 상태이거나 손실 상태일 수 있습니다. 작동 상태는 디바이스가 실행되고 모든 렌더링이 예상대로 표시되는 디바이스의 정상 상태입니다. 전체 화면 애플리케이션에서 키보드 포커스를 잃어 렌더링이 불가능할 경우, 디바이스는 손실 상태로 전환됩니다. 손실 상태의 특징은 모든 렌더링 작업의 자동 실패입니다. 즉, 렌더링 작업이 실패하더라도 렌더링 메서드가 성공 코드를 반환할 수 있습니다. 이 경우 D3DERR_DEVICELOST 오류 코드는 IDirect3DDevice9::P resent에서 반환됩니다.

설계상 디바이스 손실을 일으킬 가능성이 있는 전체 시나리오 집합은 지정되지 않았습니다. 사용자가 ALT+TAB을 누르거나 시스템 대화 상자가 초기화된 경우 등 포커스를 잃어버리는 경우가 대표적인 예입니다. 전원 관리 이벤트가 발생하거나 다른 애플리케이션이 전체 화면 작업을 가정할 때도 디바이스가 손실될 수 있습니다. 또한 IDirect3DDevice9::Reset 의 오류로 인해 디바이스가 손실된 상태가 됩니다.

IUnknown에서 파생된 모든 메서드는 디바이스 손실 후에도 작동합니다. 디바이스 손실 후 각 기능에는 일반적으로 다음 세 가지 옵션이 있습니다.

  • D3DERR_DEVICELOST 실패 - 즉, 애플리케이션이 디바이스가 손실되었음을 인식하여 애플리케이션에서 예상대로 문제가 발생하지 않음을 식별해야 합니다.
  • 자동으로 실패하여 S_OK 또는 다른 반환 코드 반환 - 함수가 자동으로 실패하는 경우 애플리케이션은 일반적으로 "성공"과 "자동 실패"의 결과를 구분할 수 없습니다.
  • 함수는 반환 코드를 반환합니다.
Direct3D 9와 Direct3D 9Ex 간의 차이점:
Direct3D 9 디바이스는 D3DERR_DEVICELOST 반환합니다. IDirect3DDevice9::P resent에서 반환되면 에뮬레이션 동작이 더 이상 작동하지 않으며 디바이스가 성공적으로 재설정될 때까지 이후의 모든 호출이 실패합니다.
Direct3D 9Ex 디바이스는 D3DERR_DEVICELOST 반환하지 않지만 새 상태 메시지를 반환할 수 있습니다(디바이스 동작 변경 참조).

 

디바이스 손실에 응답

손실된 디바이스가 재설정된 후 리소스(비디오 메모리 리소스 포함)를 다시 만들어야 합니다. 디바이스가 손실되면 애플리케이션은 디바이스를 작동 상태로 복원할 수 있는지 확인하기 위해 디바이스에 쿼리합니다. 디바이스를 복원할 수 없는 경우 애플리케이션은 디바이스를 복원할 수 있을 때까지 기다립니다.

디바이스를 복원할 수 있는 경우 애플리케이션이 모든 비디오 메모리 리소스와 스왑 체인을 파괴하여 디바이스를 준비시킵니다. 그런 다음, 애플리케이션은 IDirect3DDevice9::Reset 메서드를 호출합니다. 초기화는 디바이스를 분실할 때 영향을 주는 유일한 방법이며 애플리케이션이 디바이스를 분실에서 작동 상태로 변경할 수 있는 유일한 방법입니다. 애플리케이션이 IDirect3DDevice9::CreateRenderTarget 및 IDirect3DDevice9::CreateDepthStencilSurface 메서드에서 만든 리소스를 포함하여 D3DPOOL_DEFAULT 할당된 모든 리소스를 해제하지 않으면 다시 설정이 실패합니다.

대부분의 경우, Direct3D의 고주파수 호출은 디바이스의 손실 여부에 대한 정보를 반환하지 않습니다. 애플리케이션은 손실된 디바이스에 대한 알림을 받지 않고 IDirect3DDevice9::D rawPrimitive와 같은 렌더링 메서드를 계속 호출할 수 있습니다. 내부적으로 이러한 작업은 디바이스가 작동 상태로 재설정될 때까지 삭제됩니다.

애플리케이션은 IDirect3DDevice9::TestCooperativeLevel 메서드의 반환 값을 쿼리하여 손실된 디바이스를 발견할 때 수행할 작업을 결정할 수 있습니다.

잠금 작업

내부적으로 Direct3D는 디바이스 손실 후 잠금 작업이 성공하기에 충분한 작업을 수행합니다. 그러나 잠금 작업 중에 비디오 메모리 리소스의 데이터가 정확하다고 보장하지 않습니다. 오류 코드가 반환되지 않도록 보장합니다. 그러면 잠금 작업 중 디바이스 손실에 대한 우려 없이 애플리케이션을 작성할 수 있습니다.

리소스

리소스는 비디오 메모리를 소모할 수 있습니다. 손실된 디바이스가 어댑터 소유의 비디오 메모리에서 분리되었기 때문에 디바이스 손실 시 비디오 메모리의 할당을 보장할 수 없습니다. 결과적으로 모든 리소스 만들기 메서드는 D3D_OK 반환하여 성공하도록 구현되지만 실제로는 더미 시스템 메모리만 할당합니다. 디바이스 크기를 조정하기 전에 비디오 메모리 리소스를 삭제해야 하기 때문에 비디오 메모리의 과도 할당은 발생하지 않습니다. 이러한 더미 표면을 사용하면 애플리케이션이 IDirect3DDevice9::P resent 를 호출하고 디바이스가 손실되었음을 발견할 때까지 잠금 및 복사 작업이 정상적으로 작동하는 것처럼 보일 수 있습니다.

디바이스를 손실 상태에서 작동 상태로 재설정하기 전에 모든 비디오 메모리를 해제해야 합니다. 즉, 애플리케이션은 IDirect3DDevice9::CreateAdditionalSwapChain 으로 만든 스왑 체인과 D3DPOOL_DEFAULT 메모리 클래스에 배치된 리소스를 해제해야 합니다. 애플리케이션은 D3DPOOL_MANAGED 또는 D3DPOOL_SYSTEMMEM 메모리 클래스에서 리소스를 해제할 필요가 없습니다. 작동 상태로 전환하면서 다른 상태 데이터는 자동으로 삭제됩니다.

디바이스 손실에 응답하기 위해 단일 코드 경로로 애플리케이션을 개발하는 것이 좋습니다. 이 코드 경로는 시작 시 디바이스를 초기화하는 데 사용된 코드 경로와 동일하거나 비슷할 가능성이 높습니다.

검색된 데이터

Direct3D를 사용하면 애플리케이션이 IDirect3DDevice9::ValidateDevice를 사용하여 하드웨어에서 단일 패스 렌더링에 대해 텍스처의 유효성을 검사하고 상태를 렌더링할 수 있습니다. 일반적으로 애플리케이션을 초기화하는 동안 호출되는 이 메서드는 디바이스가 손실된 경우 D3DERR_DEVICELOST 반환합니다.

Direct3D를 통해 애플리케이션은 생성했거나 이전에 작성한 이미지를 비디오 메모리 리소스에서 비휘발성 시스템 메모리 리소스로 복사할 수도 있습니다. 이러한 전달의 소스 이미지는 언제든 손실될 수 있기 때문에, Direct3D는 디바이스 손실 시 이러한 복사 작업이 실패하도록 합니다.

비동기 쿼리와 관련하여 IDirect3DQuery9::GetData 는 FLUSH 플래그가 지정된 경우 IDirect3DQuery9::GetData 가 S_OK 반환하지 않는다는 것을 애플리케이션에 나타내기 위해 D3DERR_DEVICELOST 반환합니다.

디바이스가 손실된 경우 기본 표면이 없으므로 복사 작업 인 IDirect3DDevice9::GetFrontBufferData는 D3DERR_DEVICELOST 실패할 수 있습니다. IDirect3DDevice9::CreateAdditionalSwapChain 은 디바이스가 손실될 때 백 버퍼를 만들 수 없으므로 D3DERR_DEVICELOST 함께 실패할 수도 있습니다. 이러한 경우는 IDirect3DDevice9::P resent, IDirect3DDevice9::TestCooperativeLevel 및 IDirect3DDevice9::Reset 메서드 외부에서 D3DERR_DEVICELOST 유일한 instance.

프로그래밍 가능한 셰이더

Direct3D 9에서는 꼭짓점 셰이더 및 픽셀 셰이더를 다시 만든 후 다시 만들 필요가 없습니다. 그들은 기억될 것입니다. 이전 버전의 DirectX에서는 분실한 디바이스에서 셰이더를 다시 만들어야 했습니다.

Direct3D 디바이스