共用方式為


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備註。

下列結構與上述函式相關聯:

節點

如同列出的 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 排程器所見:

  1. 會發出先佔嘗試。

  2. 偵測到 GPU 逾時。

  3. GPU 排程器會擷取上次提交和已完成的圍欄標識碼的快照集,並忽略逾時引擎的中斷。 此組合是裝置中斷層級的一個不可部分完成作業。

  4. 如果此時硬體佇列中沒有封包,請結束。 在步驟 2 和 3 之間的時間範圍中完成封包時,就可能發生這種情況。

  5. 所有已排入佇列的 DPC 都會排清。

  6. 準備引擎重設。

  7. 呼叫 DxgkDdiResetEngine

  8. 如果 LastAbortedFenceId 成員小於上次完成的柵欄標識碼或大於最後提交的柵欄標識碼,Dxgkrnl 會導致系統錯誤檢查發生。 在損毀傾印檔案中,錯誤是由 BugCheck 0x119訊息所指出,其中包含下列四個參數:

    • 0xA,這表示驅動程序回報了無效的中止圍欄標識碼
    • 驅動程式傳回的 LastAbortedFenceId
    • 上次完成的柵欄標識碼
    • 內部作業系統參數
  9. 如果 LastAbortedFenceId 值有效,請繼續進行引擎重設復原,如下所示。 如果引擎重設會影響分頁封包,GPU 排程器會遵循引擎重設,並重設全適配卡。 擁有該分頁封包所參考配置的所有裝置也會處於錯誤狀態。 系統裝置本身不會進入錯誤狀態,而且會在重設完成之後繼續執行。

特殊情況

在步驟 3 和 7 之間的 GPU 上完成封包時,可能會發生特殊情況。 在此情況下,如果驅動程式的觀點中沒有硬體佇列中的封包,驅動程式應該將 LastAbortedFenceId 設定為最後一個已完成封包的柵欄標識碼。 從排程器的觀點來看,這類封包似乎已中止。 因此,即使封包最終完成,排程器仍會將對應的裝置置於錯誤狀態。

如果驅動程式因下列任一原因而無法執行重設作業,它應該會傳回失敗狀態代碼:

  • 硬體處於無效狀態。
  • 硬體無法重設節點。

如果 GPU 排程器收到失敗狀態代碼,它會在 Windows 8 之前執行全適配卡重設並重新啟動作業

即使驅動程式加入加入 Windows 8 和更新版本的 TDR 行為,GPU 排程器仍會要求重設並重新啟動整個邏輯適配卡。 因此,驅動程式仍必須實 作 DxgkDdiResetFromTimeoutDxgkDdiRestartFromTimeout 函式,而且其語意與 Windows 8 之前相同。 嘗試使用 DxgkDdiResetEngine 重設實體適配卡時,Windows 調試程式的 !analyze 命令會顯示 TDR 復原內容的 TdrReason 值設定為 TdrEngineTimeoutPromotedToAdapterReset = 9 的新值