분실된 디바이스(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 플러시 플래그가 지정된 경우 D3DERR_DEVICELOST 반환하여 IDirect3DQuery9::GetData S_OK 반환하지 않는다는 것을 애플리케이션에 나타냅니다.
IDirect3DDevice9::GetFrontBufferData복사 작업은 디바이스가 손실될 때 기본 표면이 없으므로 D3DERR_DEVICELOST 실패할 수 있습니다. IDirect3DDevice9::CreateAdditionalSwapChain 디바이스가 손실될 때 백 버퍼를 만들 수 없으므로 D3DERR_DEVICELOST 함께 실패할 수도 있습니다. 이러한 경우는 IDirect3DDevice9::P resent, IDirect3DDevice9::TestCooperativeLevel및 IDirect3DDevice9::Reset 메서드 외부의 유일한 D3DERR_DEVICELOST 인스턴스입니다.
프로그래밍 가능한 셰이더
Direct3D 9에서는 꼭짓점 셰이더 및 픽셀 셰이더를 다시 만든 후 다시 만들 필요가 없습니다. 그들은 기억될 것입니다. 이전 버전의 DirectX에서는 손실된 디바이스에서 셰이더를 다시 만들어야 했습니다.
관련 항목