我们非常激动地宣布 HIP RT v2.1 发布。在本篇博文中,我们将讨论新的功能和相应的 API 更改。
批量构建
在之前的版本中,底部几何体是逐个构建的,这对于大量小型几何体来说可能效率低下。我们引入了针对小型几何体的批量构建功能,允许我们在一次内核启动中高效地构建许多小型几何体。我们添加了以下函数:
hiprtError hiprtCreateGeometries(...);hiprtError hiprtDestroyGeometries(...);hiprtError hiprtBuildGeometries(...);hiprtError hiprtGetGeometriesBuildTemporaryBufferSize(...);这些函数执行与相应的单几何体变体相同的操作,一次处理多个几何体。例如,hiprtCreateGeometries 接受多个构建输入,通过一次 malloc 调用高效地创建多个几何体。同样,hiprtDestroyGeometries 一次销毁多个几何体。对于构建本身,hiprtBuildGeometries 接受多个构建输入并一次构建多个几何体。小型几何体(最多 512 个几何图元)将在一次内核启动中构建,而较大的几何体将使用指定的质量构建进行逐个处理。请注意,HIP RT 内部会分离小型和大型几何体,因此用户无需显式进行此操作。小型几何体的最大大小(即图元数量小于或等于此值的几何体将通过批量构建进行处理)可以在构建选项中指定。
struct hiprtBuildOptions{ hiprtBuildFlags buildFlags; u32 batchBuildMaxPrimCount;};如果 batchBuildMaxPrimCount == 0,则禁用批量构建,所有几何体将按顺序处理。需要注意的是,批量构建内部使用修改版的快速构建,这可能会对加速结构和光线追踪性能的质量产生轻微的负面影响。尽管如此,我们认为这种负面影响微不足道,因为几何体非常小。
全局和动态堆栈
全局堆栈有效地结合了共享内存和全局内存。虽然共享缓冲区分配相对简单,但确定全局缓冲区的大小却相当复杂。我们决定更改 API 以使分配更加用户友好。我们引入了两个新的结构来表示这两种缓冲区类型:
struct hiprtGlobalStackBuffer{ u32 stackSize; u32 stackCount; void* stackData;};
struct hiprtSharedStackBuffer{ u32 stackSize; void* stackData;};这两个结构都封装了缓冲区地址和堆栈大小。全局缓冲区堆栈还有一个堆栈计数,定义了我们需要的堆栈数量(通常每个计划的线程一个)。全局缓冲区可以通过以下函数创建/销毁:
hiprtError hiprtCreateGlobalStackBuffer(hiprtContext context, const hiprtGlobalStackBufferInput& input, hiprtGlobalStackBuffer* stackBufferOut);
hiprtError hiprtDestroyGlobalStackBuffer(hiprtContext context, hiprtGlobalStackBuffer stackBuffer);
struct hiprtGlobalStackBufferInput{ hiprtStackType type = hiprtStackTypeGlobal; u32 stackSize; u32 threadCount;};除了类型(我们将在下文讨论)之外,我们仅定义了堆栈大小和计划线程的数量。在分配了这两个缓冲区后,我们最终可以创建一个堆栈对象:
hiprtGlobalStackBuffer globalStackBuffer = ...;hiprtSharedStackBuffer sharedStackBuffer = ...;hiprtGlobalStack stack(globalStackBuffer, sharedStackBuffer);全局堆栈缓冲区包含所有计划线程的堆栈,这可能是一种浪费,因为只有一小部分线程正在并发执行。我们引入了动态堆栈,该堆栈仅为活动线程分配堆栈,并在需要时动态地将堆栈分配给线程。HIP RT 在堆栈构造函数中内部处理整个过程。动态堆栈的创建方式与全局堆栈相同;我们需要将 hiprtGlobalStackBufferInput 中的类型更改为 hiprtStackTypeDynamic(我们无需设置 threadCount):
hiprtDynamicStack stack(globalStackBuffer, sharedStackBuffer);当然,这会带来一些额外的开销,略微增加寄存器使用量。我们为内存有限的系统提供了动态堆栈选项。
变换查询函数
对于某些着色计算,我们需要从/到对象空间进行变换。我们可以将这些变换显式地存储在单独的缓冲区中,但这很浪费,因为 hiprtScene 已经包含了变换数据。我们提供了允许从场景对象查询这些变换的函数:
hiprtFrameSRT hiprtGetObjectToWorldFrameSRT(hiprtScene scene, u32 instanceID, float time);hiprtFrameSRT hiprtGetWorldToObjectFrameSRT(hiprtScene scene, u32 instanceID, float time);hiprtFrameMatrix hiprtGetObjectToWorldFrameMatrix(hiprtScene scene, u32 instanceID, float time);hiprtFrameMatrix hiprtGetWorldToObjectFrameMatrix(hiprtScene scene, u32 instanceID, float time);请注意,这些函数接受时间参数。这对于运动模糊尤其有用,因为 HIP RT 内部可以正确地插值变换。
其他功能
- 我们优化了 Orochi 中的基数排序。这提高了快速构建和平衡构建的速度(这两种构建都依赖于基数排序)。
- 我们在顶级场景对象中使用了更紧密的变换实例框,从而提高了光线追踪性能。
- 我们修复了几何体 IO 函数(
hiprtSaveGeometry和hiprtLoadGeometry)。请注意,场景 IO 函数仍然无法正常工作。 - 我们在
hiprtBuildTraceKernels和hiprtBuildTraceKernelsFromBitcode中添加了一个选项来启用/禁用编译后的追踪内核的缓存。
立即下载
HIP RT v2.1 的下载链接可在 HIP RT 页面上找到。
如果您正在寻找有关开始使用 HIPRT 的指南,请查看 HIP RT SDK 教程存储库和 HIP RT 文档页面。