使用 DRED 诊断 GPU 故障

DRED 表示设备删除扩展数据。 DRED 是一组不断发展的诊断功能,专门用于帮助确定意外设备删除错误的原因。 在支持必要功能(如下面的定义所示)的硬件上,DRED 传送自动痕迹导航以及 GPU 页面错误报告。

自动痕迹导航

在设置自动导航的场景前,我们先介绍手动差异。 预测超时检测和恢复 (TDR) 的可能情况时,可以使用 ID3D12GraphicsCommandList2::WriteBufferImmediate 方法将痕迹导航置于 GPU 命令流中,来跟踪 GPU 进度。

若要创建自定义低开销实现,这是一种合理的方法。 但是它可能会缺少标准化解决方案的部分功能,例如调试器扩展,或通过 Windows 错误报告 (WER)(又称为 Watson)报告。

因此,自动痕迹导航调用 WriteBufferImmediate 来将进度计数器置于 GPU 命令流中。 DRED 在每个 呈现操作之后插入痕迹导航,这意味着导致 GPU 工作的每个操作 (例如 绘制调度复制解析等) 。 若在运行 GPU 工作负载期间删除了设备,DRED 痕迹导航值实质上是在发生错误前完成的呈现器运行的集合。

痕迹导航历史记录环形缓冲区最多保留给定命令列表中 64KB 的运行。 如果命令列表中的操作数超过 65536 个,则仅存储最后 64KiB 操作-首先覆盖最早的操作。 但是,痕迹导航计数器值继续计数,最高计数为 UINT_MAX。 因此,最后的运行索引 =(痕迹导航计数 - 1)% 65536。

Windows 10 版本 1809(Windows 10 2018 年 10 月更新)首次发布了 DRED 1.0,并且它公开了初步的自动痕迹导航。 但是,它没有 API,启用 DRED 1.0 的唯一方法是使用反馈中心捕获 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 接口,请在 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!D3D12DeviceRemovedExtendedData 数据导出访问 DRED 数据。

对于 WinDbg 用户,请参阅 DirectX-Debugging-Tools GitHub 存储库,了解 WinDBG 扩展,以便更轻松地调试 Direct3D 12 DRED 状态。

DRED 遥测

应用程序可以使用 DRED API 控制 DRED 功能,并收集遥测来帮助分析问题。 这样即可从更广阔的范围捕捉这些难以重现的 TDR。

自 Windows 10 版本 1903 起,将所有用户模式设备删除事件上报给 Windows 错误报告 (WER)(又称为 Watson)。 若特定应用程序组合、GPU 和显示驱动程序引发了大量设备删除事件,则可能会为在相似配置上启动同个应用程序的客户暂时启用 DRED。

有关 DRED 的详细信息