TDR dans Windows 8 et versions ultérieures

À compter de Windows 8, le comportement de détection et de récupération du délai d’expiration gpu (TDR) permet de réinitialiser des parties d’adaptateurs physiques individuels, au lieu d’exiger une réinitialisation à l’échelle de l’adaptateur.

Pour plus d’informations sur la détection et la récupération du délai d’expiration (TDR).

Configuration requise

  • Version minimale de WDDM : 1.2
  • Version minimale de Windows : 8
  • Implémentation de pilote : graphiques complets et rendu uniquement : obligatoire
  • Exigences et tests WHLK : Device.Graphics... TDRResiliency

Interface de pilote de périphérique (DDI) TDR

Pour prendre en charge ce changement de comportement, les pilotes de miniport d’affichage implémentent les fonctions suivantes :

Un pilote de miniport d’affichage indique la prise en charge de ces fonctions en définissant le DXGK_DRIVERCAPS. Membre SupportPerEngineTDR , auquel cas il doit implémenter toutes les fonctions ci-dessus.

Notes

Un pilote qui prend en charge ces fonctions doit également prendre en charge la synchronisation de niveau zéro pour la fonction DxgkDdiCollectDbgInfo . Cela permet de s’assurer que les appels de niveau zéro miniport non affectés par l’opération de réinitialisation peuvent continuer. Consultez Remarques de DxgkDdiCollectDbgInfo.

Les structures suivantes sont associées aux fonctions ci-dessus :

Nœuds

Comme utilisé dans les fonctions TDR ci-dessus, un nœud est l’une des multiples parties d’une seule carte physique qui peut être planifiée indépendamment. Par exemple, un nœud 3D, un nœud de décodage vidéo et un nœud de copie peuvent tous exister dans la même carte physique, et chacun peut se voir attribuer une valeur ordinale de nœud distincte dans le DXGKARG_QUERYDEPENDENTENGINEGROUP. Membre NodeOrdinal dans un appel à DxgkDdiQueryDependentEngineGroup.

Le nombre de nœuds dans l’adaptateur physique est signalé par le pilote miniport d’affichage dans le membre NbAsymetricProcessingNodes de DXGK_DRIVERCAPS. GpuEngineTopology.

La valeur ordinale de nœud est passée dans le membre NodeOrdinal de la structure DXGKARG_CREATECONTEXT lors de la création d’un contexte.

Moteurs

Comme utilisé dans les fonctions TDR ci-dessus, un moteur est l’un des multiples adaptateurs physiques (ou GPU) qui agissent ensemble comme une seule carte logique. Le sous-système du noyau graphique DirectX prend en charge ces configurations, mais exige que chaque moteur ait le même nombre de nœuds.

Par exemple, le planificateur GPU considère que le moteur 0 correspond à l’adaptateur physique 0. Le moteur 0 doit avoir le même nombre de nœuds que le moteur 1, ce qui correspond à l’adaptateur 1.

Valeur ordinale du moteur lors de la création du contexte

Lorsqu’un contexte est créé, un seul bit correspondant à la valeur ordinale du moteur est défini dans le membre EngineAffinity de la structure DXGKARG_CREATECONTEXT . Le membre EngineOrdinal de cette structure et d’autres structures liées au planificateur est un index de base zéro. La valeur de EngineAffinity est 1 <<EngineOrdinal et EngineOrdinal est la position de bits la plus élevée dans EngineAffinity.

Paquets non affectés par la réinitialisation du moteur

Le planificateur GPU peut demander au pilote de renvoyer les paquets envoyés trop tard à la file d’attente matérielle du moteur pour être entièrement traités avant la réinitialisation du moteur. Le pilote doit suivre ces instructions pour soumettre à nouveau ces paquets :

  • Pagination des paquets : le planificateur GPU demande au pilote de renvoyer les paquets de pagination avec leurs ID de clôture d’origine, et dans le même ordre qu’ils ont été envoyés à l’origine. Tous ces paquets seront soumis de nouveau avant que de nouveaux paquets ne soient ajoutés à la file d’attente matérielle.
  • Rendu des paquets : le planificateur GPU attribue aux paquets de rendu de nouveaux ID de clôture, puis les soumettre à nouveau.

Séquence d’appel pour réinitialiser un moteur

Lorsque DxgkDdiResetEngine réussit, le planificateur GPU s’assure que la valeur LastAbortedFenceId retournée par l’appel de réinitialisation du moteur correspond soit à un ID de clôture existant dans la file d’attente matérielle, soit au dernier ID de clôture terminé sur le GPU. Cette dernière situation peut se produire lorsque la file d’attente matérielle se vide après la détection du délai d’attente GPU, mais avant l’appel du rappel de réinitialisation du moteur.

La dernière valeur d’ID de clôture terminée sur le GPU doit être conservée par le pilote à tout moment, car elle est également nécessaire pour définir le membre DmaPreempted.LastCompletedFenceId d’une structure de notification d’interruption de préemption DXGKARGCB_NOTIFY_INTERRUPT_DATA . Le dernier ID de clôture terminé doit être avancé uniquement dans les situations suivantes :

  • Lorsqu’un paquet est terminé (et non préempté), l’ID de clôture terminé doit être défini sur l’ID de clôture du paquet terminé.
  • Lorsque DxgkDdiResetEngine réussit, le dernier ID de clôture terminé doit être défini sur la valeur du membre LastCompletedFenceId retourné par l’appel de réinitialisation du moteur.
  • Pour la réinitialisation à l’échelle de l’adaptateur, le dernier ID de clôture terminé sur tous les nœuds doit être avancé au dernier ID de clôture envoyé au moment de la réinitialisation.

Voici une séquence chronologique d’une réinitialisation du moteur réussie, comme le montre le planificateur GPU :

  1. Une tentative de préemption est émise.

  2. Un délai d’attente GPU est détecté.

  3. Une instantané des derniers ID de clôture envoyés et terminés est prise par le planificateur GPU, et les interruptions du moteur de délai d’expiration sont ignorées. Il s’agit d’une opération atomique au niveau de l’interruption de l’appareil.

  4. S’il n’y a pas de paquets dans la file d’attente matérielle à ce stade, quittez. Cela peut se produire si un paquet a été terminé dans la fenêtre de temps entre les étapes 2 et 3.

  5. Tous les DPC en file d’attente sont vidés.

  6. Préparer la réinitialisation du moteur.

  7. Appelez DxgkDdiResetEngine.

  8. Si le membre LastAbortedFenceId est inférieur au dernier ID de clôture terminé ou supérieur au dernier ID de clôture envoyé, le sous-système du noyau graphique DirectX entraîne une vérification de bogue système. Dans un fichier de vidage sur incident, l’erreur est notée par le message BugCheck 0x119, qui a les quatre paramètres suivants :

    • 0xA, ce qui signifie que le conducteur a signalé un ID de clôture abandonné non valide
    • Valeur LastAbortedFenceId retournée par le pilote
    • ID de clôture terminé
    • Paramètre de système d’exploitation interne
  9. Si la valeur LastAbortedFenceId est valide, procédez à la récupération de la réinitialisation du moteur comme suit. Si un paquet de pagination a été affecté par la réinitialisation du moteur, le planificateur GPU suit la réinitialisation du moteur avec une réinitialisation à l’échelle de l’adaptateur. Tous les appareils qui possèdent des allocations référencées par ce paquet de pagination sont également placés dans l’état d’erreur. Toutefois, l’appareil système lui-même n’est pas placé dans l’état d’erreur et il reprend l’exécution une fois la réinitialisation terminée.

Cas particuliers

Une situation particulière peut se produire lorsqu’un paquet est terminé sur le GPU entre les étapes 3 et 7 décrites ci-dessus. Dans ce cas, LastAbortedFenceId doit être défini par le pilote sur l’ID de clôture du dernier paquet terminé s’il n’y a aucun paquet dans la file d’attente matérielle du point de vue du pilote. Du point de vue du planificateur, il semble qu’un tel paquet a été abandonné et que l’appareil correspondant sera placé dans un état d’erreur, même si le paquet a finalement été terminé.

Si le pilote ne peut pas effectuer une opération de réinitialisation parce que le matériel est dans un état non valide ou parce que le matériel ne peut pas réinitialiser les nœuds, le pilote doit retourner une défaillance status code. Si le planificateur GPU reçoit un échec status code, il effectue une opération de réinitialisation et de redémarrage à l’échelle de l’adaptateur suivant le comportement TDR avant Windows 8.

Même si un pilote a opté pour le comportement TDR Windows 8 et ultérieur, il arrive que le planificateur GPU demande une réinitialisation et un redémarrage de l’ensemble de l’adaptateur logique. Par conséquent, le pilote doit toujours implémenter les fonctions DxgkDdiResetFromTimeout et DxgkDdiRestartFromTimeout, et leur sémantique reste la même qu’avant Windows 8. Lorsqu’une tentative de réinitialisation d’une carte physique avec DxgkDdiResetEngine entraîne une réinitialisation de l’adaptateur logique, la commande !analyze du débogueur Windows montre que la valeur TdrReason du contexte de récupération TDR est définie sur une nouvelle valeur de TdrEngineTimeoutPromotedToAdapterReset = 9.