使用DRED診斷 GPU 錯誤

DRED 代表已移除的裝置擴充數據。 DRED 是一組不斷演進的診斷功能,旨在協助您找出非預期裝置移除錯誤的原因。 在支援必要功能的硬體上,DRED 會提供自動階層連結,以及 GPU 頁面錯誤報告。

自動階層連結

若要設定自動階層鏈接的場景,讓我們先提及手動品種。 在預期逾時偵測和復原 (TDR) 的完成時,您可以使用ID3D12GraphicsCommandList2::WriteBufferImmediate 方法將階層連結放入 GPU 命令數據流中,以追蹤 GPU 進度。

如果您想要建立自定義的低負荷實作,這是合理的方法。 但它可能缺乏標準化解決方案的一些多功能性,例如調試程式延伸模組,或透過 Windows 錯誤報告 (WER) (也稱為 Watson) 報告。

因此,DRED 的自動階層連結會呼叫 WriteBufferImmediate ,將進度計數器放入 GPU 命令數據流中。 DRED 會在每個轉譯作業之後插入階層連結,這表示導致 GPU 工作的每個作業(例如繪製、分派複製解析等)。 如果裝置在 GPU 工作負載中間移除,DRED 階層連結值基本上就是錯誤之前完成的轉譯作業集合。

階層連結歷程記錄通道緩衝區會在指定的命令清單中保留最多 64KiB 作業。 如果命令清單中有超過 65536 個作業,則只會儲存最後 64KiB 作業,先覆寫最舊的作業。 不過,階層連結計數器值會繼續計算到 UINT_MAX。 因此,LastOpIndex = (BreadcrumbCount - 1) % 65536。

DRED 1.0 首次在 Windows 10 1809 版(Windows 10 2018 年 10 月更新)中提供,並公開了基本的自動階層連結。 不過,沒有 API,啟用DRED 1.0 的唯一方法是使用意見反應中樞來擷取 App 和遊戲>效能與相容性TDR 複製(重現)。 DRED 1.0 的主要目的是透過客戶意見反應協助根本原因分析遊戲當機。

警示

  • 因為 GPU 經過大量管線處理,因此不保證階層連結計數器指出失敗的確切作業。 事實上,在某些以磚為基礎的延後轉譯裝置上,階層連結計數器可能是實際 GPU 進度背後的完整資源或未排序存取檢視 (UAV) 屏障。
  • 顯示驅動程式可以在執行命令之前重新排序命令、預先擷取資源記憶體,或在命令完成之後排清快取的記憶體。 其中任何一項都會產生 GPU 錯誤。 在這種情況下,自動階層連結計數器可能不太有用或誤導。

效能

雖然自動階層連結是設計為低負荷,但它們不是免費的。 經驗測量顯示典型 AAA Direct3D 12 圖形遊戲引擎的 2-5% 效能損失。 因此,預設會關閉自動階層連結。

硬體需求

由於在移除裝置之後必須保留階層連結計數器值,所以包含階層連結的資源必須存在於系統記憶體中,而且必須在裝置移除時保存。 這表示顯示驅動程式需要支援 D3D12_FEATURE_EXISTING_HEAPS。 幸運的是,在 Windows 10 版本 1903 上,大部分的 Direct3D 12 顯示驅動程式都是如此。

GPU 頁面錯誤報告

DRED 1.1 的新功能是DRED GPU 頁面錯誤報告。 GPU 頁面錯誤通常發生在下列其中一個狀況下。

  1. 應用程式錯誤地在參考已刪除物件的 GPU 上執行工作。 這是非預期裝置移除的主要原因之一。
  2. 應用程式錯誤地在存取收回的資源或非常駐磚的 GPU 上執行工作。
  3. 著色器會參考未初始化或過時的描述元。
  4. 在根系結結尾以外的著色器索引。

DRED 會報告任何現有或最近釋放的 API 物件的名稱和類型,以符合 GPU 回報頁面錯誤的虛擬位址 (VA) 來嘗試解決其中一些情況。

警告

並非所有 GPU 都支援頁面錯誤(不過,許多都支援)。 某些 GPU 會透過下列方式回應記憶體錯誤:位貯體寫入;讀取模擬資料(例如零):或只是懸掛。 不幸的是,在 GPU 未立即停止響應的情況下, 管道稍後可能會發生逾時偵測和復原 (TDR), 使得找出根本原因更加困難。

效能

Direct3D 12 運行時間必須主動策劃虛擬位址可索引的現有和最近刪除的 API 物件集合。。 這會增加系統記憶體額外負荷,並引入對物件建立和破壞的小型效能。 因此,此行為預設為關閉。

硬體需求

不支援頁面錯誤的 GPU 仍可受益於自動階層連結功能。

在程式代碼中設定DRED

DRED 設定是程式的全域設定,您必須在建立 Direct3D 12 裝置之前進行設定。 若要這樣做,請呼叫 D3D12GetDebugInterface 函式來擷取 ID3D12DeviceRemovedExtendedData 設定

CComPtr<ID3D12DeviceRemovedExtendedDataSettings> pDredSettings;
VERIFY_SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pDredSettings)));

// Turn on auto-breadcrumbs and page fault reporting.
pDredSettings->SetAutoBreadcrumbsEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON);
pDredSettings->SetPageFaultEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON);

注意

對DRED設定的修改不會影響已建立的裝置。 但後續對 D3D12CreateDevice呼叫會使用最新的DRED設定。

存取程式代碼中的DRED數據

偵測到裝置移除之後(例如,Present傳回DXGI_ERROR_DEVICE_REMOVED),請使用ID3D12DeviceRemovedExtendedData 介面的方法來存取已移除裝置的DRED資料。

若要擷取 ID3D12DeviceRemovedExtendedData 介面,請在 ID3D12Device (或衍生) 介面上呼叫 QueryInterface,傳遞 ID3D12DeviceRemovedExtendedData介面標識符 (IID)。

void MyDeviceRemovedHandler(ID3D12Device * pDevice)
{
    CComPtr<ID3D12DeviceRemovedExtendedData> pDred;
    VERIFY_SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&pDred)));
    D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT DredAutoBreadcrumbsOutput;
    D3D12_DRED_PAGE_FAULT_OUTPUT DredPageFaultOutput;
    VERIFY_SUCCEEDED(pDred->GetAutoBreadcrumbsOutput(&DredAutoBreadcrumbsOutput));
    VERIFY_SUCCEEDED(pDred->GetPageFaultAllocationOutput(&DredPageFaultOutput));
    // Custom processing of DRED data can be done here.
    // Produce telemetry...
    // Log information to console...
    // break into a debugger...
}

對DRED的調試程式存取

調試程式可以透過 d3d12 存取DRED資料!D3D12DeviceRemovedExtendedData 數據導出。

針對 WinDbg 使用者,請參閱 WinDBG 延伸模組的 DirectX-Debug-Tools GitHub 存放庫,讓您更容易偵錯 Direct3D 12 DRED 狀態。

DRED 遙測

您的應用程式可以使用DRED API來控制DRED功能,以及收集遙測來協助分析問題。 這可讓您更廣泛的網路來捕捉那些難以重現的 TDR。

從 Windows 10 版本 1903 開始,所有使用者模式裝置移除的事件都會回報給 Windows 錯誤報告 (WER),也稱為 Watson。 如果應用程式、GPU 和顯示驅動程式的特定組合產生足夠的裝置移除事件,則DRED可能會暫時為客戶在類似的設定上啟動相同的應用程式。

DRED 的詳細資訊