スレッドの同期および TDR

次の図は、Windows ディスプレイ ドライバー モデル (WDDM) のディスプレイ ミニポート ドライバーのスレッド同期のしくみを示しています。

Diagram that shows thread synchronization in WDDM.

ハードウェア タイムアウトが発生すると、タイムアウト検出 と回復 (TDR) プロセスが開始されます。 GPU スケジューラは、GPU をリセットするドライバーの DxgkDdiResetFromTimeout 関数を呼び出します。 DxgkDdiResetFromTimeout は、ランタイム電源管理関数である DxgkDdiSetPowerComponentFStateDxgkDdiPowerRuntimeControlRequest を除き、他のディスプレイ ミニポート ドライバー関数で同期的に呼び出されます。 つまり、DxgkDdiResetFromTimeout スレッドが実行されている間、ドライバーで他のスレッドは実行されません。 また、オペレーティング システムでは、DxgkDdiResetFromTimeout の呼び出し中に任意のアプリケーションからフレーム バッファーへのアクセスがないことも保証されます。したがって、ドライバーはメモリ コントローラー フェーズ ロック ループ (DJ) のリセットなどができます。

回復スレッドは DxgkDdiResetFromTimeout を実行しますが、割り込みと遅延プロシージャ呼び出し (DPC) は引き続き可能です。 KeSynchronizeExecution 関数を使用すると、リセット プロシージャの一部をデバイスの割り込みと同期できます。

ドライバーが DxgkDdiResetFromTimeout から戻ると、ほとんどのドライバー関数を再度呼び出すことができます。オペレーティング システムは、不要になったリソースのクリーンを開始します。 クリーンアップ期間中は、指定された理由で次のドライバー関数が呼び出されます。

  • ドライバーは、削除される割り当てについて通知するために呼び出されます。

    たとえば、割り当てがメモリ セグメントでページングされた場合、ドライバーの DxgkDdiBuildPagingBuffer 関数が Operation メンバー (DXGK_OPERATION_TRANSFER に設定された DXGKARG_BUILDPAGINGBUFFER 構造体のメンバー) と 0 に設定した Transfer.Size メンバーで呼び出され、ドライバーに削除について通知します。 リセット中にコンテンツが失われたため、コンテンツ転送は関係しません。

    アロケーションが絞りセグメントでページングされた場合、ドライバーの DxgkDdiBuildPagingBuffer 関数は、DXGKARG_BUILDPAGINGBUFFER の Operation メンバーを DXGK_OPERATION_UNMAP_APERTURE_SEGMENT に設定して呼び出され、アロケーションをアパーチャからマップ解除するようにドライバーに通知します。

  • ドライバーの DxgkDdiReleaseSwizzlingRange 関数が呼び出され、スウィズリングされていないアパーチャとセグメントのアパーチャ範囲が解放されます。

ドライバーは、絶対に必要な場合を除き、上記の呼び出し中に GPU にアクセスしないでください。

クリーンアップ期間が終了すると、オペレーティング システムはドライバーの DxgkDdiRestartFromTimeout 関数を呼び出して、クリーンアップが完了し、オペレーティング システムがレンダリング用アダプターを使用して再開することをドライバーに通知します。