VK_KHR_acceleration_structure¶
更新记录
2023/6/13 创建该文档
2023/6/13 将
Vulkan KHR 光线追踪标准中的VK_KHR_acceleration_structure内容摘录于此2023/6/13 更新
拷贝加速结构章节2023/6/13 增加
vkCmdWriteAccelerationStructuresPropertiesKHR章节2023/6/14 更新
vkCmdWriteAccelerationStructuresPropertiesKHR章节2023/6/14 增加
vkCmdCopyAccelerationStructureKHR章节2023/6/14 增加
VkCopyAccelerationStructureInfoKHR章节2023/6/14 增加
vkCmdCopyAccelerationStructureToMemoryKHR章节2023/6/15 更新
vkCmdCopyAccelerationStructureToMemoryKHR章节2023/6/15 修改
获取64位加速结构设备地址章节顺序2023/6/15 增加
VkCopyAccelerationStructureToMemoryInfoKHR章节2023/6/15 增加
vkGetDeviceAccelerationStructureCompatibilityKHR章节2023/6/15 增加
VkAccelerationStructureVersionInfoKHR章节2023/6/15 增加
VkAccelerationStructureCompatibilityKHR章节2023/6/15 修改
销毁加速结构章节顺序2023/6/15 增加
加速结构的 Host 端操作章节2023/6/19 更新
加速结构的 Host 端操作章节2023/6/19 增加
vkBuildAccelerationStructuresKHR章节2023/6/19 增加
vkCopyAccelerationStructureKHR章节2023/6/19 增加
vkCopyAccelerationStructureToMemoryKHR章节2023/6/19 增加
vkWriteAccelerationStructuresPropertiesKHR章节2023/6/21 修改
VK_KHR_device_group_creation将device扩展修改成instance扩展
加速结构的创建和构建
加速结构中经常能看到 创建 和 构建 的字样,这是两个不同的概念。加速结构的创建指的是创建加速结构句柄 VkAccelerationStructureKHR ,在创建时可以不指定其内部的具体数据,可以先创建。对于加速结构的构建指的是构建加速结构内部真正的数据和结构,具体内部结构是什么形式的是驱动内部自定义的(一种可能的结构为 BVH )。
该扩展属于 device扩展。
依赖如下
Vulkan 1.1
- VK_EXT_descriptor_indexing device扩展 在Vulkan 1.2中被纳入核心 依赖如下
VK_KHR_get_physical_device_properties2 instance扩展 在Vulkan 1.1中被纳入核心
- VK_KHR_maintenance3 device扩展 在Vulkan 1.1中被纳入核心 依赖如下
VK_KHR_get_physical_device_properties2 instance扩展 在Vulkan 1.1中被纳入核心
- VK_KHR_buffer_device_address device扩展 在Vulkan 1.2中被纳入核心 依赖如下
VK_KHR_get_physical_device_properties2 instance扩展 在Vulkan 1.1中被纳入核心
- VK_KHR_device_group device扩展 在Vulkan 1.1中被纳入核心 依赖如下
VK_KHR_device_group_creation instance扩展 在Vulkan 1.1中被纳入核心
VK_KHR_deferred_host_operations device扩展
新添加的对象类型(句柄):
新添加的函数:
查看是否支持加速结构特性¶
如果使用 Vulkan 1.1 标准,可以通过调用 vkGetPhysicalDeviceFeatures2 获取加速结构特性相关信息。
// 由 Vulkan 1.1 提供
void vkGetPhysicalDeviceFeatures2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2* pFeatures);
如果激活了 VK_KHR_get_physical_device_properties2 扩展,可以通过 vkGetPhysicalDeviceFeatures2KHR 获取。
// 由 VK_KHR_get_physical_device_properties2 提供
void vkGetPhysicalDeviceFeatures2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2* pFeatures);
对于获取设备是否支持加速结构特性,是通过将 VkPhysicalDeviceAccelerationStructureFeaturesKHR 的指针包含在 VkPhysicalDeviceFeatures2::pNext 指针链中。
// 由 Vulkan 1.1 提供
typedef struct VkPhysicalDeviceFeatures2 {
VkStructureType sType;
void* pNext;
VkPhysicalDeviceFeatures features;
} VkPhysicalDeviceFeatures2;
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkPhysicalDeviceAccelerationStructureFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 accelerationStructure;
VkBool32 accelerationStructureCaptureReplay;
VkBool32 accelerationStructureIndirectBuild;
VkBool32 accelerationStructureHostCommands;
VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind;
} VkPhysicalDeviceAccelerationStructureFeaturesKHR;
accelerationStructure 描述设备是否支持加速结构特性。
accelerationStructureCaptureReplay 描述设备是否支持保存和重复使用加速结构的设备地址。比如用于追踪捕获和回放。
accelerationStructureIndirectBuild 描述设备是否支持间接加速结构构建指令。比如
vkCmdBuildAccelerationStructuresIndirectKHR。accelerationStructureHostCommands 描述设备是否支持
Host端(CPU)的加速结构相关指令函数。比如vkBuildAccelerationStructuresKHR,vkCopyAccelerationStructureKHR,vkCopyAccelerationStructureToMemoryKHR,vkCopyMemoryToAccelerationStructureKHR,vkWriteAccelerationStructuresPropertiesKHR。descriptorBindingAccelerationStructureUpdateAfterBind 描述设备是否支持在描述符集中已经绑定加速结构之后对加速结构进行更新。如果该特性不支持,
VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT将不能与VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR一起使用。
host 端还是 device 端
host 端一般指 CPU 。 device 端一般指 GPU 。
例程¶
备注
需要开启 VK_KHR_get_physical_device_properties2 扩展
VkPhysicalDevice vk_physical_device = /*某个精挑细选的物理设备*/;
VkPhysicalDeviceAccelerationStructureFeaturesKHR vk_physical_device_acceleration_structure_features_khr = {};
vk_physical_device_acceleration_structure_features_khr.sType = VkStructureType::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
vk_physical_device_acceleration_structure_features_khr.pNext = nullptr;
vk_physical_device_acceleration_structure_features_khr.accelerationStructure = VK_FALSE;
vk_physical_device_acceleration_structure_features_khr.accelerationStructureCaptureReplay = VK_FALSE;
vk_physical_device_acceleration_structure_features_khr.accelerationStructureIndirectBuild = VK_FALSE;
vk_physical_device_acceleration_structure_features_khr.accelerationStructureHostCommands = VK_FALSE;
vk_physical_device_acceleration_structure_features_khr.descriptorBindingAccelerationStructureUpdateAfterBind = VK_FALSE;
VkPhysicalDeviceFeatures2 vk_physical_device_features_2;
vk_physical_device_features_2.sType = VkStructureType::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
vk_physical_device_features_2.pNext = &vk_physical_device_acceleration_structure_features_khr;
vk_physical_device_features_2.features = {};
vkGetPhysicalDeviceFeatures2KHR(vk_physical_device, &vk_physical_device_features_2);
激活加速结构特性¶
在创建 VkDevice 时需要将要开启的特性加入到 VkDeviceCreateInfo::pNext 指针链中。
例程¶
VkPhysicalDevice vk_physical_device = /*某个精挑细选的物理设备*/;
VkPhysicalDeviceAccelerationStructureFeaturesKHR vk_physical_device_acceleration_structure_features_khr = /*之前通过vkGetPhysicalDeviceFeatures2KHR获取到的加速结构特性信息*/;
VkDeviceCreateInfo vk_device_create_info = {};
vk_device_create_info.sType = VkStructureType::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
vk_device_create_info.pNext = &vk_physical_device_acceleration_structure_features_khr;
vk_device_create_info. ...
VkDevice vk_device = VK_NULL_HANDLE;
VkResult result = vkCreateDevice(vk_physical_device, &vk_device_create_info, &vk_device);
if (result != VK_SUCCESS)
{
/*创建失败*/
}
获取缓存的设备地址¶
vkGetBufferDeviceAddress¶
为了使得着色器可以访问缓存我们需要获取缓存的设备地址,调用如下:
// 由 VK_VERSION_1_2 提供
VkDeviceAddress vkGetBufferDeviceAddress(
VkDevice device,
const VkBufferDeviceAddressInfo* pInfo);
或者与之相等的函数:
vkGetBufferDeviceAddressKHR¶
// 由 VK_KHR_buffer_device_address 提供
VkDeviceAddress vkGetBufferDeviceAddressKHR(
VkDevice device,
const VkBufferDeviceAddressInfo* pInfo);
device 创建缓存的逻辑设备。
pInfo 指向
VkBufferDeviceAddressInfo结构体指针,内部指定了要获取的目标缓存。
VkBufferDeviceAddressInfo¶
VkBufferDeviceAddressInfo 定义如下:
// 由 VK_VERSION_1_2 提供
typedef struct VkBufferDeviceAddressInfo {
VkStructureType sType;
const void* pNext;
VkBuffer buffer;
} VkBufferDeviceAddressInfo;
或者与之相等的声明:
VkBufferDeviceAddressInfoKHR¶
// 由 VK_KHR_buffer_device_address 提供
typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR;
正确用法
buffer必须使用VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT创建。
加速结构¶
加速结构是设备驱动用于光线遍历并管理场景几何体的数据结构。应用的职责是管理加速结构,包括创建、销毁、构建和更新,并在光线查询期间同步资源。
加速结构有两种:
顶层加速结构(
top level acceleration structures)底层加速结构(
bottom level acceleration structures)
一个加速结构被构建的标志是对于一个目标加速结构执行了加速结构构建指令或拷贝指令。
加速结构¶
如图为顶层加速结构和底层加速结构的关系图。
几何体¶
几何体指的是三角形或轴对齐包围盒。
轴对齐包围盒
也叫 AABB ( Axis Aligned Bounding Box )包围盒。
顶层加速结构¶
代表实体( instances )的集合。描述符或设备地址将顶层加速结构作为遍历的起点。
顶层加速结构通过实体可以引用任意的底层加速结构。当顶层加速结构访问底层加速结构时底层加速结构必须保持有效。
底层加速结构¶
用于表示几何体集合
加速结构的更新规则¶
Vulkan API 提供两种方式从几何体中生成加速结构:
构建操作 用于构建一个加速结构
更新操作 用于修改一个已经存在的加速结构
更新操作为了执行的更快更有效率在输入方面施加了一些限制。在进行更新时,应用需要提供对于加速结构完整的描述,除了实体的定义、变换矩阵、顶点和 AABB 的位置可以改变,其他的禁止发生改变并与之前的构建描述相匹配。
更明确的说,应用禁止在更新时做如下操作:
将图元或实体从有效转成无效,反之亦然。
更改三角形几何体的索引和顶点格式
将三角形几何体的变换指针从空变成非空,反之亦然。
改变加速结构中几何体或实体的数量。
改变加速结构中几何体的标志位域(
flags)。改变加速结构中几何体的顶点数量或图元数量。
无效的图元和实体¶
加速结构允许使用一个特定的输入值表示无效的图元或实体。
当三角形的每个顶点的第一个( X )分量为 NaN 时即为一个无效三角形。如果顶点的其他分量为 NaN 但是第一个分量不为 NaN 时其行为是未定义的。如果顶点格式中不存在 NaN 的话,则所有的三角形都认为是有效的。
当一个实体引用的加速结构为 0 时被认为是无效。
当 AABB 的最小 X 坐标为 NaN 时被认为是无效,如果其他的部分为 NaN 而第一个不是 NaN 的话其行为是未定义的。
在如上定义中 NaN 可以是任意类型的 NaN ,比如有符号的。无符号的、安静的、吵闹的或是其他种种。
安静的、吵闹的
安静的 NaN ,大概率是指 IEEE 754-2008 标准中定义的 Quiet NaN 。是指尾数最高位为 1 的 NaN 值。
吵闹的 NaN ,大概率是指 IEEE 754-2008 标准中定义的 Signaling NaN 。是指尾数最高位为 0 ,其余低位不全为 0 的 NaN 值。
一个无效对象对于所有的光线都被认为是不可见的,并且不应该出现在加速结构中。驱动应确保无效对象的存在不会严重降低遍历性能。
无效对象使用一个自然增涨的索引值计数,在 SPIR-V 是通过 InstanceId 和 PrimitiveId 体现出来。这允许场景中的对象在有效与无效之间自由的变换。不影响使用 ID 值进行索引的任何数组的布局。
对于任何有效与无效状态的转换都需要进行一个完整的加速结构重构建。如果拷贝源加速结构中有效的对象在目标加速结构中变成无效对象,反之亦然,则应用不能执行加速结构的更新。
加速结构的描述¶
所有的加速结构都通过 VkAccelerationStructureBuildGeometryInfoKHR 进行描述:
VkAccelerationStructureBuildGeometryInfoKHR¶
VkAccelerationStructureBuildGeometryInfoKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureBuildGeometryInfoKHR {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureTypeKHR type;
VkBuildAccelerationStructureFlagsKHR flags;
VkBuildAccelerationStructureModeKHR mode;
VkAccelerationStructureKHR srcAccelerationStructure;
VkAccelerationStructureKHR dstAccelerationStructure;
uint32_t geometryCount;
const VkAccelerationStructureGeometryKHR* pGeometries;
const VkAccelerationStructureGeometryKHR* const* ppGeometries;
VkDeviceOrHostAddressKHR scratchData;
} VkAccelerationStructureBuildGeometryInfoKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。type 用于设置加速结构的构建类型。
flags 用于指定的加速结构的额外参数。
mode 用于设置要进行的操作类型。
srcAccelerationStructure 是用于当
mode为VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR时其指向一个已经存在的加速结构,用于更新到dst加速结构中 。dstAccelerationStructure 指向一个用于构建的目标加速结构。
geometryCount 表示要构建进入到
dstAccelerationStructure的几何数量。pGeometries 指向数量为
geometryCount类型为VkAccelerationStructureGeometryKHR结构体数组。ppGeometries 指向数量为
geometryCount类型为VkAccelerationStructureGeometryKHR结构体 指针 数组。scratchData 是
device或host端用于构建时暂付缓存的内存地址。
暂付缓存
暂付缓存( scratch buffer ),是 Vulkan 对于内部缓存的优化。原本的内部缓存应由 Vulkan 驱动内部自身分配和管理,但是有些内部内存会经常性的更新,为了优化这一部分缓存, Vulkan 将这一部分
缓存交由用户分配管理,优化了内存使用和读写。 scratch 原本是抓挠之意,由于这部分内存时不时的要更新一下,像猫抓一样,所以叫 抓挠 缓存,实则是暂时交付给 Vulkan 驱动内部。
只有 pGeometries 或者 ppGeometries 其中之一可以设置有效指针,另外一个必须是 NULL 。有效指针所对应的数组用于描述构建加速结构的几何数据。
pGeometries或者ppGeometries对应的每一个元素的索引将会作为光线遍历的几何索引。该几何索引可在光追着色器中通过内置的RayGeometryIndexKHR访问,并且用于在光线遍历时确定运行哪一个最近命中着色器和相交着色器。 该几何索引可以通过OpRayQueryGetIntersectionGeometryIndexKHR指令进行光线查询。
当 mode 是 VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR 时 srcAccelerationStructure 和 dstAccelerationStructure 对于此更新操作也许是相同的或是不同的。如果是相同的,其本身将会更新,否则。目标加速结构将会更新而不会修改源加速结构。
正确用法
只有
pGeometries或者ppGeometries其中之一可以设置有效指针,另外一个必须是NULL。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,则pGeometries或ppGeometries数组的geometryType必须是VK_GEOMETRY_TYPE_INSTANCES_KHR。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,则geometryCount只能是1。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,则pGeometries或ppGeometries数组的geometryType必须不能是VK_GEOMETRY_TYPE_INSTANCES_KHR。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,则pGeometries或ppGeometries数组的geometryType必须相同 。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,则geometryCount必须小于等于VkPhysicalDeviceAccelerationStructurePropertiesKHR::maxGeometryCount。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,则pGeometries或ppGeometries数组的geometryType是VK_GEOMETRY_TYPE_AABBS_KHR的话,所有数量的AABB对应的所有几何体必须小于等于VkPhysicalDeviceAccelerationStructurePropertiesKHR::maxPrimitiveCount。如果
type是VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,则pGeometries或ppGeometries数组的geometryType是VK_GEOMETRY_TYPE_TRIANGLES_KHR的话,所有数量的三角形对应的所有几何体必须小于等于VkPhysicalDeviceAccelerationStructurePropertiesKHR::maxPrimitiveCount。如果
flags包含VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR位域 ,就不能再包含VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR位域了。
VkBuildAccelerationStructureFlagBitsKHR¶
VkAccelerationStructureBuildGeometryInfoKHR::flags 可以设置的值如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkBuildAccelerationStructureFlagBitsKHR {
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002,
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004,
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008,
VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, // 由 VK_KHR_ray_tracing_position_fetch 提供
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR = 0x00000800,
} VkBuildAccelerationStructureFlagBitsKHR;
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR 表示可以更新
mode为VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR的加速结构。VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR 表示可以作为
mode为VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR加速结构拷贝指令的数据源进行压缩。VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR 表示在构建加速结构时优先考虑优化光追性能。
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR 表示在构建加速结构时优先考虑优化构建时长。
VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR 表示最小化加速结构的暂付缓存,这背后可能会增加构建时长和光追性能。
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR 表示当光线击中三角形获取顶点位置时可以使用该加速结构。
备注
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR 和 VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR 的设置可能会比正常创建花费更多的时间,并且应该在有相应需求时使用这两个特性。
VkBuildAccelerationStructureModeKHR¶
VkBuildAccelerationStructureModeKHR 枚举定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkBuildAccelerationStructureModeKHR {
VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR = 0,
VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1,
} VkBuildAccelerationStructureModeKHR;
VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR 表示目标加速结构将会使用用户提供的几何数据构建。
VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR 表示目标加速结构将会使用用户提供的源加速结构的几何数据进行更新。
VkDeviceOrHostAddressKHR¶
VkDeviceOrHostAddressKHR 定义的 union 联合体如下:
// 由 VK_KHR_acceleration_structure 提供
typedef union VkDeviceOrHostAddressKHR {
VkDeviceAddress deviceAddress;
void* hostAddress;
} VkDeviceOrHostAddressKHR;
备注
VkDeviceOrHostAddressKHR 是联合体 union 。
deviceAddress 表示通过
vkGetBufferDeviceAddressKHR获取到的设备缓存地址。hostAddress 表示
host端的内存地址。
VkDeviceOrHostAddressConstKHR¶
VkDeviceOrHostAddressConstKHR 定义的 union 联合体如下:
// 由 VK_KHR_acceleration_structure 提供
typedef union VkDeviceOrHostAddressConstKHR {
VkDeviceAddress deviceAddress;
const void* hostAddress;
} VkDeviceOrHostAddressConstKHR;
deviceAddress 表示通过
vkGetBufferDeviceAddressKHR获取到的设备缓存地址。hostAddress 表示
host端的内存地址。
备注
VkDeviceOrHostAddressConstKHR 是联合体 union 。比 VkDeviceOrHostAddressKHR 在命名上多了个 Const 。
VkAccelerationStructureGeometryKHR¶
VkAccelerationStructureGeometryKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureGeometryKHR {
VkStructureType sType;
const void* pNext;
VkGeometryTypeKHR geometryType;
VkAccelerationStructureGeometryDataKHR geometry;
VkGeometryFlagsKHR flags;
} VkAccelerationStructureGeometryKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。geometryType 描述几何类型。
geometry 为
VkAccelerationStructureGeometryDataKHR联合类型,描述geometryType对应的数据。flags 是
VkGeometryFlagBitsKHR值的位域,用于描述几何体如何构建的额外参数。
正确用法
目前
pNext必须为NULL。如果
geometryType为VK_GEOMETRY_TYPE_TRIANGLES_KHR的话,geometry的triangles成员必须是一个有效的VkAccelerationStructureGeometryTrianglesDataKHR结构数据。如果
geometryType为VK_GEOMETRY_TYPE_AABBS_KHR的话,geometry的aabbs成员必须是一个有效的VkAccelerationStructureGeometryAabbsDataKHR结构数据。如果
geometryType为VK_GEOMETRY_TYPE_INSTANCES_KHR的话,geometry的instances成员必须是一个有效的VkAccelerationStructureGeometryInstancesDataKHR结构数据。
VkGeometryTypeKHR¶
几何类型通过 VkGeometryTypeKHR 指定,其定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkGeometryTypeKHR {
VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0,
VK_GEOMETRY_TYPE_AABBS_KHR = 1,
VK_GEOMETRY_TYPE_INSTANCES_KHR = 2,
} VkGeometryTypeKHR;
VK_GEOMETRY_TYPE_TRIANGLES_KHR 表示几何类型由三角形组成。
VK_GEOMETRY_TYPE_AABBS_KHR 表示几何类型由轴对齐包围盒组成。
VK_GEOMETRY_TYPE_INSTANCES_KHR 表示几何类型由加速结构实体组成。
VkGeometryFlagBitsKHR¶
几何体在加速结构构架中额外参数:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkGeometryFlagBitsKHR {
VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001,
VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002,
} VkGeometryFlagBitsKHR;
VK_GEOMETRY_OPAQUE_BIT_KHR 表示就算追踪时产生了一个击中组该几何体也不会去调用任意命中着色器。
VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR 表示驱动对于几何体上的每一个图元只会调用一次任意命中着色器。如果该标志位域没有设置,驱动可能会对该结合体调用多次任意命中着色器。
VkAccelerationStructureGeometryDataKHR¶
VkAccelerationStructureGeometryDataKHR 定义的 union 联合体如下:
// 由 VK_KHR_acceleration_structure 提供
typedef union VkAccelerationStructureGeometryDataKHR {
VkAccelerationStructureGeometryTrianglesDataKHR triangles;
VkAccelerationStructureGeometryAabbsDataKHR aabbs;
VkAccelerationStructureGeometryInstancesDataKHR instances;
} VkAccelerationStructureGeometryDataKHR;
triangles 是
VkAccelerationStructureGeometryTrianglesDataKHR结构数据。aabbs 是
VkAccelerationStructureGeometryAabbsDataKHR结构数据。instances 是
VkAccelerationStructureGeometryInstancesDataKHR结构数据。
备注
VkAccelerationStructureGeometryDataKHR 是联合体 union 。
VkAccelerationStructureGeometryTrianglesDataKHR¶
VkAccelerationStructureGeometryTrianglesDataKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureGeometryTrianglesDataKHR {
VkStructureType sType;
const void* pNext;
VkFormat vertexFormat;
VkDeviceOrHostAddressConstKHR vertexData;
VkDeviceSize vertexStride;
uint32_t maxVertex;
VkIndexType indexType;
VkDeviceOrHostAddressConstKHR indexData;
VkDeviceOrHostAddressConstKHR transformData;
} VkAccelerationStructureGeometryTrianglesDataKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。vertexFormat 是顶点数据的格式。
vertexData 是
device或host端包含几何顶点数据的内存地址。maxVertex 是在使用该结构体构建加速结构时可以寻址的最高顶点数据索引。
vertexStride 点与点之间的比特跨度。
indexType 是索引的
VkIndexType类型。indexData 是包含索引数据的
device或host端内存地址。transformData 是包含一个用于描述该加速结构中几何体变换数据
VkTransformMatrixKHR的device或host端内存地址。该数据的设置是可选的。
备注
与图形管线 VkVertexInputBindingDescription 的顶端缓存跨度最大不能超过 maxVertexInputBindingStride 不同,加速结构几何体的 vertexStride 被限制在32位值中。
正确用法
vertexStride必须为vertexFormat最小分量比特的倍数 。vertexStride必须小于等于 \(2^{32}-1\) 。vertexFormat的格式特性必须包括VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR特性。
VkTransformMatrixKHR¶
VkTransformMatrixKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkTransformMatrixKHR {
float matrix[3][4];
} VkTransformMatrixKHR;
matrix 是 \(3\times4\) 行主式仿射变换矩阵 。
正确用法
matrix内部的 \(3\times3\) 矩阵必须是可逆矩阵。
VkAccelerationStructureGeometryAabbsDataKHR¶
VkAccelerationStructureGeometryAabbsDataKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureGeometryAabbsDataKHR {
VkStructureType sType;
const void* pNext;
VkDeviceOrHostAddressConstKHR data;
VkDeviceSize stride;
} VkAccelerationStructureGeometryAabbsDataKHR
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。data 是
device或host端包含位置数据的VkAabbPositionsKHR轴对齐包围盒数据内存地址。stride
data条目之间的比特跨度。并且必须是8的倍数。
正确用法
stride必须小于等于 \(2^{32}-1\) 。
VkAabbPositionsKHR¶
VkAabbPositionsKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAabbPositionsKHR {
float minX;
float minY;
float minZ;
float maxX;
float maxY;
float maxZ;
} VkAabbPositionsKHR;
minX 包围盒边界框对角的
x位置。minY 包围盒边界框对角的
y位置。minZ 包围盒边界框对角的
z位置。maxX 包围盒边界框另一对角的
x位置。maxY 包围盒边界框另一对角的
y位置。maxZ 包围盒边界框另一对角的
z位置。
正确用法
minX必须小于等于maxX。
minY必须小于等于maxY。
minZ必须小于等于maxZ。
VkAccelerationStructureGeometryInstancesDataKHR¶
VkAccelerationStructureGeometryInstancesDataKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureGeometryInstancesDataKHR {
VkStructureType sType;
const void* pNext;
VkBool32 arrayOfPointers;
VkDeviceOrHostAddressConstKHR data;
} VkAccelerationStructureGeometryInstancesDataKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。arrayOfPointers 用于指示
data是按照地址数组解析还是就是一个数组解析。data 如果
arrayOfPointers为VK_TRUE,该data用于单独的VkAccelerationStructureInstanceKHR引用device或host端数组,如果为VK_FALSE的话将会是VkAccelerationStructureInstanceKHR数组地址,并且VkAccelerationStructureInstanceKHR是紧密排布的。
加速结构实体 ( instances )可以构建进顶层加速结构中。每一个加速结构实体在包含所有底层加速结构的顶层加速结构中都是一个单独项。多个实体可以指向相同的底层加速结构。
加速结构实体
指的是 VkAccelerationStructureInstanceKHR 。一般在 Vulkan 光追标准中也叫 实体 ( instances )。
VkAccelerationStructureInstanceKHR¶
一个加速结构实体通过 VkAccelerationStructureInstanceKHR 定义:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureInstanceKHR {
VkTransformMatrixKHR transform;
uint32_t instanceCustomIndex:24;
uint32_t mask:8;
uint32_t instanceShaderBindingTableRecordOffset:24;
VkGeometryInstanceFlagsKHR flags:8;
uint64_t accelerationStructureReference;
} VkAccelerationStructureInstanceKHR;
transform 用于描述该实体的变换。
instanceCustomIndex 用户自定义的
24比特索引值。该值可通过光追着色器的内置变量InstanceCustomIndexKHR进行访问。mask 是一个
8比特可见性遮罩值。只有当Cull Mask & instance.mask != 0时实体才会被光线击中。instanceShaderBindingTableRecordOffset 是一个
24比特偏移值。用于计算命中着色器绑定表索引。flags 是一个
8比特VkGeometryInstanceFlagBitsKHR遮罩值引用在该实体上。- accelerationStructureReference 是一下两者之一。
从
vkGetAccelerationStructureDeviceAddressKHR获取到包含数据的device地址。将会被用于加速结构device操作中。一个
VkAccelerationStructureKHR对象。将会被用于设备加速结构host操作中。
C 语言标准的规范并没有定义位域的顺序,但是一般,对于现有编译器都会提供正确的结构体布局。这默认的位域模板如下:
instanceCustomIndex和mask将会一同占用一个uint32_t。instanceCustomIndex占用开头的24位mask占用之后的8位
instanceShaderBindingTableRecordOffset和flags将会一同占用一个uint32_t。instanceCustomIndex占用开头的24位mask占用之后的8位
如果编译器没有按照此方式进行结构体内存布局,应用需要根据如上模板使用其他方式设置数值。
VkGeometryInstanceFlagBitsKHR¶
VkAccelerationStructureInstanceKHR::flags 用于设置实体的行为位域值如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkGeometryInstanceFlagBitsKHR {
VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001,
VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004,
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR,
} VkGeometryInstanceFlagBitsKHR;
VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR 取消实体的面剔除。
VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR 表示确认哪一个是正面,与之前的判断策略相反。由于是使用物体空间(
object space)来判断正反面,在实体上的变换并不会影响判断结构,但是对于几何体的变换会影响判断结果。VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR 表示该实体下的所有几何体都被认为是
VK_GEOMETRY_OPAQUE_BIT_KHR,该行为可通过SPIR-V的NoOpaqueKHR光追标志位进行覆盖。VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR 表示该实体下的所有几何体都不被认为是
VK_GEOMETRY_OPAQUE_BIT_KHR,该行为可通过SPIR-V的NoOpaqueKHR光追标志位进行覆盖。
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR 和 VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR 这两个标志位域一定不能同时使用。
获取加速结构的构建大小¶
vkGetAccelerationStructureBuildSizesKHR¶
为了获取加速结构构建的大小,调用:
// 由 VK_KHR_acceleration_structure 提供
void vkGetAccelerationStructureBuildSizesKHR(
VkDevice device,
VkAccelerationStructureBuildTypeKHR buildType,
const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo,
const uint32_t* pMaxPrimitiveCounts,
VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo);
device 用于创建加速结构的逻辑设备句柄。
buildType 指定是使用
host端还是device端(或是两者兼得)上构建加速结构。pBuildInfo 描述构建的参数。
pMaxPrimitiveCounts 是指向类型为
uint32_t长度为pBuildInfo->geometryCount的数组指针。用于定义有多少图元构建进入每个几何体中。pSizeInfo 返回构建加速结构时需要的大小、暂付缓存的大小。
获取加速结构的构建大小
在获取加速结构要构建的大小时,主要是通过 VkAccelerationStructureBuildGeometryInfoKHR 描述加速结构,而不像 VkImage 和 VkBuffer 这类先创建资源句柄再获取资源要分配的大小。换而言之,加速结构在获取大小时不需要先创建完加速结构资源句柄后再获取大小。
在调用该函数时 pBuildInfo 的 srcAccelerationStructure 、 dstAccelerationStructure 和 mode 成员数据会被忽略。 pBuildInfo 中 VkDeviceOrHostAddressKHR scratchData 也将会被忽略,除非 VkAccelerationStructureGeometryTrianglesDataKHR::transformData 中的 hostAddress 成员是 NULL 。
使用该函数中的 VkAccelerationStructureBuildSizesInfoKHR 返回的 accelerationStructureSize 的大小创建加速结构,为了支持使用 VkAccelerationStructureBuildGeometryInfoKHR 和 VkAccelerationStructureBuildRangeInfoKHR 数组进行任意的构建和更新,构建和更新时需要依照如下规范:
构建指令是
host端,buildType需要是VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR或者VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR。构建指令是
device端,buildType需要是VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR或者VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR。- 对于
VkAccelerationStructureBuildGeometryInfoKHR: 其
type和flags成员需要分别与pBuildInfo->type和pBuildInfo->flags对应相等。geometryCount需要小于等与pBuildInfo->geometryCount。对于
pGeometries或ppGeometries数组中的每一个元素,其geometryType成员需要与pBuildInfo->geometryType相等。对于
pGeometries或ppGeometries数组中的每一个元素,其flags成员需要与pBuildInfo->flags相等。对于
pGeometries或ppGeometries数组中的每一个元素,当其geometryType成员等于VK_GEOMETRY_TYPE_TRIANGLES_KHR时,geometry.triangles的vertexFormat和indexType成员需要与pBuildInfo中的对应成员相等。对于
pGeometries或ppGeometries数组中的每一个元素,当其geometryType成员等于VK_GEOMETRY_TYPE_TRIANGLES_KHR时,geometry.triangles的maxVertex成员需要与pBuildInfo中的对应成员相等。对于
pGeometries或ppGeometries数组中的每一个元素,当其geometryType成员等于VK_GEOMETRY_TYPE_TRIANGLES_KHR时,geometry.triangles的transformData成员不是NULL,pBuildInfo对应的transformData.hostAddress也不能是NULL。
- 对于
- 对于每一个与
VkAccelerationStructureBuildGeometryInfoKHR对应的VkAccelerationStructureBuildRangeInfoKHR: 其
VkAccelerationStructureBuildGeometryInfoKHR的primitiveCount成员需要小于等于对应pMaxPrimitiveCounts的元素。
- 对于每一个与
与之相似的 updateScratchSize 在如上规范下使用 VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR 的 mode 的话将支持任意构建指令,并且 buildScratchSize 值在如上规范下使用 VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR 的 mode 的话将支持任意构建指令。
正确用法
必须激活
rayTracingPipeline或rayQuery特性。如果
device使用多物理设备创建的,则一定不能激活bufferDeviceAddressMultiDevice特性。如果
pBuildInfo->geometryCount不是0的话,pMaxPrimitiveCounts必须指向一个有效的类型为uint32_t长度为pBuildInfo->geometryCount的数组指针。如果
pBuildInfo->pGeometries或pBuildInfo->ppGeometries有一个VK_GEOMETRY_TYPE_INSTANCES_KHR类型的geometryType的话,每一个pMaxPrimitiveCounts[i]必须小于等于VkPhysicalDeviceAccelerationStructurePropertiesKHR::maxInstanceCount。
VkAccelerationStructureBuildTypeKHR¶
对于 vkGetAccelerationStructureBuildSizesKHR 中的 buildType 可设值为:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkAccelerationStructureBuildTypeKHR {
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2,
} VkAccelerationStructureBuildTypeKHR;
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR 请求的内存将会使用
host端进行操作。VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR 请求的内存将会使用
device端进行操作。VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR 请求的内存将会同时支持使用
host端和device端进行操作。
VkAccelerationStructureBuildSizesInfoKHR¶
VkAccelerationStructureBuildSizesInfoKHR 结构体描述了加速结构构建需求大小和暂付缓存的大小:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureBuildSizesInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceSize accelerationStructureSize;
VkDeviceSize updateScratchSize;
VkDeviceSize buildScratchSize;
} VkAccelerationStructureBuildSizesInfoKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。accelerationStructureSize 为
VkAccelerationStructureKHR在构建和更新时需要的比特大小。updateScratchSize 在更新时需要暂付缓存的比特大小。
buildScratchSize 在构建时需要暂付缓存的比特大小。
创建加速结构¶
vkCreateAccelerationStructureKHR¶
通过调用 vkCreateAccelerationStructureKHR 创建加速结构
// 由 VK_KHR_acceleration_structure 提供
VkResult vkCreateAccelerationStructureKHR(
VkDevice device,
const VkAccelerationStructureCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkAccelerationStructureKHR* pAccelerationStructure);
device 用于创建加速结构的逻辑设备句柄。
pCreateInfo 加速结构的构建信息。
pAllocator 分配器。
pAccelerationStructure 创建的目标加速结构句柄。
加速结构仅仅用于创建一个具有特定形状的物体。可以构建进入加速结构的几何数量和类型是通过 VkAccelerationStructureCreateInfoKHR 来指定。
之后往加速结构内部填入数据和绑定内存是通过调用 vkCmdBuildAccelerationStructuresKHR 、 vkBuildAccelerationStructuresKHR 、 vkCmdCopyAccelerationStructureKHR 和 vkCopyAccelerationStructureKHR 函数实现的。
在将缓存输入构建加速结构指令构建加速结构时,如何构建加速结构是设备自己内部实现。
正确用法
必须激活
accelerationStructure特性。如果
VkAccelerationStructureCreateInfoKHR::deviceAddress不是0的话,需要激活accelerationStructureCaptureReplay特性。如果
device是从多个物理设备建立的话,需要激活bufferDeviceAddressMultiDevice特性。
VkAccelerationStructureCreateInfoKHR¶
对应调用 vkCreateAccelerationStructureKHR 时,需要设置对应的 VkAccelerationStructureCreateInfoKHR 创建信息。
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureCreateFlagsKHR createFlags;
VkBuffer buffer;
VkDeviceSize offset;
VkDeviceSize size;
VkAccelerationStructureTypeKHR type;
VkDeviceAddress deviceAddress;
} VkAccelerationStructureCreateInfoKHR;
sType 该结构体的类型,必须是
VkStructureType::VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR。pNext 要么是
NULL要么指向VkAccelerationStructureMotionInfoNV或VkOpaqueCaptureDescriptorDataCreateInfoEXT。createFlags 是
VkAccelerationStructureCreateFlagBitsKHR的位域,用于创建加速结构时指定附加参数。buffer 加速结构将会存储的目标缓存。
offset 对于目标缓存的起始地址的比特偏移,在目标缓存的此偏移位置之后存储加速结构。偏移值必须是
256的倍数。size 加速结构需要的大小。
type
VkAccelerationStructureTypeKHR枚举值,用于创建的加速结构类型。deviceAddress 如果使用
accelerationStructureCaptureReplay特性,需要该加速结构请求的设备地址。
如果 deviceAddress 为 0 的话,表示没有指定请求地址。
如果 deviceAddress 不为 0 的话,其地址需要与 buffer 相对应。
应用应该避免在同一进程中使用应用提供的地址和设备实现提供的地址,这是为了减少 VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR 错误出现的可能性。
备注
一个预期的用法是将追踪捕获、回放工具,在使用 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT 位域创建的所有缓存上添加 VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT 位域,并且在那些 deviceAddress 不是 0 的
加速结构所对应的所有用于存储的缓存上增加 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT 位域。这也就意味着在应用还没有需要增加 VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT 位域时,工具需要对于内存分配增加 VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT 位域。
在捕获期间,工具将会保存捕获追踪到的设备地址。在回放期间,缓存将会根据原始地址创建,所以任何在追踪数据中存储的地址值将会一直处于有效状态。
驱动实现比较喜欢将这些缓存在 GPU 地址空间上进行分解,所以正常的内存分配将不会使用这些分解内存。为了避免地址空间分配冲突,应用或工具需要避免在 VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT 缓存上混合使用应用和驱动提供的地址。
应用应该使用除了 VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 之外的 VkAccelerationStructureTypeKHR 类型来创建加速结构
备注
VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 本意是给 API 转换层( API translation layers )使用的。 该类型可以在你创建加速结构时不清楚创建的是顶层加速结构还是底层加速结构时使用。在构建时真正的加速结构类型必须指定为 VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR 或 VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR 。
如果加速结构将作为构建的目标,加速结构需要的大小可以通过 vkGetAccelerationStructureBuildSizesKHR 获取。如果加速结构用于压缩拷贝的话, vkCmdWriteAccelerationStructuresPropertiesKHR 或 vkWriteAccelerationStructuresPropertiesKHR 可以用于获取需要的压缩大小。
如果加速结构用于构建 VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV 的话,其 VkAccelerationStructureCreateInfoKHR::createFlags 必须包含 VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV ,并且 VkAccelerationStructureCreateInfoKHR::pNext 中增加 VkAccelerationStructureMotionInfoNV 作为构建对象的原始数据。
VkAccelerationStructureMotionInfoNV 和 VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV
这两个属于 VK_NV_ray_tracing_motion_blur ,是 NVIDIA 的扩展,并不是 KHR 扩展,目前先忽略。
VkAccelerationStructureTypeKHR¶
VkAccelerationStructureCreateInfoKHR::type 用于设定加速结构的类型,支持的类型为:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkAccelerationStructureTypeKHR {
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0,
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1,
VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2,
} VkAccelerationStructureTypeKHR;
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR 表示包含实体(引用底层加速结构)的顶层加速结构。
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR 表示包含用于求交的
AABBs或几何数据的底层加速结构。VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 表示在加速结构创建时不知道是什么类型的,具体的类型需要在构建时确定,并且构建时必须确定是顶层加速结构还是底层加速结构。
VkAccelerationStructureCreateFlagBitsKHR¶
VkAccelerationStructureCreateInfoKHR::createFlags 可以设置的标志位域如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkAccelerationStructureCreateFlagBitsKHR {
VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001,
} VkAccelerationStructureCreateFlagBitsKHR;
VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR 表示加速结构的地址可以被之后的一系列执行存储和重用。
获取64位加速结构设备地址¶
vkGetAccelerationStructureDeviceAddressKHR¶
获取 64 位的加速结构设备地址,通过调用:
// 由 VK_KHR_acceleration_structure 提供
VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR(
VkDevice device,
const VkAccelerationStructureDeviceAddressInfoKHR* pInfo);
device 用于之前创建加速结构的逻辑设备句柄。
pInfo 指向用于设定获取目标加速结构地址的
VkAccelerationStructureDeviceAddressInfoKHR结构体。
该函数返回的 64 位的加速结构地址,可以用于与加速结构相关的设备和着色器操作,比如光线遍历和绑定加速结构。
如果加速结构在创建时 VkAccelerationStructureCreateInfoKHR::deviceAddress 给的是有效设备地址,该函数将返回与之相同的设备地址。
如果加速结构在创建时 type 是 VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 时,该函数返回的地址在使用相同的 VkBuffer 分配的 VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 的类型加速结构必须与其他加速度结构的相对偏移量一致。
返回的地址必须以 256 比特对齐。
VkAccelerationStructureDeviceAddressInfoKHR¶
相应的 VkAccelerationStructureDeviceAddressInfoKHR 定义为:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureDeviceAddressInfoKHR {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureKHR accelerationStructure;
} VkAccelerationStructureDeviceAddressInfoKHR;
sType 该结构体的类型,必须为
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。accelerationStructure 设定要获取设备地址的目标加速结构。
销毁加速结构¶
vkDestroyAccelerationStructureKHR¶
销毁一个加速结构,通过调用:
// 由 VK_KHR_acceleration_structure 提供
void vkDestroyAccelerationStructureKHR(
VkDevice device,
VkAccelerationStructureKHR accelerationStructure,
const VkAllocationCallbacks* pAllocator);
device 用于销毁加速结构的逻辑设备句柄。
accelerationStructure 要销毁的加速结构句柄。
pAllocator 指定使用
host端的内存分配器。
构建加速结构¶
vkCmdBuildAccelerationStructuresKHR¶
构建加速结构调用 vkCmdBuildAccelerationStructuresKHR :
// 由 VK_KHR_acceleration_structure 提供
void vkCmdBuildAccelerationStructuresKHR(
VkCommandBuffer commandBuffer,
uint32_t infoCount,
const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
commandBuffer 指定在哪个指令缓存中记录指令。
infoCount 只是要构建的加速结构的个数。该个数为
pInfos和ppBuildRangeInfos需要提供的个数。pInfos 是类型为
VkAccelerationStructureBuildGeometryInfoKHR数量为infoCount的数组,用于定义构建的每一个加速结构中的几何体。ppBuildRangeInfos 是类型为
VkAccelerationStructureBuildRangeInfoKHR数量为infoCount的数组。每一个ppBuildRangeInfos[i]都是指向数量为pInfos[i].geometryCount类型为VkAccelerationStructureBuildRangeInfoKHR的数组,用于动态定义pInfos[i]中对应的几何数据在内存中偏移。
vkCmdBuildAccelerationStructuresKHR 指令支持一次性构建多个加速结构,然而在每一个加速结构构建之间是没有隐含的顺序或同步的。
备注
这也就意味着应用不能在构建底层架结构或者实体加速结构( instance acceleration structures )的同一个 vkCmdBuildAccelerationStructuresKHR 构建指令中构建顶层加速结构。同时也不能在构建时在加速结构内存或暂付缓存上使用内存混叠。
实体加速结构
大概率是指 pInfos 中的 VkAccelerationStructureGeometryKHR* pGeometries 成员中 VkAccelerationStructureGeometryInstancesDataKHR instances 成员,用于构建实体加速结构。但在构建顶层加速结构是也会使用到 VkAccelerationStructureGeometryInstancesDataKHR instances ,此处的实体加速结构是啥并不明确,待后文看看。
内存混叠
内存混叠有点类似于 C++ 的 union 。同一段内存可以被多个资源使用,多见于临时资源的覆盖,使得一段内存可以多次重复使用。
访问 VkAccelerationStructureBuildGeometryInfoKHR::scratchData 对应的暂付缓存的设备地址必须在 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR 访问类型进行同步。
访问 VkAccelerationStructureBuildGeometryInfoKHR::srcAccelerationStructure 和 VkAccelerationStructureBuildGeometryInfoKHR::dstAccelerationStructure 时必须在 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR 或 VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR 访问类型进行同步较适当。
访问其他的 VkAccelerationStructureGeometryTrianglesDataKHR::vertexData 、 VkAccelerationStructureGeometryTrianglesDataKHR::indexData 、 VkAccelerationStructureGeometryTrianglesDataKHR::transformData 、 VkAccelerationStructureGeometryAabbsDataKHR::data 和 VkAccelerationStructureGeometryInstancesDataKHR::data 的输入缓存
时必须在 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_SHADER_READ_BIT 访问类型进行同步。
VkAccelerationStructureBuildRangeInfoKHR¶
VkAccelerationStructureBuildRangeInfoKHR 定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureBuildRangeInfoKHR {
uint32_t primitiveCount;
uint32_t primitiveOffset;
uint32_t firstVertex;
uint32_t transformOffset;
} VkAccelerationStructureBuildRangeInfoKHR;
primitiveCount 为对应的几何加速结构定义图元数量。
primitiveOffset 为图元在具体内存中的比特偏移。
firstVertex 为要构建的三角形几何体的第一个顶点的索引值。
transformOffset 为变换矩阵在具体内存中的比特偏移。
图元的数量和图元偏移将会根据不同的 VkGeometryTypeKHR 有所不同:
- 对于类型为
VK_GEOMETRY_TYPE_TRIANGLES_KHR的几何体,primitiveCount是要构建的三角形数量,每个三角形被认为由三个顶点组成。 如果几何体使用索引,将会从
VkAccelerationStructureGeometryTrianglesDataKHR::indexData中使用primitiveCount\(\times3\) 数量的索引数据,并从primitiveOffset偏移开始。获取顶点时,将会在索引值上加上firstVertex数量值。如果几何体不使用索引,将会从
VkAccelerationStructureGeometryTrianglesDataKHR::vertexData中使用primitiveCount\(\times3\) 数量的顶点数据,并从primitiveOffset\(+\)VkAccelerationStructureGeometryTrianglesDataKHR::vertexStride\(\times\)firstVertex偏移开始。如果
VkAccelerationStructureGeometryTrianglesDataKHR::transformData不是NULL的话, 将会从VkAccelerationStructureGeometryTrianglesDataKHR::transformData中在transformOffset偏移之后获取一个VkTransformMatrixKHR结构体数据。
- 对于类型为
对于类型为
VK_GEOMETRY_TYPE_AABBS_KHR,primitiveCount是轴对齐包围盒的个数。将会从VkAccelerationStructureGeometryAabbsDataKHR::data在primitiveOffset偏移之后获取primitiveCount个VkAabbPositionsKHR结构体数据。对于类型为
VK_GEOMETRY_TYPE_INSTANCES_KHR,primitiveCount是加速结构的个数。将会从VkAccelerationStructureGeometryInstancesDataKHR::data在primitiveOffset偏移之后获取primitiveCount个VkAccelerationStructureInstanceKHR结构体数据。
正确用法
对于类型为
VK_GEOMETRY_TYPE_TRIANGLES_KHR,如果几何体使用索引,VkAccelerationStructureGeometryTrianglesDataKHR::indexData必须是VkAccelerationStructureGeometryTrianglesDataKHR::indexType元素大小的倍数。对于类型为
VK_GEOMETRY_TYPE_TRIANGLES_KHR,如果几何体不使用索引,VkAccelerationStructureGeometryTrianglesDataKHR::vertexData必须是VkAccelerationStructureGeometryTrianglesDataKHR::vertexFormat元素大小的倍数。对于类型为
VK_GEOMETRY_TYPE_TRIANGLES_KHR, 对于VkAccelerationStructureGeometryTrianglesDataKHR::transformData的偏移transformOffset必须是16的倍数。对于类型为
VK_GEOMETRY_TYPE_AABBS_KHR, 对于VkAccelerationStructureGeometryAabbsDataKHR::data的偏移primitiveOffset必须是8的倍数。对于类型为
VK_GEOMETRY_TYPE_INSTANCES_KHR, 对于VkAccelerationStructureGeometryInstancesDataKHR::data的偏移primitiveOffset必须是16的倍数。
拷贝加速结构¶
还有一个用于拷贝加速结构的命令而不更新其内容。加速结构可以进行压缩来获得更高的性能。在拷贝前,应用必须先查询加速结构的大小。
vkCmdWriteAccelerationStructuresPropertiesKHR¶
查询加速结构的大小调用:
// 由 VK_KHR_acceleration_structure 提供
void vkCmdWriteAccelerationStructuresPropertiesKHR(
VkCommandBuffer commandBuffer,
uint32_t accelerationStructureCount,
const VkAccelerationStructureKHR* pAccelerationStructures,
VkQueryType queryType,
VkQueryPool queryPool,
uint32_t firstQuery);
commandBuffer 用于记录该指令的命令缓存。
accelerationStructureCount 要查询的加速结构的数量。
pAccelerationStructures 指向构建完成的加速结构数组。
queryType 其为
VkQueryType中的值,用于管理查询池的查询类型。queryPool 用于管理查询结果的查询池。
firstQuery 在查询池中包含
accelerationStructureCount数量的查询结果的第一个查询索引。
访问 pAccelerationStructures 中的任何一个加速结构都需要在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段和 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR 访问类型进行同步。
如果
queryType是VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR的话,则返回的查询值就是加速结构压缩之后需要的比特数量。如果
queryType是VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR的话,则返回的查询值就是加速结构序列化之后需要的比特数量。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure特性queryPool创建时的queryType必须与vkCmdWriteAccelerationStructuresPropertiesKHR::queryType相匹配。pAccelerationStructures中的加速结构在必须通过buffer绑定到了设备内存上。pAccelerationStructures中的加速结构在调用该指令之前必须已经构建完成。如果
queryType是VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR的话,pAccelerationStructures中所有的加速结构必须根据VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR构建的。queryType必须是VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR或VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR或VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR或VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR。
vkCmdCopyAccelerationStructureKHR¶
拷贝加速结构调用:
// 由 VK_KHR_acceleration_structure 提供
void vkCmdCopyAccelerationStructureKHR(
VkCommandBuffer commandBuffer,
const VkCopyAccelerationStructureInfoKHR* pInfo);
commandBuffer 用于记录该指令的命令缓存。
pInfo 指向
VkCopyAccelerationStructureInfoKHR结构体,用于定义拷贝操作。
该指令将会根据 pInfo->mode 中的模式将 pInfo->src 的加速结构拷贝至 pInfo->dst 加速结构中。
访问 pInfo->src 和 pInfo->dst 必须使用 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR 或 VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR 访问类型,在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段进行同步。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure特性pInfo->src中的加速结构在必须通过buffer绑定到了设备内存上。pInfo->dst中的加速结构在必须通过buffer绑定到了设备内存上。
VkCopyAccelerationStructureInfoKHR¶
VkCopyAccelerationStructureInfoKHR 定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkCopyAccelerationStructureInfoKHR {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureKHR src;
VkAccelerationStructureKHR dst;
VkCopyAccelerationStructureModeKHR mode;
} VkCopyAccelerationStructureInfoKHR;
sType 该结构体的类型,必须是
VkStructureType::VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。src 拷贝的源加速结构。
dst 拷贝的目标加速结构。
mode 用于在拷贝时增加额外操作。
正确用法
mode只能是VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR或VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR。src的源加速结构在执行该指令前必须构建完成 。如果
mode是VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR的话,src在构建时指定VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR。src中的加速结构在必须通过buffer绑定到了设备内存上。dst中的加速结构在必须通过buffer绑定到了设备内存上。dst中的加速结构在必须通过vkBindAccelerationStructureMemoryNV绑定到一个VkDeviceMemory设备内存上。该条存疑
拷贝时 mode 可能的值定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkCopyAccelerationStructureModeKHR {
VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0,
VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1,
VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2,
VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3,
} VkCopyAccelerationStructureModeKHR;
VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR 将
src中的加速结构直接拷贝至dst中,其中dst的创建参数必须和src的创建参数一样。如果src引用了其他加速结构,dst也需要进行相应的匹配。VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR 将
src中的加速结构压缩版本拷贝至dst中,其中dst的加速结构大小最起码需要与src构建之后使用vkCmdWriteAccelerationStructuresPropertiesKHR或vkWriteAccelerationStructuresPropertiesKHR获取到的大小一致。如果src引用了其他加速结构,dst也需要进行相应的匹配。VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR 将加速结构序列化到一个半透明的格式中,可以在兼容实现中加载。
VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR 将半透明的格式反序列化到中加速结构的缓存中。
vkCmdCopyAccelerationStructureToMemoryKHR¶
将加速结构拷贝至设备内存中调用:
// 由 VK_KHR_acceleration_structure 提供
void vkCmdCopyAccelerationStructureToMemoryKHR(
VkCommandBuffer commandBuffer,
const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
commandBuffer 用于记录该指令的命令缓存。
pInfo 定义拷贝操作。
访问 pInfo->src 的加速结构时必须在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR 访问类型进行同步。
访问 pInfo->dst.deviceAddress 的加速结构时必须在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_TRANSFER_WRITE_BIT 访问类型进行同步。
该指令与 vkCopyAccelerationStructureToMemoryKHR 函数的结果相似,只不过 vkCmdCopyAccelerationStructureToMemoryKHR 是写入 device 地址中,并且在 device 端执行而不是在 host 端。这两个指令函数的输出结果不一定每一个比特位都相同,但是在使用上 vkCmdCopyMemoryToAccelerationStructureKHR 和 vkCopyMemoryToAccelerationStructureKHR 是一样的。
序列化数据头结构如下:
VK_UUID_SIZE比特数据与VkPhysicalDeviceIDProperties::driverUUID相匹配。VK_UUID_SIZE比特数据使用vkGetDeviceAccelerationStructureCompatibilityKHR来进行兼容性对照。一个
64位整型的总大小与VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR查询到的相匹配。一个
64位整型的反序列化大小最终将会传入VkAccelerationStructureCreateInfoKHR::size。一个
64位整型表示加速结构句柄的数量。该数量与使用VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR查询到的数量相匹配。对于底层加速结构来说是0,但对于顶层加速结构来说是驱动实现相关的。句柄的数量和顺序与我们用于构建时使用的加速结构可能会不匹配。
vkGetAccelerationStructureDeviceAddressKHR 返回相匹配的句柄将会在缓存中根据数量紧凑排布。应用期望在反序列化时将句柄与应用生成的底层加速结构进行映射。将会根据 host 端的字节序列书序写入或读出缓存的序列化数据。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure特性。pInfo->dst.deviceAddress必须是一个缓存绑定到设备内内存的有效设备地址。pInfo->dst.deviceAddress必须是256比特对齐。如果缓存指向的
pInfo->dst.deviceAddress是非稀疏则必须绑定到一个单一的VkDeviceMemory对象上。pInfo->src使用到的buffer必须绑定到一个设备内存中。
VkCopyAccelerationStructureToMemoryInfoKHR¶
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkCopyAccelerationStructureToMemoryInfoKHR {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureKHR src;
VkDeviceOrHostAddressKHR dst;
VkCopyAccelerationStructureModeKHR mode;
} VkCopyAccelerationStructureToMemoryInfoKHR;
sType 该结构体的类型,必须是
VkStructureType::VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。src 拷贝的源加速结构。
dst 是拷贝目标
host或device内存地址。mode 是拷贝时的额外参数。
正确用法
src的加速结构必须在执行拷贝指令前创建完成。dst的内存大小最起码需要与使用VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR查询类型调用vkWriteAccelerationStructuresPropertiesKHR或vkCmdWriteAccelerationStructuresPropertiesKHR函数获取到src的序列化大小相同。mode只能是VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR。
vkCmdCopyMemoryToAccelerationStructureKHR¶
将设备内存拷贝至加速结构,调用:
// 由 VK_KHR_acceleration_structure 提供
void vkCmdCopyMemoryToAccelerationStructureKHR(
VkCommandBuffer commandBuffer,
const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
commandBuffer 用于记录该指令的命令缓存。
pInfo 定义拷贝操作。
访问 pInfo->dst 的加速结构时必须在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR 访问类型进行同步。
访问 pInfo->src.deviceAddress 的地址时必须在 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR 或 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR 管线阶段使用 VK_ACCESS_TRANSFER_READ_BIT 访问类型进行同步。
该指令支持使用 vkCmdCopyAccelerationStructureToMemoryKHR 或 vkCopyAccelerationStructureToMemoryKHR 拷贝的目标内存地址。
该指令的的反序列化将会作为 vkCmdCopyAccelerationStructureToMemoryKHR 输入。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure特性。pInfo->src.deviceAddress必须是已经绑定到设备内存的缓存地址。pInfo->src.deviceAddress必须是256比特对齐。如果缓存指向的
pInfo->src.deviceAddress是非稀疏则必须绑定到一个单一的VkDeviceMemory对象上。pInfo->dst使用到的buffer必须绑定到一个设备内存中。
VkCopyMemoryToAccelerationStructureInfoKHR¶
VkCopyMemoryToAccelerationStructureInfoKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkCopyMemoryToAccelerationStructureInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceOrHostAddressConstKHR src;
VkAccelerationStructureKHR dst;
VkCopyAccelerationStructureModeKHR mode;
} VkCopyMemoryToAccelerationStructureInfoKHR;
sType 该结构体的类型,必须是
VkStructureType::VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。src 拷贝的源
host或device内存地址。dst 是拷贝目标加速结构。
mode 是拷贝时的额外参数。
正确用法
src的内存指针必须包含之前使用vkCmdCopyAccelerationStructureToMemoryKHR获取的序列化数据。可以用该函数将加速结构进行数据重定位移动。mode只能是VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR。src中的数据必须与vkGetDeviceAccelerationStructureCompatibilityKHR返回的目标物理设备有兼容的格式。dst创建的大小需要大于等于src序列化的大小。
vkGetDeviceAccelerationStructureCompatibilityKHR¶
为了检查序列化的加速结构是否与当前设备兼容:
// 由 VK_KHR_acceleration_structure 提供
void vkGetDeviceAccelerationStructureCompatibilityKHR(
VkDevice device,
const VkAccelerationStructureVersionInfoKHR* pVersionInfo,
VkAccelerationStructureCompatibilityKHR* pCompatibility);
device 用于检查版本的设备。
pVersionInfo 用于设置检查版本的信息。
pCompatibility 用于返回兼容性信息。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure特性。
VkAccelerationStructureVersionInfoKHR¶
VkAccelerationStructureVersionInfoKHR 结构体定义如下:
// 由 VK_KHR_acceleration_structure 提供
typedef struct VkAccelerationStructureVersionInfoKHR {
VkStructureType sType;
const void* pNext;
const uint8_t* pVersionData;
} VkAccelerationStructureVersionInfoKHR;
sType 该结构体的类型,必须是
VkStructureType::VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR。pNext 要么是
NULL要么指向其他结构体来扩展该结构体。pVersionData 指向
vkCmdCopyAccelerationStructureToMemoryKHR中定义的加速结构版本头。
备注
pVersionData 指向一个 \(2\times VK\_UUID\_SIZE\) 的 uint8_t 的数组,而不是两个 VK_UUID_SIZE 数组。因为此成员的预期用例将指向内存中加载先前序列化的加速结构(通过vkCmdCopyAccelerationStructureToMemoryKHR或vkCopyAcceleration StructureToMemory KHR)的头部。使用数组将需要 UUID 的额外拷贝。不知所云
正确用法
pVersionData必须是指向 \(2\times VK\_UUID\_SIZE\) 的uint8_t的数组。
VkAccelerationStructureCompatibilityKHR¶
pCompatibility 可能的返回值如下:
// 由 VK_KHR_acceleration_structure 提供
typedef enum VkAccelerationStructureCompatibilityKHR {
VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0,
VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR = 1,
} VkAccelerationStructureCompatibilityKHR;
VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR 表示
pVersionData的加速结构版本与device兼容。VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR 表示
pVersionData的加速结构版本与device不兼容。
加速结构的 Host 端操作¶
如果驱动支持 VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructureHostCommands 特性的话,这说明对于加速结构支持在 Host 端进行操作。相关 Host 端操作函数与 Device 端操作函数对应如下:
vkBuildAccelerationStructuresKHR对应vkCmdBuildAccelerationStructuresKHRvkCopyAccelerationStructureKHR对应vkCmdCopyAccelerationStructureKHRvkCopyAccelerationStructureToMemoryKHR对应vkCmdCopyAccelerationStructureToMemoryKHRvkCopyMemoryToAccelerationStructureKHR对应vkCmdCopyMemoryToAccelerationStructureKHRvkWriteAccelerationStructuresPropertiesKHR对应vkCmdWriteAccelerationStructuresPropertiesKHR
Host 端操作函数与 Device 端操作函数在功能上是等价的,只不过是在 Host 端进行操作,而不是插入到命令缓存中( command buffers )。
所有 Host 端的加速结构必须将内存绑定到 Host 端可访问的内存上,并且加速结构构建时的所有输入数据必须使用 Host 端内存而不是 Device 端数据。当时用 Host 端的函数时不需要应用将加速结构的内存映射出来。
备注
vkBuildAccelerationStructuresKHR 和 vkCmdBuildAccelerationStructuresKHR 也许会使用不同的算法,然而并没有要求这两个函数的结果需要完全相同。这两个函数可能会分别建立各自完全不同的内存或遍历性能,但是应该尽可能地尽量做到相似。
除了这些细节之外,Host 和 Device 操作是可互换兼容的。比如可以使用 vkBuildAccelerationStructuresKHR 构建一个加速结构,之后可以使用 vkCmdCopyAccelerationStructureKHR 将其进行压缩,并且使用 vkCopyAccelerationStructureToMemoryKHR 将加速结构进行序列化。
备注
为了高效执行,由于驱动可能在指令执行期间反复的读写加速结构内存,所以操作这个加速结构的内存需要总是绑定到 host cached 内存上( VK_MEMORY_PROPERTY_HOST_CACHED_BIT )。
vkBuildAccelerationStructuresKHR¶
在 Host 端构建一个加速结构调用:
// 由 VK_KHR_acceleration_structure 提供
VkResult vkBuildAccelerationStructuresKHR(
VkDevice device,
VkDeferredOperationKHR deferredOperation,
uint32_t infoCount,
const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
device 表示构建加速结构对应的
VkDevice。deferredOperation 是一个可选的
VkDeferredOperationKHR句柄,为该指令申请延迟操作。infoCount 表示要构建的加速结构数量。并表示
pInfos和ppBuildRangeInfos需要提供的数量。pInfos 指向数量为
infoCount类型为VkAccelerationStructureBuildGeometryInfoKHR结构体的数组,用于定义每一个要构建的加速结构。ppBuildRangeInfos 指向数量为
infoCount类型为VkAccelerationStructureBuildRangeInfoKHR结构体指针数组。,每一个ppBuildRangeInfos[i]都指向一个数量为pInfos[i].geometryCount类型为VkAccelerationStructureBuildRangeInfoKHR的结构体数组,用于对应pInfos[i]中几何数句的动态内存偏移。
该函数的工作和 vkCmdBuildAccelerationStructuresKHR 函数一致,只不过执行在 Host 端上。
vkBuildAccelerationStructuresKHR 支持一次性构建多个加速结构,然而构建与构建之间没有内置的顺序和同步。
备注
这也就意味着不能通过 vkBuildAccelerationStructuresKHR 函数调用同时构建底层加速结构和顶层加速结构。同样也不允许使用任何加速结构或暂付缓存的内存混叠。
vkCopyAccelerationStructureKHR¶
在 Host 端拷贝和压缩加速结构,调用:
// 由 VK_KHR_acceleration_structure 提供
VkResult vkCopyAccelerationStructureKHR(
VkDevice device,
VkDeferredOperationKHR deferredOperation,
const VkCopyAccelerationStructureInfoKHR* pInfo);
device 表示构建加速结构对应的
VkDevice。deferredOperation 是一个可选的
VkDeferredOperationKHR句柄,为该指令申请延迟操作。pInfo 指向用于定义拷贝操作的
VkCopyAccelerationStructureInfoKHR结构体。
该函数的工作和 vkCmdCopyAccelerationStructureKHR 函数一致,只不过执行在 Host 端上。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructureHostCommands特性。如果
deferredOperation不是VK_NULL_HANDLE的话,其必须是一个有效的VkDeferredOperationKHR句柄。任何与
deferredOperation相关的前操作都需要完成结束。用于
pInfo->src的buffer必须绑定到Host端可访问的内存上。用于
pInfo->dst的buffer必须绑定到Host端可访问的内存上。用于
pInfo->src的buffer必须绑定到没有分配多实体的内存上。用于
pInfo->dst的buffer必须绑定到没有分配多实体的内存上。
vkCopyMemoryToAccelerationStructureKHR¶
将 Host 端可访问的内存拷贝到加速结构中,调用:
// 由 VK_KHR_acceleration_structure 提供
VkResult vkCopyMemoryToAccelerationStructureKHR(
VkDevice device,
VkDeferredOperationKHR deferredOperation,
const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
device 表示构建加速结构对应的
VkDevice,与pInfo->dst的设备相同。deferredOperation 是一个可选的
VkDeferredOperationKHR句柄,为该指令申请延迟操作。pInfo 指向用于定义拷贝操作的
VkCopyMemoryToAccelerationStructureInfoKHR结构体。
该函数的工作和 vkCmdCopyMemoryToAccelerationStructureKHR 函数一致,只不过执行在 Host 端上。
该函数支持使用 vkCmdCopyAccelerationStructureToMemoryKHR 或 vkCopyAccelerationStructureToMemoryKHR 的加速结构内存。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructureHostCommands特性。如果
deferredOperation不是VK_NULL_HANDLE的话,其必须是一个有效的VkDeferredOperationKHR句柄。任何与
deferredOperation相关的前操作都需要完成结束。用于
pInfo->src.hostAddress必须是一个有效的Host端指针。用于
pInfo->dst的buffer必须绑定到Host端可访问的内存上。用于
pInfo->src.hostAddress必须16比特对齐。用于
pInfo->dst的buffer必须绑定到没有分配多实体的内存上。
vkCopyAccelerationStructureToMemoryKHR¶
将加速结构拷贝至 Host 端可访问的内存上,调用:
// 由 VK_KHR_acceleration_structure 提供
VkResult vkCopyAccelerationStructureToMemoryKHR(
VkDevice device,
VkDeferredOperationKHR deferredOperation,
const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
device 表示构建加速结构对应的
VkDevice,与pInfo->src的设备相同。deferredOperation 是一个可选的
VkDeferredOperationKHR句柄,为该指令申请延迟操作。pInfo 指向用于定义拷贝操作的
VkCopyAccelerationStructureToMemoryInfoKHR结构体。
该函数的工作和 vkCmdCopyAccelerationStructureToMemoryKHR 函数一致,只不过执行在 Host 端上。
该函数与 vkCmdCopyAccelerationStructureToMemoryKHR 结果相同,只不过直接将结果写入 Host 端指针指向的内存上,并执行在 Host 端上而不是 Device 端。每次输出的结果并不一定每一个比特都相等,但都可以被 vkCmdCopyMemoryToAccelerationStructureKHR 或 vkCopyMemoryToAccelerationStructureKHR 使用。
正确用法
需要激活
VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructureHostCommands特性。如果
deferredOperation不是VK_NULL_HANDLE的话,其必须是一个有效的VkDeferredOperationKHR句柄。任何与
deferredOperation相关的前操作都需要完成结束。用于
pInfo->src的buffer必须绑定到Host端可访问的内存上。用于
pInfo->dst.hostAddress必须是有效的Host指针。用于
pInfo->dst.hostAddress必须16比特对齐。用于
pInfo->src的buffer必须绑定到没有分配多实体的内存上。
vkWriteAccelerationStructuresPropertiesKHR¶
在 Host 端查询加速结构大小,调用:
// Provided by VK_KHR_acceleration_structure
VkResult vkWriteAccelerationStructuresPropertiesKHR(
VkDevice device,
uint32_t accelerationStructureCount,
const VkAccelerationStructureKHR* pAccelerationStructures,
VkQueryType queryType,
size_t dataSize,
void* pData,
size_t stride);
device 表示拥有
pAccelerationStructures加速结构对应的VkDevice。accelerationStructureCount 表示要查询的加速结构的数量。
pAccelerationStructures 用于指向之前构建的加速结构数组。
queryType 是
VkQueryType值用于设置查询类型。dataSize 是
pData中数据的比特大小。pData 指向用户分配的缓存用于写入结果。
stride 指向这是写入的每个结果之间的跨度。
该函数的工作和 vkCmdWriteAccelerationStructuresPropertiesKHR 函数一致,只不过执行在 Host 端上。