TDR в Windows 8 и более поздних версиях

Начиная с Windows 8 функция обнаружения и восстановления времени ожидания GPU (TDR) позволяет сбрасывать части отдельных физических адаптеров, не требуя сброса на уровне адаптера.

Дополнительные сведения о TDR см. в разделе Обнаружение и восстановление времени ожидания (TDR).

Требования

  • Минимальная версия WDDM: 1.2
  • Минимальная версия Windows: 8
  • Реализация драйвера — полная графика и только отрисовка: обязательно
  • Требования и тесты WHLK: Device.Graphics... TDRResiliency

Интерфейс драйвера устройства TDR (DDI)

Чтобы учесть это изменение поведения, драйверы мини-портов для отображения реализуют следующие функции:

Драйвер мини-порта дисплея указывает на поддержку этих функций, задав DXGK_DRIVERCAPS. Член SupportPerEngineTDR , в этом случае он должен реализовывать все перечисленные выше функции.

Примечание

Драйвер, поддерживающий эти функции, также должен поддерживать синхронизацию нулевого уровня для функции DxgkDdiCollectDbgInfo . Это необходимо для обеспечения продолжения вызовов мини-портов нулевого уровня, не затронутых операцией сброса. См. примечания DxgkDdiCollectDbgInfo.

С приведенными выше функциями связаны следующие структуры:

Узлы

Как указано в приведенных выше функциях TDR, узел является одной из нескольких частей одного физического адаптера, который можно запланировать независимо. Например, трехмерный узел, узел декодирования видео и узел копирования могут существовать в одном физическом адаптере, и каждому из них может быть назначено отдельное порядковое значение узла в DXGKARG_QUERYDEPENDENTENGINEGROUP. Элемент NodeOrdinal в вызове DxgkDdiQueryDependentEngineGroup.

Число узлов в физическом адаптере определяется драйвером мини-порта дисплея в элементе NbAsymetricProcessingNodesDXGK_DRIVERCAPS. GpuEngineTopology.

Порядковое значение узла передается в элемент NodeOrdinal структуры DXGKARG_CREATECONTEXT при создании контекста.

Двигатели

Как используется в приведенных выше функциях TDR, подсистема является одним из нескольких физических адаптеров (или GPU), которые вместе действуют в качестве одного логического адаптера. Подсистема ядра графики DirectX поддерживает такие конфигурации, но требует, чтобы у каждого обработчика было одинаковое количество узлов.

Например, планировщик GPU считает, что подсистема 0 соответствует физическому адаптеру 0. Подсистема 0 должна иметь то же количество узлов, что и подсистема 1, что соответствует адаптеру 1.

Порядковое значение подсистемы при создании контекста

При создании контекста в элементе EngineAffinity структуры DXGKARG_CREATECONTEXT задается один бит, соответствующий порядковой стоимости подсистемы. Элемент EngineOrdinal этой и других структур, связанных с планировщиком, является индексом от нуля. Значение EngineAffinity равно 1 <<EngineOrdinal, а EngineOrdinal — самая высокая битовая позиция в EngineAffinity.

Пакеты, не затронутые сбросом подсистемы

Планировщик GPU может попросить драйвер повторно отправить пакеты, которые были отправлены слишком поздно в очередь оборудования подсистемы для полной обработки до завершения сброса подсистемы. Чтобы повторно отправлять такие пакеты, драйвер должен следовать этим рекомендациям:

  • Пакеты разбиения по страницам. Планировщик GPU попросит драйвера повторно отправлять пакеты подкачки с исходными идентификаторами ограждения в том же порядке, в который они были отправлены изначально. Все такие пакеты будут повторно отправляться перед добавлением новых пакетов в очередь оборудования.
  • Отрисовка пакетов. Планировщик GPU назначит отрисовки пакетов новые идентификаторы ограждения, а затем повторно отправляет их.

Последовательность вызовов для сброса подсистемы

После успешного выполнения dxgkDdiResetEngine планировщик GPU гарантирует, что значение LastAbortedFenceId , возвращаемое вызовом сброса подсистемы, соответствует либо существующему идентификатору ограждения в очереди оборудования, либо последнему завершенному идентификатору ограждения на GPU. Последняя ситуация может произойти, когда очередь оборудования очищается после обнаружения времени ожидания GPU, но до вызова обратного вызова сброса подсистемы.

Последнее завершенное значение идентификатора ограждения в GPU должно поддерживаться драйвером в любое время, так как оно также необходимо для задания элемента DmaPreempted.LastCompletedFenceId структуры уведомления о прерывании DXGKARGCB_NOTIFY_INTERRUPT_DATA вытеснения. Последний завершенный идентификатор ограждения должен быть расширен только в следующих ситуациях:

  • Когда пакет завершен (не вытесняется), последний завершенный идентификатор ограждения должен быть задан в качестве идентификатора ограждения завершенного пакета.
  • При успешном выполнении dxgkDdiResetEngine для последнего завершенного идентификатора ограждения должно быть задано значение члена LastCompletedFenceId , возвращаемое вызовом сброса подсистемы.
  • Для сброса на уровне адаптера последний завершенный идентификатор ограждения на всех узлах должен быть расширен до последнего переданного идентификатора ограждения во время сброса.

Ниже приведена хронологическая последовательность успешного сброса подсистемы, как видно планировщику GPU:

  1. Выполняется попытка вытеснения.

  2. Обнаружено время ожидания GPU.

  3. Планировщик GPU принимает snapshot последних отправленных и завершенных идентификаторов ограждения, а прерывания подсистемы ожидания игнорируются. Это одна атомарная операция на уровне прерывания устройства.

  4. Если на данный момент в очереди оборудования нет пакетов, выйдите из нее. Это может произойти, если пакет был завершен в период между шагами 2 и 3.

  5. Все поставленные в очередь контроллеры домена очищаются.

  6. Подготовка к сбросу подсистемы.

  7. Вызовите DxgkDdiResetEngine.

  8. Если член LastAbortedFenceId меньше последнего завершенного идентификатора ограждения или больше идентификатора последнего отправленного забора, подсистема графического ядра DirectX вызывает проверку системных ошибок. В файле аварийного дампа ошибка отмечается сообщением BugCheck 0x119, которое имеет следующие четыре параметра:

    • 0xA, то есть водитель сообщил о недопустимом прерванном заборе
    • Значение LastAbortedFenceId , возвращаемое драйвером
    • Идентификатор последнего завершенного ограждения
    • Параметр внутренней операционной системы
  9. Если значение LastAbortedFenceId является допустимым, выполните восстановление сброса подсистемы следующим образом. Если на пакет подкачки повлиял сброс подсистемы, планировщик GPU следует за сбросом подсистемы с помощью сброса на уровне адаптера. Все устройства, владеющие выделениями, на которые ссылается этот пакет подкачки, также помещаются в состояние ошибки. Однако само системное устройство не переводится в состояние ошибки и возобновляет выполнение после завершения сброса.

Особые случаи

Особая ситуация может возникнуть, когда пакет завершается на GPU между шагами 3 и 7, описанными выше. В этом случае для Параметра LastAbortedFenceId драйвер должен задать идентификатор последнего завершенного пакета, если с точки зрения драйвера в очереди оборудования нет пакетов. С точки зрения планировщика будет казаться, что такой пакет был прерван, и соответствующее устройство будет переведено в состояние ошибки, даже если пакет в конечном итоге завершен.

Если драйвер не может выполнить операцию сброса, так как оборудование находится в недопустимом состоянии или оборудование не может сбрасывать узлы, драйвер должен вернуть код состояния сбоя. Если планировщик GPU получает код состояния сбоя, он выполняет операцию сброса и перезапуска на уровне адаптера после поведения TDR до Windows 8.

Даже если драйвер выбрал Windows 8 и более поздних версий TDR, в некоторых случаях планировщик GPU запрашивает сброс и перезапуск всего логического адаптера. Поэтому драйвер должен по-прежнему реализовывать функции DxgkDdiResetFromTimeout и DxgkDdiRestartFromTimeout, а их семантика остается такой же, как и до Windows 8. Когда попытка сброса физического адаптера с помощью DxgkDdiResetEngine приводит к сбросу логического адаптера, команда !analyze отладчика Windows показывает, что для значения TdrReason контекста восстановления TDR задано новое значение TdrEngineTimeoutPromotedToAdapterReset = 9.