Windows 8 和更新版本中的 TDR

從 Windows 8 開始,GPU 逾時偵測和復原 (TDR) 行為可讓個別實體適配卡的部分重設,而不需要重設全適配卡。

如需 TDR 的詳細資訊,請參閱逾時偵測和復原 (TDR)

規格需求

  • 最低 WDDM 版本:1.2
  • 最低 Windows 版本:8
  • 驅動程序實作 - 僅限完整圖形和轉譯:強制
  • WHLK 需求和測試: Device.Graphics...TDRResiliency

TDR 裝置驅動程式介面 (DDI)

若要因應此行為變更,請顯示迷你埠驅動程式會實作下列函式:

顯示迷你埠驅動程式會藉由設定 DXGK_DRIVERCAPS來指出這些函式的支援。SupportPerEngineTDR 成員,在此情況下,它必須實作上述所有函式。

注意

支援這些函式的驅動程式也必須支援 DxgkDdiCollectDbgInfo 函式的層級零同步處理。 這是為了確保重設作業不會影響層級零的迷你埠呼叫可以繼續。 請參閱 DxgkDdiCollectDbgInfo 的備註。

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

節點

如上述 TDR 函式中所使用, 節點 是可獨立排程之單一實體適配卡的多個部分之一。 例如,3D節點、視訊譯碼節點和複製節點全都存在於相同的實體配接器中,而且每個節點都可以在DXGKARG_QUERYDEPENDENTENGINEGROUP中指派個別的節點序數值。呼叫 DxgkDdiQueryDependentEngineGroup 中的 NodeOrdinal 成員。

實體配接器中的節點數目是由 DXGK_DRIVERCAPSNbAsymetricProcessingNodes 成員中的顯示迷你埠驅動程式所報告。GpuEngineTopology

建立內容時,節點序數值會傳入DXGKARG_CREATECONTEXT結構的 NodeOrdinal 成員。

引擎

如上述 TDR 函式中所使用, 引擎 是多個實體配接器之一, (或 GPU) 一起做為一個邏輯配接器。 DirectX 圖形核心子系統支援這類設定,但需要每個引擎必須具有相同數目的節點。

例如,GPU 排程器會將引擎 0 視為對應至實體適配卡 0。 引擎 0 必須有與引擎 1 相同的節點數目,其對應至配接器 1。

建立內容時的引擎序數值

建立內容時,會在DXGKARG_CREATECONTEXT 結構的 EngineAffinity 成員中設定對應至引擎序數值的單一位。 這個和其他排程器相關結構的 EngineOrdinal 成員是以零起始的索引。 EngineAffinity 的值是 1 <<EngineOrdinal,EngineOrdinalEngineAffinity 中最高的位位置。

引擎重設不會影響封包

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 成員小於最後一個已完成的柵欄標識碼,或大於最後提交的柵欄標識碼,DirectX 圖形核心子系統就會發生系統錯誤檢查。 在損毀傾印檔案中,錯誤是由 錯誤檢查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 的新值。