共用方式為


使用DRED診斷 GPU 錯誤

DRED 代表裝置移除擴展資料。 DRED 是一組不斷演進的診斷功能,旨在協助您找出非預期裝置移除錯誤的原因。 在支援必要功能的硬體上,DRED 會提供自動追溯路徑以及 GPU 頁面錯誤報告。

自動階層連結

為了介紹自動麵包屑,我們先提到手動版本。 為應對可能出現的 超時偵測與復原(TDR),您可以使用 ID3D12GraphicsCommandList2::WriteBufferImmediate 方法面包屑標記 放入 GPU 命令數據流,以追蹤 GPU 進度。

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

因此,DRED 的自動階層連結會呼叫 WriteBufferImmediate,將進度計數器放入 GPU 命令數據流中。 DRED 會在每個 渲染操作之後插入一個標記,這表示每項會產生 GPU 工作的操作(例如,繪製分派複製解決等等)。 如果裝置在 GPU 工作負載進行中被移除,那麼 DRED 階層連結值基本上就是錯誤發生前已完成的渲染操作集合。

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

DRED 1.0 首次在 Windows 10 版本 1809 中提供(Windows 10 2018 年 10 月更新),並公開了基本自動階層連結。 不過,沒有 API,啟用DRED 1.0的唯一方法是使用 意見反應中樞 來擷取 Apps & Games>遊戲效能和相容性的 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 會透過報告符合 GPU 回報頁面錯誤的虛擬位址(VA)的任何現有或最近釋放的 API 物件名稱和類型,來嘗試解決其中一些情況。

警告

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

性能

Direct3D 12 執行階段必須主動管理可以由虛擬位址 (VA) 索引的現有和最近刪除的 API 物件集合。 這會增加系統記憶體的負擔,並對物件的創建和銷毀造成輕微的效能損失。 因此,此行為預設是關閉的。

硬體需求

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

在程式代碼中設定DRED

DRED 設定是程式的全域設定,您必須在建立 Direct3D 12 裝置之前進行設定。 若要執行此操作,請呼叫 D3D12GetDebugInterface 函式以擷取 ID3D12DeviceRemovedExtendedDataSettings

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 介面,請呼叫 QueryInterfaceID3D12Device (或衍生的)介面上,傳遞 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 使用者,請參閱 DirectX-Debug-Tools WinDBG 延伸模組的 GitHub 存放庫,讓您更輕鬆地偵錯 Direct3D 12 DRED 狀態。

DRED 遙測

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

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

DRED 的詳細資訊