다음을 통해 공유


커널 모드 드라이버에서 CPU 이벤트 신호

KMD(커널 모드 드라이버)가 CPU 이벤트에 신호를 전송하여 UMD(사용자 모드 드라이버)에게 무언가에 대해 알려야 하는 경우가 있습니다. 예를 들어:

  • KMD가 해당 개체 중 하나가 잘못된 상태임을 감지하고 UMD에 알려야 하는 경우
  • GPU 디버깅 중에 KMD가 일부 이벤트가 발생했음을 UMD와 통신해야 합니다. GPU용 제어판이 있는 IHV의 경우 KMD에서 CPU 이벤트를 신호로 전송하면 KMD가 제어판 앱에 내부 이벤트에 대해 알릴 수 있습니다.

일반적으로 UMD는 CPU 이벤트를 만들고 이스케이프 프라이빗 데이터의 KMD에 NT 핸들을 전달할 수 있습니다. NT 핸들은 가상 머신 경계를 넘어 사용할 수 없으므로 GPU-PV(GPU 반가상화) 시나리오에서는 이 메서드가 작동하지 않습니다.

Windows 11 버전 21H2(WDDM 3.0)부터 WDDM API는 UMD가 KMD에서 신호를 받을 수 있는 CPU 이벤트 개체를 만들 수 있도록 확장되었습니다. 이 기능은 UMD가 호스트 또는 GPU-PV를 사용하여 가상 머신에서 실행 중일 때 모두 작동합니다.

기능 흐름

동기화 개체는 컨텍스트 큐에 삽입할 수 없습니다. DXGKCB_SIGNALEVENT 사용하여 KMD에서만 신호를 받을 수 있습니다.

CPU 이벤트 동기화 개체를 처리하는 사용자 모드 API

KMD CPU 이벤트 개체 만들기

KMD CPU 이벤트 개체는 다음을 사용하여 D3D12DDICB_CREATESYNCHRONIZATIONOBJECT2 호출하여 GPU 동기화 개체로 만들어집니다.

  • D3DDDI_CPU_NOTIFICATION 형식으로 설정됩니다.

  • 개체 가 KMD로 신호를 받도록 지정하기 위해 SignalByKmd 로 설정된 플래그입니다. 이 플래그는 D3DDDI_SYNCHRONIZATIONOBJECTINFO2 Type 멤버가D3DDDI_CPU_NOTIFICATION 경우에만 설정할 수 있습니다.

SignalByKmd 플래그가 설정되면 DXGKDDI_CREATECPUEVENT 호출되어 KMD CPU 이벤트 개체를 만듭니다. 동기화 개체를 만들 때 디바이스 핸들을 지정해야 합니다.

동기화 개체는 신호 및 대기 API에서 사용할 수 없습니다(D3DKMTSignalSynchronizationObject, D3DKMTWaitForSynchronizatioObject). KMD에서만 신호를 받을 수 있으며 UMD는 해당 CPU 이벤트를 기다릴 수 있습니다.

KMD CPU 이벤트 동기화 개체에 대한 사용량을 정의하는 UMD 이스케이프

알려진 이스케이프가 D3DDDI_DRIVERESCAPETYPE 추가되었습니다. D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE KMD CPU 이벤트 개체의 의도된 사용량을 KMD에 알리는 데 사용됩니다. 알려진 이스케이프는 DXGKARG_ESCAPE::Flags.DriverKnownEscape = 1을 설정하여 정의됩니다. 알려진 이스케이프는 보안 가상 머신에서도 호스트로 전송됩니다.

다음 코드 조각은 사용 예제입니다.

D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE Command = {};
Command.EscapeType = D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE;
Command.hSyncObject = SyncObjectHandle;
Command.Usage[0] = 1;

D3DKMT_ESCAPE Args = {};
Args.hAdapter = AdapterHandle;
Args.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
Args.Flags.DriverKnownEscape = 1;
Args.Flags.NoAdapterSynchronization = 1; // Prevent waking up the device from D3
Args.pPrivateDriverData = &Command;
Args.PrivateDriverDataSize = sizeof(Command);

NTSTATUS Status = D3DKMTEscape(&Args);

Dxgkrnl 은 다음을 사용하여 DXGKDDI_ESCAPE 호출합니다.

  • hDevice 는 동기화 개체를 만드는 데 사용된 미니포트 디바이스 핸들로 설정됩니다.
  • D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE 구조를 가리키는 pPrivateDriverData
  • PrivateDriverDataSize 가 로 설정됨 sizeof(D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE)

KMD CPU 이벤트 개체 만들기 및 삭제

다음 DDI는 KMD CPU 이벤트 동기화 개체를 만들고 삭제하는 데 사용됩니다.

KMD에서 CPU 이벤트 개체 신호

CPU 이벤트 개체에 신호를 표시하기 위해 KMD는 IRQL<= DISPATCH_LEVEL 및 DXGKARGCB_SIGNALEVENT 구조체 값이 다음과 같이 설정된 DXGKCB_SIGNALEVENT 호출합니다.

  • hDxgkProcess는 0과 같습니다.

  • hEventDXGKDDI_CREATECPUEVENT 전달된 Dxgkrnl CPU 이벤트 개체 핸들과 같습니다.

  • CpuEventObject 는 1이어야 합니다.

  • 예약은 0이어야 합니다.