Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Существуют случаи, когда драйвер в режиме ядра (KMD) должен сигнализировать о событии ЦП, чтобы уведомить драйвер пользовательского режима (UMD) о чем-то; Например:
- Когда KMD обнаруживает, что один из его объектов находится в плохом состоянии и должен уведомлять UMD.
- Во время отладки GPU, когда KMD должен сообщить UMD о произошедшем событии. Для независимых производителей оборудования (IHV) с панелями управления для GPU, KMD, сигнализируя о событиях процессора, позволяет уведомлять приложение панели управления GPU о внутренних событиях.
Как правило, UMD может создать событие ЦП и передать его дескриптор NT в KMD, используя приватные данные. Этот метод не работает в сценарии паравиртуализации GPU (GPU-PV), так как дескрипторы NT нельзя использовать между границами виртуальных машин.
Начиная с Windows 11 версии 21H2 (WDDM 3.0), API WDDM был расширен, чтобы разрешить UMD создать объект события ЦП, который может быть сигналирован KMD. Эта функция работает как при запуске UMD на узле, так и в виртуальной машине с помощью GPU-PV.
Поток функций
UMD создает объект синхронизации GPU с типом D3DDDI_CPU_NOTIFICATION . Созданный объект становится видимым для KMD, задав флаг SignalByKmd при вызове D3DKMTCreateSynchronizationObject.
Dxgkrnl вызывает DXGKDDI_CREATECPUEVENT , чтобы разрешить KMD создавать собственный объект.
UMD вызывает D3DKMTEscape с известным escape type D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE, чтобы уведомить KMD о предполагаемом использовании объекта синхронизации.
Dxgkrnl вызывает DXGKDDI_ESCAPE для передачи частных данных в KMD.
В какой-то момент KMD вызывает DXGKCB_SIGNALEVENT с флагом CpuEventObject , чтобы сигнализировать объект события ЦП.
UMD вызывает D3DKMTDesynchronizationObject для уничтожения объекта события ЦП.
Dxgkrnl вызывает DXGKDDI_DESTROYCPUEVENT для уничтожения объекта события ЦП. DXGKCB_SIGNALEVENT не следует вызывать после этого момента.
Объект синхронизации нельзя вставить в очередь контекста. Сигнал о нем может передаваться только KMD через DXGKCB_SIGNALEVENT.
API пользовательского режима для обработки объектов синхронизации событий ЦП
Создание объекта события KMD CPU
Объект события KMD для ЦП создается как объект синхронизации GPU посредством вызова D3D12DDICB_CREATESYNCHRONIZATIONOBJECT2 с:
Тип установлен на D3DDDI_CPU_NOTIFICATION.
Флаги, установленные на SignalByKmd, чтобы указать, что объект будет сигнализирован KMD. Этот флаг можно задать только в том случае, если элемент Type структуры D3DDDI_SYNCHRONIZATIONOBJECTINFO2 является D3DDDI_CPU_NOTIFICATION.
Когда установлен флаг SignalByKmd, будет вызвана функция DXGKDDI_CREATECPUEVENT для создания объекта события ЦП KMD. Обратите внимание, что при создании объекта синхронизации необходимо указать дескриптор устройства.
Объект синхронизации нельзя использовать в API сигнала и ожидания (D3DKMTSignalSynchronizationObject, D3DKMTWaitForSynchronizatioObject). Сигнал может быть подан только KMD, а UMD может ожидать соответствующего события ЦП.
UMD escape для задания использования объекта синхронизации событий на центральном процессоре KMD
В D3DDDI_DRIVERESCAPETYPE добавлен известный escape-экран. D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE используется для уведомления KMD о предполагаемом использовании объекта события центрального процессора 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 , заданный для дескриптора минипорта устройства, который использовался для создания объекта синхронизации
- pPrivateDriverData, указывающий на структуру D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE
-
PrivateDriverDataSize установлено в
sizeof(D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE)
Создание и уничтожение объекта события процессора KMD
Следующие DDIs используются для создания и уничтожения объектов синхронизации событий ЦП KMD:
Сигнализация объекта события процессора из KMD
Чтобы сигнализировать объект события ЦП, KMD вызывает DXGKCB_SIGNALEVENT на IRQL <= DISPATCH_LEVEL с значениями структуры DXGKARGCB_SIGNALEVENT, установленными следующим образом:
hDxgkProcess равно 0.
hEvent равно дескриптору события ЦП Dxgkrnl , переданной в DXGKDDI_CREATECPUEVENT.
CpuEventObject должен иметь значение 1.
Зарезервировано должно быть равно 0.