内容创建/渲染

驱动程序级别的光线追踪验证

对于使用 Microsoft DirectX 光线追踪应用程序的开发者而言,光线追踪验证可帮助您提高性能、发现难以调试的问题和崩溃的根本原因。

与现有调试解决方案不同,光线追踪验证会在驱动程序级别执行检查,从而识别 D3D12 调试层等工具无法发现的潜在问题。警告和错误通过回调直接从驱动程序发送到应用程序,并通过现有的应用程序端调试或日志记录系统进行处理。

强烈建议您在任何功能开发和功能测试期间尽可能启用光线追踪验证。

要求

光线追踪验证需要 NVIDIA 驱动 551.61 及更高版本,以及 NVIDIA API(NvAPI)。

介于 545.00 和 551.61 之间的驱动程序版本也支持光线追踪验证。但是,在这些早期版本中,验证速度可能会非常缓慢,令人望而却步。我们建议升级到驱动程序 551.61 或更高版本。

启用光线追踪验证

要启用光线追踪验证,请将NV_ALLOW_RAYTRACING_VALIDATION=1环境变量。

接下来,开发人员可以创建一个 Direct3D 12 设备,然后初始化 NVIDIA 图形 API (NVAPI)

在此设备上启用光线追踪验证,NvAPI_D3D12_EnableRaytracingValidation功能。

自定义NVAPI_D3D12_RAYTRACING_VALIDATION_MESSAGE_CALLBACK将函数输出到您选择的调试器或日志记录系统,然后将其注册为NvAPI_D3D12_RegisterRaytracingValidationMessageCallback

在收到围栏信号后或在设备移除处理程序中NvAPI_D3D12_FlushRaytracingValidationMessages

性能优化

运行具有光线追踪验证的应用程序会产生一定的性能成本。因此,应用程序不应该在启用光线追踪验证的情况下运行。NV_ALLOW_RAYTRACING_VALIDATION=1environment 变量可以防止最终用户意外遇到任何性能下降。

NvAPI_D3D12_FlushRaytracingValidationMessages对于调用时已在 GPU 上完成的工作,请向注册的回调报告任何验证消息。这使您能够控制报告消息的粒度。至关重要的是,即使在设备移除错误之后,显式刷新也能处理验证消息。

应用示例

以下代码示例展示了如何使用 NvAPI 在应用中启用和使用光线追踪验证:

// Validation callback
static void __stdcall myValidationMessageCallback(void* pUserData, NVAPI_D3D12_RAYTRACING_VALIDATION_MESSAGE_SEVERITY severity, const char* messageCode, const char* message, const char* messageDetails)
{
          const char* severityString = "unknown";
          switch (severity)
          {
          case NVAPI_D3D12_RAYTRACING_VALIDATION_MESSAGE_SEVERITY_ERROR: severityString = "error"; break;
          case NVAPI_D3D12_RAYTRACING_VALIDATION_MESSAGE_SEVERITY_WARNING: severityString = "warning"; break;
          }
          fprintf(stderr, "Ray Tracing Validation message: %s: [%s] %s\n%s", severityString, messageCode, message, messageDetails);
          fflush(stderr);
}
 
// Enable Ray Tracing Validation
void onCreate()
{
          NvAPI_Initialize();
          ID3D12Device* device = MyCreateD3DDevice();
          if (validationMode) {
                    NvAPI_D3D12_EnableRaytracingValidation(device, NVAPI_D3D12_RAYTRACING_VALIDATION_FLAG_NONE);
                    NvAPI_D3D12_RegisterRaytracingValidationMessageCallback(device, &myValidationMessageCallback, (void*)&myCallbackData, &nvapiValidationCallbackHandle);
          }
}
 
// Flush the validation message after a fence signal
void waitForGPU(UINT64 fenceValue)
{
          fence->SetEventOnCompletion(fenceValue, fenceEvent);
          WaitForSingleObjectEx(fenceEvent, INFINITE, FALSE);
          if (validationMode)
                    NvAPI_D3D12_FlushRaytracingValidationMessages(device);
}
 
// We highly recommend checking for DXGI_ERROR_DEVICE_REMOVED and flushing the validation message if this occurs
void onDeviceRemoved()
{
          // flushing after DXGI_ERROR_DEVICE_REMOVED is OK
          if (validationMode)
                 NvAPI_D3D12_FlushRaytracingValidationMessages(device);
}

正在验证的内容是什么?

光线追踪验证报告系统中发生的某些错误条件DispatchRaysBuildRaytracingAccelerationStructure会导致难以调试的错误或损坏。

例如,应用程序可能会为下一帧构建新的光线追踪工作流,并更新当前帧仍在使用的着色器绑定表 (SBT).这可能会导致当前帧中 SBT 中缺少条目的潜在错误。光线追踪验证报告UNKNOWN_ENTRY_FUNCTION错误以及特定于错误的详细信息,指导您找到错误的根本原因。

验证检查DispatchRays包括以下内容:

  • 意外的 SBT 记录着色器类型,例如在预期命中组时遇到错过着色器条目。
  • SBT 引用了不属于管线的着色器。
  • 越界 SBT 条目。
  • 着色器负载类型不匹配,当调用的着色器期望的类型不同于传递给TraceRay
  • 已超过最大追踪深度。
  • 堆栈溢出。

验证检查BuildRaytracingAccelerationStructure包括以下内容:

  • 针对低效加速结构的性能警告。
  • 在可重新拟合的底层 AS 中使用过度的生三角形。这可能会导致性能不佳。
  • 坏顶点数据,例如 NaN 和大数。
  • 条件不佳的几何图形或实例转换。
  • 用于改装、复制或 TLAS 构建的源加速结构不完整。在 AS 操作之间正确同步时,可能存在应用端问题。
  • 顶点、OMM 或 DMM 输入索引越界检查。
  • 更改了 AS build 和 refit 之间的标志。

输出示例

在发布时,以下是驱动验证输出的几个示例。驱动捕获的错误将随着时间的推移而演变和增长。

error: [UNKNOWN_ENTRY_FUNCTION] attempted to execute a shader that is not part of the pipeline
	launch index: [451, 309, 0]
	additional occurrences: 12
	SBT byte offset (if applicable): 1088
	SBT range: likely hitgroup/raygen/callable

error: [UNEXPECTED_SHADER_TYPE] encountered a shader-binding-table record with unexpected shader type
	launch index: [0, 0, 0]
	additional occurrences: 10737
	type: hitgroup
	expected: miss
	SBT byte offset: 64
	SBT GPUVA: 0xb2841c0

error: [HIT_SBT_OUT_OF_BOUNDS] encountered an out-of-bounds access in the shader binding table when accessing a hitgroup record
	launch index: [826, 122, 0]
	additional occurrences: 1067
	SBT byte offset: 7040
	SBT byte size: 6528
	SBT index: 110
	instance SBT base index: 108

warning: [EXCESSIVE_DEGENERATE_PRIMITIVES] Acceleration structure has a significant portion of degenerated primitives, which can lead to poor performance.

性能

启用光线追踪验证会产生性能成本。但是,此成本通常很低,尤其是在未检测到错误时。对于日常功能开发和调试而言,性能影响应该是可以接受的。正如前面提到的,应用程序不应启用验证模式。

在最近针对大量基准测试进行的测试中,我们观察到,在未触发任何错误的情况下,性能影响平均约为 3%的帧时间。对于确实触发错误的基准测试,性能开销在 3%到 40%之间。

光线追踪验证不会影响计算或像素着色器中基于光线查询的光线追踪。

结束语

光线追踪验证是一种功能强大的工具,用于调试棘手的崩溃和提高光线追踪性能。启用该验证所需的更改小巧而简单。

如果您正在开发光线追踪应用,请立即考虑将其添加到您的开发生态系统中。有关更多信息,请参阅光线追踪论坛

 

Tags