Windows 8 和更新版本中的 TDR
從 Windows 8 開始,GPU 逾時偵測和復原 (TDR) 行為可讓個別實體適配卡的部分重設,而不需要全適配卡重設。
如需詳細資訊,請參閱逾時偵測和復原(TDR)。
需求
- 最低 WDDM 版本:1.2
- 最低 Windows 版本:8
- 驅動程序實作— 僅限完整圖形和轉譯:必要
- WHLK 需求和測試: Device.Graphics...TDRResiliency
TDR 裝置驅動器介面 (DDI)
為了配合此行為變更,內核模式顯示迷你埠驅動程式 (KMD) 可以實作下列函式:
KMD 會藉由設定 DXGK_DRIVERCAPS來指出這些函式的支援。SupportPerEngineTDR 成員,在此情況下,它必須實作所有列出的函式。
支援這些函式的驅動程式也必須支援 DxgkDdiCollectDbgInfo 函式的層級零同步處理。 這項需求可確保如果重設作業不會影響 KMD 呼叫,層級零 KMD 呼叫仍可繼續。 請參閱 DxgkDdiCollectDbgInfo 的備註。
下列結構與上述函式相關聯:
- DXGK_DRIVERCAPS
- DXGK_ENGINESTATUS
- DXGKARG_QUERYDEPENDENTENGINEGROUP
- DXGKARG_QUERYENGINESTATUS
- DXGKARG_RESETENGINE
節點
如同列出的 TDR 函式中所使用, 節點 是單一實體配接器中可獨立排程的多個部分之一。 例如,3D節點、視訊譯碼節點和複製節點全都可以存在於相同的實體適配卡中,而且每個節點都可以指派個別的節點序數。 此指派會儲存在DXGKARG_QUERYDEPENDENTENGINEGROUP中。呼叫 DxgkDdiQueryDependentEngineGroup 中的 NodeOrdinal 成員。
實體配接器中的節點數目是由 DXGK_DRIVERCAPS NbAsymetricProcessingNodes 成員中的顯示迷你埠驅動程式所報告。GpuEngineTopology。
當建立內容時,節點序數值會在DXGKARG_CREATECONTEXT結構的 NodeOrdinal 成員中傳遞。
引擎
如同 TDR DDI 函式中所使用的,引擎是多個實體配接器之一(或 GPU),一起做為一個邏輯配接器。 Dxgkrnl 支援這類設定,但要求每個引擎都必須有相同數目的節點。
例如,GPU 排程器會將引擎 0 視為對應至實體適配卡 0。 引擎 0 必須擁有與引擎 1 相同的節點數目,其對應至適配卡 1。
建立內容時的引擎序數值
建立內容時,會在DXGKARG_CREATECONTEXT 結構的 EngineAffinity 成員中設定對應至引擎序數值的單一位。 這個和其他排程器相關結構的 EngineOrdinal 成員是以零起始的索引。 EngineAffinity 的值是 1<< EngineOrdinal,EngineOrdinal 是 EngineAffinity 中最高的位位置。
引擎重設未受影響的封包
GPU 排程器可能會要求驅動程式在引擎重設完成之前,重新提交已提交到引擎硬體佇列太晚的封包,無法完全處理。 驅動程式必須遵循下列指導方針,才能重新提交這類封包:
- 分頁封包:GPU 排程器會要求驅動程式以原始的柵欄標識元重新提交分頁封包,且順序與原本送出封包的順序相同。 在新的封包新增至硬體佇列之前,會重新提交任何這類封包。
- 轉譯封包:GPU 排程器會指派轉譯封包新的圍欄標識符,然後重新提交。
呼叫序列以重設引擎
當 DxgkDdiResetEngine 成功時,GPU 排程器可確保從引擎重設呼叫傳回的 LastAbortedFenceId 值會對應至:
- 硬體佇列中現有的柵欄標識碼。
- GPU 上最後一個已完成的柵欄標識碼。 當硬體佇列在偵測到 GPU 逾時後空,但在叫用引擎重設回呼之前,就可能發生這種情況。
驅動程序必須一律維護 GPU 上最後一個已完成的柵欄標識碼值,因為需要該柵欄標識碼,才能設定DXGKARGCB_NOTIFY_INTERRUPT_DATA先占通知結構的 DmaPreempted.LastCompletedFenceId 成員。 最後一個已完成的柵欄標識碼應該只在下列情況下進階:
- 當封包完成時(未先佔),最後一個已完成的圍欄標識碼應該設定為已完成封包的柵欄標識碼。
- 當 DxgkDdiResetEngine 成功時,最後完成的柵欄標識碼應該設定為引擎重設呼叫所傳回的 LastCompletedFenceId 成員的值。
- 針對全適配卡重設,所有節點上最後一個已完成的柵欄標識碼都應該在重設時,進階到最後一個提交的圍欄標識碼。
以下是成功重設引擎的時間序列,如 GPU 排程器所見:
會發出先佔嘗試。
偵測到 GPU 逾時。
GPU 排程器會擷取上次提交和已完成的圍欄標識碼的快照集,並忽略逾時引擎的中斷。 此組合是裝置中斷層級的一個不可部分完成作業。
如果此時硬體佇列中沒有封包,請結束。 在步驟 2 和 3 之間的時間範圍中完成封包時,就可能發生這種情況。
所有已排入佇列的 DPC 都會排清。
準備引擎重設。
如果 LastAbortedFenceId 成員小於上次完成的柵欄標識碼或大於最後提交的柵欄標識碼,Dxgkrnl 會導致系統錯誤檢查發生。 在損毀傾印檔案中,錯誤是由 BugCheck 0x119訊息所指出,其中包含下列四個參數:
- 0xA,這表示驅動程序回報了無效的中止圍欄標識碼
- 驅動程式傳回的 LastAbortedFenceId 值
- 上次完成的柵欄標識碼
- 內部作業系統參數
如果 LastAbortedFenceId 值有效,請繼續進行引擎重設復原,如下所示。 如果引擎重設會影響分頁封包,GPU 排程器會遵循引擎重設,並重設全適配卡。 擁有該分頁封包所參考配置的所有裝置也會處於錯誤狀態。 系統裝置本身不會進入錯誤狀態,而且會在重設完成之後繼續執行。
特殊情況
在步驟 3 和 7 之間的 GPU 上完成封包時,可能會發生特殊情況。 在此情況下,如果驅動程式的觀點中沒有硬體佇列中的封包,驅動程式應該將 LastAbortedFenceId 設定為最後一個已完成封包的柵欄標識碼。 從排程器的觀點來看,這類封包似乎已中止。 因此,即使封包最終完成,排程器仍會將對應的裝置置於錯誤狀態。
如果驅動程式因下列任一原因而無法執行重設作業,它應該會傳回失敗狀態代碼:
- 硬體處於無效狀態。
- 硬體無法重設節點。
如果 GPU 排程器收到失敗狀態代碼,它會在 Windows 8 之前執行全適配卡重設並重新啟動作業。
即使驅動程式加入加入 Windows 8 和更新版本的 TDR 行為,GPU 排程器仍會要求重設並重新啟動整個邏輯適配卡。 因此,驅動程式仍必須實 作 DxgkDdiResetFromTimeout 和 DxgkDdiRestartFromTimeout 函式,而且其語意與 Windows 8 之前相同。 嘗試使用 DxgkDdiResetEngine 重設實體適配卡時,Windows 調試程式的 !analyze 命令會顯示 TDR 復原內容的 TdrReason 值設定為 TdrEngineTimeoutPromotedToAdapterReset = 9 的新值。