Synchronisation de threads et TDR

L’illustration suivante montre comment fonctionne la synchronisation des threads pour le pilote miniport d’affichage dans le modèle WDDM (Windows Display Driver Model).

Diagramme montrant la synchronisation de threads dans WDDM.

Si un délai d’attente matériel se produit, le processus de détection et de récupération du délai d’expiration (TDR) démarre. Le planificateur GPU appelle la fonction DxgkDdiResetFromTimeout du pilote, qui réinitialise le GPU. DxgkDdiResetFromTimeout est appelé de manière synchrone avec toute autre fonction de pilote miniport d’affichage, à l’exception des fonctions de gestion de l’alimentation runtime DxgkDdiSetPowerComponentFState et DxgkDdiPowerRuntimeControlRequest. Autrement dit, aucun autre thread ne s’exécute dans le pilote pendant que le thread DxgkDdiResetFromTimeout s’exécute . Le système d’exploitation garantit également qu’aucun accès à la mémoire tampon de trame ne peut se produire à partir d’une application pendant l’appel à DxgkDdiResetFromTimeout ; par conséquent, le pilote peut réinitialiser une boucle de verrouillage de phase (PLL) du contrôleur de mémoire, et ainsi de suite.

Pendant que le thread de récupération exécute DxgkDdiResetFromTimeout, les interruptions et les appels de procédure différée (PDC) peuvent continuer à être appelés. La fonction KeSynchronizeExecution peut être utilisée pour synchroniser des parties de la procédure de réinitialisation avec des interruptions d’appareil.

Une fois le pilote retourné à partir de DxgkDdiResetFromTimeout, la plupart des fonctions de pilote peuvent à nouveau être appelées et le système d’exploitation commence à propre les ressources qui ne sont plus nécessaires. Pendant la période de nettoyage, les fonctions de pilote suivantes sont appelées pour les raisons indiquées :

  • Le pilote est appelé pour signaler la suppression d’une allocation.

    Par exemple, si l’allocation a été paginée dans un segment de mémoire, la fonction DxgkDdiBuildPagingBuffer du pilote est appelée avec le membre Operation de la structure DXGKARG_BUILDPAGINGBUFFER défini sur DXGK_OPERATION_TRANSFER et avec le membre Transfer.Size défini sur zéro pour informer le pilote de l’éviction. Notez qu’aucun transfert de contenu n’est impliqué, car le contenu a été perdu pendant la réinitialisation.

    Si l’allocation a été paginée dans un segment d’ouverture, la fonction DxgkDdiBuildPagingBuffer du pilote est appelée avec le membre Operation de DXGKARG_BUILDPAGINGBUFFER défini sur DXGK_OPERATION_UNMAP_APERTURE_SEGMENT pour informer le pilote d’annuler le mappage de l’allocation à partir de l’ouverture.

  • La fonction DxgkDdiReleaseSwizzlingRange du pilote est appelée pour libérer une ouverture non pivotante et des plages d’ouverture de segment.

Le pilote ne doit pas accéder au GPU lors des appels précédents, sauf si cela est absolument nécessaire.

Une fois la période de nettoyage terminée, le système d’exploitation appelle la fonction DxgkDdiRestartFromTimeout du pilote pour informer le pilote que le nettoyage est terminé et que le système d’exploitation reprendra à l’aide de l’adaptateur pour le rendu.