Mesa (main): radv: Add copy/serialization info to accel struct headers.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Oct 1 14:13:37 UTC 2021
Module: Mesa
Branch: main
Commit: 817b4a9acad71def1e974c1e5d3bb0d5c61fec1b
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=817b4a9acad71def1e974c1e5d3bb0d5c61fec1b
Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date: Wed Sep 1 12:50:00 2021 +0200
radv: Add copy/serialization info to accel struct headers.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12840>
---
src/amd/vulkan/radv_acceleration_structure.c | 170 +++++++++++++++++----------
src/amd/vulkan/radv_acceleration_structure.h | 12 ++
2 files changed, 117 insertions(+), 65 deletions(-)
diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c
index 77c8826e007..9d90e89cb32 100644
--- a/src/amd/vulkan/radv_acceleration_structure.c
+++ b/src/amd/vulkan/radv_acceleration_structure.c
@@ -536,26 +536,37 @@ build_bvh(struct radv_device *device, const VkAccelerationStructureBuildGeometry
.base = base_ptr,
.curr_ptr = (char *)first_node_ptr + 128};
+ uint64_t instance_offset = (const char *)ctx.curr_ptr - (const char *)base_ptr;
+ uint64_t instance_count = 0;
+
/* This initializes the leaf nodes of the BVH all at the same level. */
- for (uint32_t i = 0; i < info->geometryCount; ++i) {
- const VkAccelerationStructureGeometryKHR *geom =
- info->pGeometries ? &info->pGeometries[i] : info->ppGeometries[i];
+ for (int inst = 1; inst >= 0; --inst) {
+ for (uint32_t i = 0; i < info->geometryCount; ++i) {
+ const VkAccelerationStructureGeometryKHR *geom =
+ info->pGeometries ? &info->pGeometries[i] : info->ppGeometries[i];
- switch (geom->geometryType) {
- case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
- build_triangles(&ctx, geom, ranges + i, i);
- break;
- case VK_GEOMETRY_TYPE_AABBS_KHR:
- build_aabbs(&ctx, geom, ranges + i, i);
- break;
- case VK_GEOMETRY_TYPE_INSTANCES_KHR: {
- result = build_instances(device, &ctx, geom, ranges + i);
- if (result != VK_SUCCESS)
- goto fail;
- break;
- }
- case VK_GEOMETRY_TYPE_MAX_ENUM_KHR:
- unreachable("VK_GEOMETRY_TYPE_MAX_ENUM_KHR unhandled");
+ if ((inst && geom->geometryType != VK_GEOMETRY_TYPE_INSTANCES_KHR) ||
+ (!inst && geom->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR))
+ continue;
+
+ switch (geom->geometryType) {
+ case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
+ build_triangles(&ctx, geom, ranges + i, i);
+ break;
+ case VK_GEOMETRY_TYPE_AABBS_KHR:
+ build_aabbs(&ctx, geom, ranges + i, i);
+ break;
+ case VK_GEOMETRY_TYPE_INSTANCES_KHR: {
+ result = build_instances(device, &ctx, geom, ranges + i);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ instance_count += ranges[i].primitiveCount;
+ break;
+ }
+ case VK_GEOMETRY_TYPE_MAX_ENUM_KHR:
+ unreachable("VK_GEOMETRY_TYPE_MAX_ENUM_KHR unhandled");
+ }
}
}
@@ -622,6 +633,8 @@ build_bvh(struct radv_device *device, const VkAccelerationStructureBuildGeometry
compute_bounds(base_ptr, header->root_node_offset, &header->aabb[0][0]);
+ header->instance_offset = instance_offset;
+ header->instance_count = instance_count;
header->compacted_size = (char *)ctx.curr_ptr - base_ptr;
/* 16 bytes per invocation, 64 invocations per workgroup */
@@ -629,6 +642,11 @@ build_bvh(struct radv_device *device, const VkAccelerationStructureBuildGeometry
header->copy_dispatch_size[1] = 1;
header->copy_dispatch_size[2] = 1;
+ header->serialization_size =
+ header->compacted_size + align(sizeof(struct radv_accel_struct_serialization_header) +
+ sizeof(uint64_t) * header->instance_count,
+ 128);
+
fail:
device->ws->buffer_unmap(accel->bo);
return result;
@@ -1403,6 +1421,9 @@ struct bvh_state {
uint32_t node_offset;
uint32_t node_count;
uint32_t scratch_offset;
+
+ uint32_t instance_offset;
+ uint32_t instance_count;
};
void
@@ -1432,52 +1453,62 @@ radv_CmdBuildAccelerationStructuresKHR(
.dst_offset = ALIGN(sizeof(struct radv_accel_struct_header), 64) + 128,
.dst_scratch_offset = 0,
};
-
- for (unsigned j = 0; j < pInfos[i].geometryCount; ++j) {
- const VkAccelerationStructureGeometryKHR *geom =
- pInfos[i].pGeometries ? &pInfos[i].pGeometries[j] : pInfos[i].ppGeometries[j];
-
- prim_consts.geometry_type = geom->geometryType;
- prim_consts.geometry_id = j | (geom->flags << 28);
- unsigned prim_size;
- switch (geom->geometryType) {
- case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
- prim_consts.vertex_addr =
- geom->geometry.triangles.vertexData.deviceAddress +
- ppBuildRangeInfos[i][j].firstVertex * geom->geometry.triangles.vertexStride +
- (geom->geometry.triangles.indexType != VK_INDEX_TYPE_NONE_KHR
- ? ppBuildRangeInfos[i][j].primitiveOffset
- : 0);
- prim_consts.index_addr = geom->geometry.triangles.indexData.deviceAddress +
- ppBuildRangeInfos[i][j].primitiveOffset;
- prim_consts.transform_addr = geom->geometry.triangles.transformData.deviceAddress +
- ppBuildRangeInfos[i][j].transformOffset;
- prim_consts.vertex_stride = geom->geometry.triangles.vertexStride;
- prim_consts.vertex_format = geom->geometry.triangles.vertexFormat;
- prim_consts.index_format = geom->geometry.triangles.indexType;
- prim_size = 64;
- break;
- case VK_GEOMETRY_TYPE_AABBS_KHR:
- prim_consts.aabb_addr =
- geom->geometry.aabbs.data.deviceAddress + ppBuildRangeInfos[i][j].primitiveOffset;
- prim_consts.aabb_stride = geom->geometry.aabbs.stride;
- prim_size = 64;
- break;
- case VK_GEOMETRY_TYPE_INSTANCES_KHR:
- prim_consts.instance_data = geom->geometry.instances.data.deviceAddress;
- prim_consts.array_of_pointers = geom->geometry.instances.arrayOfPointers ? 1 : 0;
- prim_size = 128;
- break;
- default:
- unreachable("Unknown geometryType");
+ bvh_states[i].node_offset = prim_consts.dst_offset;
+ bvh_states[i].instance_offset = prim_consts.dst_offset;
+
+ for (int inst = 1; inst >= 0; --inst) {
+ for (unsigned j = 0; j < pInfos[i].geometryCount; ++j) {
+ const VkAccelerationStructureGeometryKHR *geom =
+ pInfos[i].pGeometries ? &pInfos[i].pGeometries[j] : pInfos[i].ppGeometries[j];
+
+ if ((inst && geom->geometryType != VK_GEOMETRY_TYPE_INSTANCES_KHR) ||
+ (!inst && geom->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR))
+ continue;
+
+ prim_consts.geometry_type = geom->geometryType;
+ prim_consts.geometry_id = j | (geom->flags << 28);
+ unsigned prim_size;
+ switch (geom->geometryType) {
+ case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
+ prim_consts.vertex_addr =
+ geom->geometry.triangles.vertexData.deviceAddress +
+ ppBuildRangeInfos[i][j].firstVertex * geom->geometry.triangles.vertexStride +
+ (geom->geometry.triangles.indexType != VK_INDEX_TYPE_NONE_KHR
+ ? ppBuildRangeInfos[i][j].primitiveOffset
+ : 0);
+ prim_consts.index_addr = geom->geometry.triangles.indexData.deviceAddress +
+ ppBuildRangeInfos[i][j].primitiveOffset;
+ prim_consts.transform_addr = geom->geometry.triangles.transformData.deviceAddress +
+ ppBuildRangeInfos[i][j].transformOffset;
+ prim_consts.vertex_stride = geom->geometry.triangles.vertexStride;
+ prim_consts.vertex_format = geom->geometry.triangles.vertexFormat;
+ prim_consts.index_format = geom->geometry.triangles.indexType;
+ prim_size = 64;
+ break;
+ case VK_GEOMETRY_TYPE_AABBS_KHR:
+ prim_consts.aabb_addr =
+ geom->geometry.aabbs.data.deviceAddress + ppBuildRangeInfos[i][j].primitiveOffset;
+ prim_consts.aabb_stride = geom->geometry.aabbs.stride;
+ prim_size = 64;
+ break;
+ case VK_GEOMETRY_TYPE_INSTANCES_KHR:
+ prim_consts.instance_data = geom->geometry.instances.data.deviceAddress;
+ prim_consts.array_of_pointers = geom->geometry.instances.arrayOfPointers ? 1 : 0;
+ prim_size = 128;
+ bvh_states[i].instance_count += ppBuildRangeInfos[i][j].primitiveCount;
+ break;
+ default:
+ unreachable("Unknown geometryType");
+ }
+
+ radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
+ cmd_buffer->device->meta_state.accel_struct_build.leaf_p_layout,
+ VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(prim_consts),
+ &prim_consts);
+ radv_unaligned_dispatch(cmd_buffer, ppBuildRangeInfos[i][j].primitiveCount, 1, 1);
+ prim_consts.dst_offset += prim_size * ppBuildRangeInfos[i][j].primitiveCount;
+ prim_consts.dst_scratch_offset += 4 * ppBuildRangeInfos[i][j].primitiveCount;
}
-
- radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
- cmd_buffer->device->meta_state.accel_struct_build.leaf_p_layout,
- VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(prim_consts), &prim_consts);
- radv_unaligned_dispatch(cmd_buffer, ppBuildRangeInfos[i][j].primitiveCount, 1, 1);
- prim_consts.dst_offset += prim_size * ppBuildRangeInfos[i][j].primitiveCount;
- prim_consts.dst_scratch_offset += 4 * ppBuildRangeInfos[i][j].primitiveCount;
}
bvh_states[i].node_offset = prim_consts.dst_offset;
bvh_states[i].node_count = prim_consts.dst_scratch_offset / 4;
@@ -1535,6 +1566,9 @@ radv_CmdBuildAccelerationStructuresKHR(
pInfos[i].dstAccelerationStructure);
const size_t base = offsetof(struct radv_accel_struct_header, compacted_size);
struct radv_accel_struct_header header;
+
+ header.instance_offset = bvh_states[i].instance_offset;
+ header.instance_count = bvh_states[i].instance_count;
header.compacted_size = bvh_states[i].node_offset;
/* 16 bytes per invocation, 64 invocations per workgroup */
@@ -1542,8 +1576,14 @@ radv_CmdBuildAccelerationStructuresKHR(
header.copy_dispatch_size[1] = 1;
header.copy_dispatch_size[2] = 1;
- radv_update_buffer(cmd_buffer, accel_struct->bo, accel_struct->mem_offset + base,
- (const char *)&header + base, sizeof(header) - base);
+ header.serialization_size =
+ header.compacted_size + align(sizeof(struct radv_accel_struct_serialization_header) +
+ sizeof(uint64_t) * header.instance_count,
+ 128);
+
+ radv_update_buffer_cp(cmd_buffer,
+ radv_buffer_get_va(accel_struct->bo) + accel_struct->mem_offset + base,
+ (const char *)&header + base, sizeof(header) - base);
}
free(bvh_states);
radv_meta_restore(&saved_state, cmd_buffer);
diff --git a/src/amd/vulkan/radv_acceleration_structure.h b/src/amd/vulkan/radv_acceleration_structure.h
index 7278a9ec136..062edde5016 100644
--- a/src/amd/vulkan/radv_acceleration_structure.h
+++ b/src/amd/vulkan/radv_acceleration_structure.h
@@ -25,6 +25,16 @@
#define RADV_ACCELERATION_STRUCTURE_H
#include <stdint.h>
+#include <vulkan/vulkan.h>
+
+struct radv_accel_struct_serialization_header {
+ uint8_t driver_uuid[VK_UUID_SIZE];
+ uint8_t accel_struct_compat[VK_UUID_SIZE];
+ uint64_t serialization_size;
+ uint64_t compacted_size;
+ uint64_t instance_count;
+ uint64_t instances[];
+};
struct radv_accel_struct_header {
uint32_t root_node_offset;
@@ -35,6 +45,8 @@ struct radv_accel_struct_header {
uint64_t compacted_size;
uint64_t serialization_size;
uint32_t copy_dispatch_size[3];
+ uint64_t instance_offset;
+ uint64_t instance_count;
};
struct radv_bvh_triangle_node {
More information about the mesa-commit
mailing list