Windows 8 이상에서 TDR

Windows 8 부터 GPU TDR(시간 제한 검색 및 복구) 동작을 사용하면 어댑터 전체 재설정을 요구하는 대신 개별 물리적 어댑터의 일부를 다시 설정할 수 있습니다.

TDR에 대한 자세한 내용은 TDR(시간 제한 검색 및 복구)을 참조하세요.

요구 사항

  • 최소 WDDM 버전: 1.2
  • 최소 Windows 버전: 8
  • 드라이버 구현 - 전체 그래픽 및 렌더링 전용: 필수
  • WHLK 요구 사항 및 테스트: Device.Graphics... TDRResiliency

TDR DDI(디바이스 드라이버 인터페이스)

이 동작 변경을 수용하려면 미니포트 드라이버를 표시하여 다음 함수를 구현합니다.

디스플레이 미니포트 드라이버는 DXGK_DRIVERCAPS 설정하여 이러한 함수에 대한 지원을 나타냅니다. SupportPerEngineTDR 멤버입니다. 이 경우 위의 모든 함수를 구현해야 합니다.

참고

이러한 함수를 지원하는 드라이버는 DxgkDdiCollectDbgInfo 함수에 대한 수준 0 동기화도 지원해야 합니다. 이는 초기화 작업의 영향을 받지 않는 수준 0 미니포트 호출을 계속할 수 있도록 하기 위한 것입니다. DxgkDdiCollectDbgInfo의 설명을 참조하세요.

다음 구조체는 위의 함수와 연결됩니다.

노드

위의 TDR 함수에 사용된 것처럼 노드 는 독립적으로 예약할 수 있는 단일 물리적 어댑터의 여러 부분 중 하나입니다. 예를 들어 3차원 노드, 비디오 디코딩 노드 및 복사 노드는 모두 동일한 물리적 어댑터에 존재할 수 있으며, 각 노드는 DXGKARG_QUERYDEPENDENTENGINEGROUP 별도의 노드 서수 값을 할당할 수 있습니다. DxgkDdiQueryDependentEngineGroup에 대한 호출의 NodeOrdinal 멤버입니다.

실제 어댑터의 노드 수는 DXGK_DRIVERCAPSNbAsymetricProcessingNodes 멤버의 디스플레이 미니포트 드라이버에 의해 보고됩니다. GpuEngineTopology.

노드 서수 값은 컨텍스트를 만들 때 DXGKARG_CREATECONTEXT 구조체의 NodeOrdinal 멤버에 전달됩니다.

엔진

위의 TDR 함수에 사용된 것처럼 엔진 은 하나의 논리 어댑터 역할을 하는 여러 물리적 어댑터(또는 GPU) 중 하나입니다. DirectX 그래픽 커널 하위 시스템은 이러한 구성을 지원하지만 각 엔진에 동일한 수의 노드가 있어야 합니다.

예를 들어 GPU 스케줄러는 엔진 0을 실제 어댑터 0에 해당하는 것으로 간주합니다. 엔진 0은 어댑터 1에 해당하는 엔진 1과 동일한 수의 노드를 가져야 합니다.

컨텍스트 생성 시 엔진 서수 값

컨텍스트가 만들어지면 엔진 서수 값에 해당하는 단일 비트가 DXGKARG_CREATECONTEXT 구조체의 EngineAffinity 멤버에 설정됩니다. 이 구조체 및 기타 스케줄러 관련 구조의 EngineOrdinal 멤버는 0부터 시작하는 인덱스입니다. EngineAffinity 값은 1 <<EngineOrdinal이고 EngineOrdinalEngineAffinity에서 가장 높은 비트 위치입니다.

엔진 재설정의 영향을 받지 않는 패킷

엔진 다시 설정이 완료되기 전에 엔진 하드웨어 큐에 너무 늦게 제출된 패킷을 완전히 처리하도록 GPU 스케줄러에서 드라이버를 다시 제출하라는 메시지가 표시될 수 있습니다. 드라이버는 이러한 패킷을 다시 제출하려면 다음 지침을 따라야 합니다.

  • 패킷 페이징: 드라이버는 GPU 스케줄러가 원래 펜스 ID로 페이징 패킷을 원래 제출된 순서와 동일한 순서로 다시 제출하도록 요청합니다. 이러한 패킷은 하드웨어 큐에 새 패킷을 추가하기 전에 다시 제출됩니다.
  • 패킷 렌더링: GPU 스케줄러는 렌더링 패킷에 새 펜스 ID를 할당한 다음 다시 제출합니다.

시퀀스를 호출하여 엔진 초기화

DxgkDdiResetEngine이 성공하면 GPU 스케줄러는 엔진 재설정 호출에서 반환된 LastAbortedFenceId 값이 하드웨어 큐의 기존 펜스 ID 또는 GPU에서 마지막으로 완료된 펜스 ID에 해당하도록 합니다. 후자의 상황은 GPU 시간 제한이 검색된 후 엔진 재설정 콜백이 호출되기 전에 하드웨어 큐가 비워지는 경우에 발생할 수 있습니다.

또한 DXGKARGCB_NOTIFY_INTERRUPT_DATA 선점 인터럽트 알림 구조의 DmaPreempted.LastCompletedFenceId 멤버를 설정해야 하므로 GPU에서 마지막으로 완료된 펜스 ID 값은 드라이버에서 항상 유지 관리해야 합니다. 마지막으로 완료된 펜스 ID는 다음과 같은 경우에만 고급으로 지정해야 합니다.

  • 패킷이 완료되면(선점되지 않음) 마지막으로 완료된 펜스 ID를 완료된 패킷의 펜스 ID로 설정해야 합니다.
  • DxgkDdiResetEngine이 성공하면 마지막으로 완료된 펜스 ID를 엔진 재설정 호출에서 반환된 LastCompletedFenceId 멤버의 값으로 설정해야 합니다.
  • 어댑터 전체 재설정의 경우 모든 노드에서 마지막으로 완료된 펜스 ID는 재설정 시 마지막으로 제출된 펜스 ID로 고급화되어야 합니다.

GPU 스케줄러에서 볼 수 있듯이 성공적인 엔진 재설정의 시간 순서는 다음과 같습니다.

  1. 선점 시도가 발생합니다.

  2. GPU 시간 제한이 검색됩니다.

  3. 마지막으로 제출되고 완료된 펜스 ID의 스냅샷 GPU 스케줄러에서 가져와서 시간 제한 엔진의 인터럽트는 무시됩니다. 디바이스 인터럽트 수준에서 하나의 원자성 작업입니다.

  4. 이 시점에서 하드웨어 큐에 패킷이 없으면 종료합니다. 이는 2단계와 3단계 사이의 시간 창에서 패킷이 완료된 경우에 발생할 수 있습니다.

  5. 큐에 대기 중인 모든 DPC가 플러시됩니다.

  6. 엔진 재설정을 준비합니다.

  7. DxgkDdiResetEngine을 호출합니다.

  8. LastAbortedFenceId 멤버가 마지막으로 완료된 펜스 ID보다 작거나 마지막으로 제출된 펜스 ID보다 큰 경우 DirectX 그래픽 커널 하위 시스템에서 시스템 버그 검사가 발생합니다. 크래시 덤프 파일에서 오류는 다음과 같은 네 가지 매개 변수가 있는 BugCheck 0x119 메시지로 표시됩니다.

    • 0xA 드라이버가 잘못된 중단된 펜스 ID를 보고했음을 의미합니다.
    • 드라이버에서 반환한 LastAbortedFenceId
    • 마지막으로 완료된 펜스 ID
    • 내부 운영 체제 매개 변수
  9. LastAbortedFenceId 값이 유효한 경우 다음과 같이 엔진 재설정 복구를 진행합니다. 페이징 패킷이 엔진 재설정의 영향을 받은 경우 GPU 스케줄러는 어댑터 전체 재설정을 사용하여 엔진 재설정을 따릅니다. 해당 페이징 패킷에서 참조하는 할당을 소유한 모든 디바이스도 오류 상태에 배치됩니다. 그러나 시스템 디바이스 자체는 오류 상태로 전환되지 않으며 다시 설정이 완료된 후 실행을 다시 시작합니다.

특수 사례

위에서 설명한 3단계와 7단계 사이에 GPU에서 패킷이 완료되면 특별한 상황이 발생할 수 있습니다. 이 경우 드라이버의 관점에서 하드웨어 큐에 패킷이 없는 경우 드라이버에서 LastAbortedFenceId 를 마지막으로 완료된 패킷의 펜스 ID로 설정해야 합니다. 스케줄러의 관점에서 볼 때 이러한 패킷이 중단된 것으로 나타나고 패킷이 결국 완료되더라도 해당 디바이스가 오류 상태로 전환됩니다.

하드웨어가 잘못된 상태이거나 하드웨어가 노드를 다시 설정할 수 없으므로 드라이버가 다시 설정 작업을 수행할 수 없는 경우 드라이버는 오류 상태 코드를 반환해야 합니다. GPU 스케줄러가 코드에 상태 오류를 수신하는 경우 Windows 8 전에 TDR 동작에 따라 어댑터 전체 재설정 및 다시 시작 작업을 수행합니다.

드라이버가 Windows 8 이상 TDR 동작을 옵트인한 경우에도 GPU 스케줄러가 전체 논리 어댑터의 초기화 및 다시 시작을 요청하는 경우가 있습니다. 따라서 드라이버는 여전히 DxgkDdiResetFromTimeoutDxgkDdiRestartFromTimeout 함수를 구현해야 하며 해당 의미 체계는 Windows 8 이전과 동일하게 유지됩니다. DxgkDdiResetEngine을 사용하여 물리적 어댑터를 다시 설정하려고 하면 논리 어댑터가 다시 설정되면 Windows 디버거의 !analyze 명령은 TDR 복구 컨텍스트의 TdrReason 값이 TdrEngineTimeoutPromotedToAdapterReset = 9의 새 값으로 설정되었음을 보여 줍니다.