使用 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 页面错误通常在下列情况之一下发生。
- 应用程序在 GPU 上错误地执行了应用已删除的对象的作业。 这是意外删除设备的主要原因之一。
- 应用程序错误地在 GPU 上执行了访问已逐出的资源或非驻留磁贴的作业。
- 着色器引用未初始化的或过时的描述符。
- 着色器索引超出根绑定末尾。
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。