vulkan: Pass a structure to most BVH build callbacks

It is annoying to change all function signatures when a driver needs
more information. There are also some callbacks that have a lot of
parameters and there have already been bugs related to that.

This patch tries to clean the interface by adding a struct that contains
all information that might be relevant for the driver and passing that
to most callbacks.

radv changes are:
Reviewed-by: Natalie Vock <natalie.vock@gmx.de>

anv changes are:
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

turnip changes are:
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>

vulkan runtime changes are:

Reviewed-by: Natalie Vock <natalie.vock@gmx.de>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35385>
This commit is contained in:
Konstantin Seurer 2025-06-06 17:07:53 +02:00 committed by Marge Bot
parent a73824a59d
commit 4cbbdc0a50
6 changed files with 350 additions and 423 deletions

View file

@ -70,15 +70,15 @@ enum radv_encode_key_bits {
};
static void
radv_get_acceleration_structure_layout(struct radv_device *device, uint32_t leaf_count,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
radv_get_acceleration_structure_layout(struct radv_device *device,
const struct vk_acceleration_structure_build_state *state,
struct acceleration_structure_layout *accel_struct)
{
const struct radv_physical_device *pdev = radv_device_physical(device);
uint32_t internal_count = MAX2(leaf_count, 2) - 1;
uint32_t internal_count = MAX2(state->leaf_node_count, 2) - 1;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(state->build_info);
uint32_t bvh_leaf_size;
uint32_t bvh_node_size_gcd;
@ -117,18 +117,18 @@ radv_get_acceleration_structure_layout(struct radv_device *device, uint32_t leaf
uint32_t internal_node_size =
radv_use_bvh8(pdev) ? sizeof(struct radv_gfx12_box_node) : sizeof(struct radv_bvh_box32_node);
uint64_t bvh_size = bvh_leaf_size * leaf_count + internal_node_size * internal_count;
uint64_t bvh_size = bvh_leaf_size * state->leaf_node_count + internal_node_size * internal_count;
uint32_t offset = 0;
offset += sizeof(struct radv_accel_struct_header);
if (device->rra_trace.accel_structs) {
accel_struct->geometry_info_offset = offset;
offset += sizeof(struct radv_accel_struct_geometry_info) * build_info->geometryCount;
offset += sizeof(struct radv_accel_struct_geometry_info) * state->build_info->geometryCount;
}
if (device->vk.enabled_features.rayTracingPositionFetch && geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
accel_struct->primitive_base_indices_offset = offset;
offset += sizeof(uint32_t) * build_info->geometryCount;
offset += sizeof(uint32_t) * state->build_info->geometryCount;
}
/* On GFX12, we need additional space for leaf node offsets since they do not have the same
@ -136,7 +136,7 @@ radv_get_acceleration_structure_layout(struct radv_device *device, uint32_t leaf
*/
accel_struct->leaf_node_offsets_offset = offset;
if (radv_use_bvh8(pdev))
offset += leaf_count * 4;
offset += state->leaf_node_count * 4;
/* Parent links, which have to go directly before bvh_offset as we index them using negative
* offsets from there. */
@ -150,7 +150,7 @@ radv_get_acceleration_structure_layout(struct radv_device *device, uint32_t leaf
offset += internal_node_size;
accel_struct->leaf_nodes_offset = offset;
offset += bvh_leaf_size * leaf_count;
offset += bvh_leaf_size * state->leaf_node_count;
accel_struct->internal_nodes_offset = offset;
/* Factor out the root node. */
@ -160,25 +160,24 @@ radv_get_acceleration_structure_layout(struct radv_device *device, uint32_t leaf
}
static void
radv_get_update_scratch_layout(struct radv_device *device,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info, uint32_t leaf_count,
radv_get_update_scratch_layout(struct radv_device *device, const struct vk_acceleration_structure_build_state *state,
struct update_scratch_layout *scratch)
{
const struct radv_physical_device *pdev = radv_device_physical(device);
uint32_t internal_count = MAX2(leaf_count, 2) - 1;
uint32_t internal_count = MAX2(state->leaf_node_count, 2) - 1;
uint32_t offset = 0;
if (radv_use_bvh8(pdev)) {
scratch->geometry_data_offset = offset;
offset += sizeof(struct vk_bvh_geometry_data) * build_info->geometryCount;
offset += sizeof(struct vk_bvh_geometry_data) * state->build_info->geometryCount;
scratch->bounds_offsets = offset;
offset += sizeof(vk_aabb) * internal_count;
} else {
scratch->bounds_offsets = offset;
offset += sizeof(vk_aabb) * leaf_count;
offset += sizeof(vk_aabb) * state->leaf_node_count;
}
scratch->internal_ready_count_offset = offset;
@ -378,58 +377,46 @@ radv_device_init_null_accel_struct(struct radv_device *device)
}
static VkDeviceSize
radv_get_as_size(VkDevice _device, const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo, uint32_t leaf_count)
radv_get_as_size(VkDevice _device, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_device, device, _device);
struct acceleration_structure_layout accel_struct;
radv_get_acceleration_structure_layout(device, leaf_count, pBuildInfo, &accel_struct);
radv_get_acceleration_structure_layout(device, state, &accel_struct);
return accel_struct.size;
}
static VkDeviceSize
radv_get_update_scratch_size(struct vk_device *vk_device, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
uint32_t leaf_count)
radv_get_update_scratch_size(VkDevice _device, const struct vk_acceleration_structure_build_state *state)
{
struct radv_device *device = container_of(vk_device, struct radv_device, vk);
VK_FROM_HANDLE(radv_device, device, _device);
struct update_scratch_layout scratch;
radv_get_update_scratch_layout(device, build_info, leaf_count, &scratch);
radv_get_update_scratch_layout(device, state, &scratch);
return scratch.size;
}
static uint32_t
radv_get_encode_key(struct vk_device *vk_device, const VkAccelerationStructureBuildGeometryInfoKHR *build_info)
static void
radv_get_build_config(VkDevice _device, struct vk_acceleration_structure_build_state *state)
{
struct radv_device *device = container_of(vk_device, struct radv_device, vk);
VK_FROM_HANDLE(radv_device, device, _device);
struct radv_physical_device *pdev = radv_device_physical(device);
uint32_t encode_key = 0;
if (radv_use_bvh8(pdev))
return RADV_ENCODE_KEY_COMPACT;
encode_key |= RADV_ENCODE_KEY_COMPACT;
if (build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR)
return RADV_ENCODE_KEY_COMPACT;
if (state->build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR)
encode_key |= RADV_ENCODE_KEY_COMPACT;
return 0;
}
state->config.encode_key[0] = encode_key;
state->config.encode_key[1] = encode_key;
static uint32_t
radv_get_update_key(struct vk_device *vk_device, bool in_place)
{
return in_place ? RADV_BUILD_FLAG_UPDATE_IN_PLACE : 0;
}
uint32_t update_key = 0;
if (state->build_info->srcAccelerationStructure == state->build_info->dstAccelerationStructure)
update_key |= RADV_BUILD_FLAG_UPDATE_IN_PLACE;
static void
radv_get_build_config(struct vk_device *vk_device, struct vk_build_config *config,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info)
{
uint32_t encode_key = radv_get_encode_key(vk_device, build_info);
config->encode_key[0] = encode_key;
config->encode_key[1] = encode_key;
uint32_t update_key =
radv_get_update_key(vk_device, build_info->srcAccelerationStructure == build_info->dstAccelerationStructure);
config->update_key[0] = update_key;
state->config.update_key[0] = update_key;
}
static void
@ -494,17 +481,18 @@ radv_build_flags(VkCommandBuffer commandBuffer, uint32_t key)
}
static VkResult
radv_encode_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
radv_encode_bind_pipeline(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
radv_bvh_build_bind_pipeline(commandBuffer, RADV_META_OBJECT_KEY_BVH_ENCODE, encode_spv, sizeof(encode_spv),
sizeof(struct encode_args),
radv_build_flags(commandBuffer, key));
radv_build_flags(commandBuffer, state->config.encode_key[0]));
return VK_SUCCESS;
}
static VkResult
radv_encode_bind_pipeline_gfx12(VkCommandBuffer commandBuffer, uint32_t key)
radv_encode_bind_pipeline_gfx12(VkCommandBuffer commandBuffer,
const struct vk_acceleration_structure_build_state *state)
{
radv_bvh_build_bind_pipeline(commandBuffer, RADV_META_OBJECT_KEY_BVH_ENCODE, encode_gfx12_spv,
sizeof(encode_gfx12_spv), sizeof(struct encode_gfx12_args), 0);
@ -513,18 +501,19 @@ radv_encode_bind_pipeline_gfx12(VkCommandBuffer commandBuffer, uint32_t key)
}
static void
radv_encode_as(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos, VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr, uint32_t leaf_count, uint32_t key,
struct vk_acceleration_structure *dst)
radv_encode_as(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
struct acceleration_structure_layout layout;
radv_get_acceleration_structure_layout(device, leaf_count, build_info, &layout);
radv_get_acceleration_structure_layout(device, state, &layout);
if (key & RADV_ENCODE_KEY_COMPACT) {
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
if (state->config.encode_key[0] & RADV_ENCODE_KEY_COMPACT) {
uint32_t dst_offset = layout.internal_nodes_offset - layout.bvh_offset;
radv_update_memory_cp(cmd_buffer, intermediate_header_addr + offsetof(struct vk_ir_header, dst_node_offset),
&dst_offset, sizeof(uint32_t));
@ -533,35 +522,36 @@ radv_encode_as(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuild
}
const struct encode_args args = {
.intermediate_bvh = intermediate_as_addr,
.intermediate_bvh = intermediate_bvh_addr,
.output_bvh = vk_acceleration_structure_get_va(dst) + layout.bvh_offset,
.header = intermediate_header_addr,
.output_bvh_offset = layout.bvh_offset,
.leaf_node_count = leaf_count,
.geometry_type = vk_get_as_geometry_type(build_info),
.leaf_node_count = state->leaf_node_count,
.geometry_type = vk_get_as_geometry_type(state->build_info),
};
radv_bvh_build_set_args(commandBuffer, &args, sizeof(args));
struct radv_dispatch_info dispatch = {
.unaligned = true,
.ordered = true,
.blocks = {MAX2(leaf_count, 1), 1, 1},
.blocks = {MAX2(state->leaf_node_count, 1), 1, 1},
};
radv_compute_dispatch(cmd_buffer, &dispatch);
}
static void
radv_encode_as_gfx12(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr, VkDeviceAddress intermediate_header_addr,
uint32_t leaf_count, uint32_t key, struct vk_acceleration_structure *dst)
radv_encode_as_gfx12(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
struct acceleration_structure_layout layout;
radv_get_acceleration_structure_layout(device, leaf_count, build_info, &layout);
radv_get_acceleration_structure_layout(device, state, &layout);
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
struct vk_ir_header header = {
.sync_data =
@ -581,17 +571,17 @@ radv_encode_as_gfx12(VkCommandBuffer commandBuffer, const VkAccelerationStructur
cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2;
const struct encode_gfx12_args args = {
.intermediate_bvh = intermediate_as_addr,
.intermediate_bvh = intermediate_bvh_addr,
.output_base = vk_acceleration_structure_get_va(dst),
.header = intermediate_header_addr,
.output_bvh_offset = layout.bvh_offset,
.leaf_node_offsets_offset = layout.leaf_node_offsets_offset,
.leaf_node_count = leaf_count,
.geometry_type = vk_get_as_geometry_type(build_info),
.leaf_node_count = state->leaf_node_count,
.geometry_type = vk_get_as_geometry_type(state->build_info),
};
radv_bvh_build_set_args(commandBuffer, &args, sizeof(args));
uint32_t internal_count = MAX2(leaf_count, 2) - 1;
uint32_t internal_count = MAX2(state->leaf_node_count, 2) - 1;
struct radv_dispatch_info dispatch = {
.ordered = true,
@ -602,11 +592,11 @@ radv_encode_as_gfx12(VkCommandBuffer commandBuffer, const VkAccelerationStructur
}
static VkResult
radv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
radv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
if (!(key & RADV_ENCODE_KEY_COMPACT))
if (!(state->config.encode_key[1] & RADV_ENCODE_KEY_COMPACT))
return VK_SUCCESS;
/* Wait for encoding to finish. */
@ -623,22 +613,23 @@ radv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
}
static void
radv_init_header(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr, VkDeviceAddress intermediate_header_addr, uint32_t leaf_count,
uint32_t key, struct vk_acceleration_structure *dst)
radv_init_header(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
size_t base = offsetof(struct radv_accel_struct_header, compacted_size);
uint64_t instance_count = build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR ? leaf_count : 0;
uint64_t instance_count =
state->build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR ? state->leaf_node_count : 0;
struct acceleration_structure_layout layout;
radv_get_acceleration_structure_layout(device, leaf_count, build_info, &layout);
radv_get_acceleration_structure_layout(device, state, &layout);
if (key & RADV_ENCODE_KEY_COMPACT) {
if (state->config.encode_key[1] & RADV_ENCODE_KEY_COMPACT) {
base = offsetof(struct radv_accel_struct_header, geometry_type);
struct header_args args = {
@ -671,27 +662,27 @@ radv_init_header(VkCommandBuffer commandBuffer, const VkAccelerationStructureBui
header.size = header.serialization_size - sizeof(struct radv_accel_struct_serialization_header) -
sizeof(uint64_t) * header.instance_count;
header.build_flags = build_info->flags;
header.geometry_type = vk_get_as_geometry_type(build_info);
header.geometry_count = build_info->geometryCount;
header.build_flags = state->build_info->flags;
header.geometry_type = vk_get_as_geometry_type(state->build_info);
header.geometry_count = state->build_info->geometryCount;
header.primitive_base_indices_offset = layout.primitive_base_indices_offset;
radv_update_memory_cp(cmd_buffer, vk_acceleration_structure_get_va(dst) + base, (const char *)&header + base,
sizeof(header) - base);
if (device->rra_trace.accel_structs) {
uint64_t geometry_infos_size = build_info->geometryCount * sizeof(struct radv_accel_struct_geometry_info);
uint64_t geometry_infos_size = state->build_info->geometryCount * sizeof(struct radv_accel_struct_geometry_info);
struct radv_accel_struct_geometry_info *geometry_infos = malloc(geometry_infos_size);
if (!geometry_infos)
return;
for (uint32_t i = 0; i < build_info->geometryCount; i++) {
for (uint32_t i = 0; i < state->build_info->geometryCount; i++) {
const VkAccelerationStructureGeometryKHR *geometry =
build_info->pGeometries ? &build_info->pGeometries[i] : build_info->ppGeometries[i];
state->build_info->pGeometries ? &state->build_info->pGeometries[i] : state->build_info->ppGeometries[i];
geometry_infos[i].type = geometry->geometryType;
geometry_infos[i].flags = geometry->flags;
geometry_infos[i].primitive_count = build_range_infos[i].primitiveCount;
geometry_infos[i].primitive_count = state->build_range_infos[i].primitiveCount;
}
radv_CmdUpdateBuffer(commandBuffer, vk_buffer_to_handle(dst->buffer), dst->offset + layout.geometry_info_offset,
@ -700,9 +691,9 @@ radv_init_header(VkCommandBuffer commandBuffer, const VkAccelerationStructureBui
free(geometry_infos);
}
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(state->build_info);
if (device->vk.enabled_features.rayTracingPositionFetch && geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
uint32_t base_indices_size = sizeof(uint32_t) * build_info->geometryCount;
uint32_t base_indices_size = sizeof(uint32_t) * state->build_info->geometryCount;
uint32_t *base_indices = malloc(base_indices_size);
if (!base_indices) {
vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
@ -710,9 +701,9 @@ radv_init_header(VkCommandBuffer commandBuffer, const VkAccelerationStructureBui
}
uint32_t base_index = 0;
for (uint32_t i = 0; i < build_info->geometryCount; i++) {
for (uint32_t i = 0; i < state->build_info->geometryCount; i++) {
base_indices[i] = base_index;
base_index += build_range_infos[i].primitiveCount;
base_index += state->build_range_infos[i].primitiveCount;
}
radv_CmdUpdateBuffer(commandBuffer, vk_buffer_to_handle(dst->buffer),
@ -723,24 +714,23 @@ radv_init_header(VkCommandBuffer commandBuffer, const VkAccelerationStructureBui
}
static void
radv_init_update_scratch(VkCommandBuffer commandBuffer, VkDeviceAddress scratch,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos, uint32_t leaf_count,
struct vk_acceleration_structure *src_as, struct vk_acceleration_structure *dst_as)
radv_init_update_scratch(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_physical_device *pdev = radv_device_physical(device);
uint64_t scratch = state->build_info->scratchData.deviceAddress;
struct update_scratch_layout layout;
radv_get_update_scratch_layout(device, build_info, leaf_count, &layout);
radv_get_update_scratch_layout(device, state, &layout);
/* Prepare ready counts for internal nodes */
radv_fill_memory(cmd_buffer, scratch + layout.internal_ready_count_offset,
layout.size - layout.internal_ready_count_offset, 0x0, RADV_COPY_FLAGS_DEVICE_LOCAL);
if (radv_use_bvh8(pdev)) {
uint32_t data_size = sizeof(struct vk_bvh_geometry_data) * build_info->geometryCount;
uint32_t data_size = sizeof(struct vk_bvh_geometry_data) * state->build_info->geometryCount;
struct vk_bvh_geometry_data *data = malloc(data_size);
if (!data) {
vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
@ -748,13 +738,13 @@ radv_init_update_scratch(VkCommandBuffer commandBuffer, VkDeviceAddress scratch,
}
uint32_t first_id = 0;
for (uint32_t i = 0; i < build_info->geometryCount; i++) {
for (uint32_t i = 0; i < state->build_info->geometryCount; i++) {
const VkAccelerationStructureGeometryKHR *geom =
build_info->pGeometries ? &build_info->pGeometries[i] : build_info->ppGeometries[i];
state->build_info->pGeometries ? &state->build_info->pGeometries[i] : state->build_info->ppGeometries[i];
const VkAccelerationStructureBuildRangeInfoKHR *build_range_info = &build_range_infos[i];
const VkAccelerationStructureBuildRangeInfoKHR *build_range_info = &state->build_range_infos[i];
data[i] = vk_fill_geometry_data(build_info->type, first_id, i, geom, build_range_info);
data[i] = vk_fill_geometry_data(state->build_info->type, first_id, i, geom, build_range_info);
first_id += build_range_info->primitiveCount;
}
@ -767,7 +757,7 @@ radv_init_update_scratch(VkCommandBuffer commandBuffer, VkDeviceAddress scratch,
}
static void
radv_update_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
radv_update_bind_pipeline(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
@ -783,7 +773,7 @@ radv_update_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
if (radv_device_physical(device)->info.cp_sdma_ge_use_system_memory_scope)
cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2;
bool in_place = key & RADV_BUILD_FLAG_UPDATE_IN_PLACE;
bool in_place = state->config.update_key[0] & RADV_BUILD_FLAG_UPDATE_IN_PLACE;
uint32_t flags = in_place ? RADV_BUILD_FLAG_UPDATE_IN_PLACE : 0;
if (radv_use_bvh8(pdev)) {
@ -806,16 +796,16 @@ pack_geometry_id_and_flags(uint32_t geometry_id, uint32_t flags)
}
static void
radv_update_as(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos, uint32_t leaf_count, uint32_t key,
struct vk_acceleration_structure *src, struct vk_acceleration_structure *dst)
radv_update_as(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, src, state->build_info->srcAccelerationStructure);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
if (src != dst) {
struct acceleration_structure_layout layout;
radv_get_acceleration_structure_layout(device, leaf_count, build_info, &layout);
radv_get_acceleration_structure_layout(device, state, &layout);
/* Copy header/metadata */
const uint64_t src_va = vk_acceleration_structure_get_va(src);
@ -826,24 +816,24 @@ radv_update_as(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuild
}
struct update_scratch_layout layout;
radv_get_update_scratch_layout(device, build_info, leaf_count, &layout);
radv_get_update_scratch_layout(device, state, &layout);
struct update_args update_consts = {
.src = vk_acceleration_structure_get_va(src),
.dst = vk_acceleration_structure_get_va(dst),
.leaf_bounds = build_info->scratchData.deviceAddress,
.internal_ready_count = build_info->scratchData.deviceAddress + layout.internal_ready_count_offset,
.leaf_node_count = leaf_count,
.leaf_bounds = state->build_info->scratchData.deviceAddress,
.internal_ready_count = state->build_info->scratchData.deviceAddress + layout.internal_ready_count_offset,
.leaf_node_count = state->leaf_node_count,
};
uint32_t first_id = 0;
for (uint32_t i = 0; i < build_info->geometryCount; i++) {
for (uint32_t i = 0; i < state->build_info->geometryCount; i++) {
const VkAccelerationStructureGeometryKHR *geom =
build_info->pGeometries ? &build_info->pGeometries[i] : build_info->ppGeometries[i];
state->build_info->pGeometries ? &state->build_info->pGeometries[i] : state->build_info->ppGeometries[i];
const VkAccelerationStructureBuildRangeInfoKHR *build_range_info = &build_range_infos[i];
const VkAccelerationStructureBuildRangeInfoKHR *build_range_info = &state->build_range_infos[i];
update_consts.geom_data = vk_fill_geometry_data(build_info->type, first_id, i, geom, build_range_info);
update_consts.geom_data = vk_fill_geometry_data(state->build_info->type, first_id, i, geom, build_range_info);
radv_bvh_build_set_args(commandBuffer, &update_consts, sizeof(update_consts));
@ -854,16 +844,16 @@ radv_update_as(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuild
}
static void
radv_update_as_gfx12(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos, uint32_t leaf_count,
uint32_t key, struct vk_acceleration_structure *src, struct vk_acceleration_structure *dst)
radv_update_as_gfx12(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, src, state->build_info->srcAccelerationStructure);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
if (src != dst) {
struct acceleration_structure_layout layout;
radv_get_acceleration_structure_layout(device, leaf_count, build_info, &layout);
radv_get_acceleration_structure_layout(device, state, &layout);
/* Copy header/metadata */
const uint64_t src_va = vk_acceleration_structure_get_va(src);
@ -874,15 +864,15 @@ radv_update_as_gfx12(VkCommandBuffer commandBuffer, const VkAccelerationStructur
}
struct update_scratch_layout layout;
radv_get_update_scratch_layout(device, build_info, leaf_count, &layout);
radv_get_update_scratch_layout(device, state, &layout);
struct update_gfx12_args update_consts = {
.src = vk_acceleration_structure_get_va(src),
.dst = vk_acceleration_structure_get_va(dst),
.geom_data = build_info->scratchData.deviceAddress + layout.geometry_data_offset,
.bounds = build_info->scratchData.deviceAddress + layout.bounds_offsets,
.internal_ready_count = build_info->scratchData.deviceAddress + layout.internal_ready_count_offset,
.leaf_node_count = leaf_count,
.geom_data = state->build_info->scratchData.deviceAddress + layout.geometry_data_offset,
.bounds = state->build_info->scratchData.deviceAddress + layout.bounds_offsets,
.internal_ready_count = state->build_info->scratchData.deviceAddress + layout.internal_ready_count_offset,
.leaf_node_count = state->leaf_node_count,
};
radv_bvh_build_set_args(commandBuffer, &update_consts, sizeof(update_consts));

View file

@ -144,12 +144,13 @@ get_bvh_layout(VkGeometryTypeKHR geometry_type,
layout->size = offset;
}
VkDeviceSize get_bvh_size(VkDevice device,
const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo,
uint32_t leaf_count)
VkDeviceSize
get_bvh_size(VkDevice device,
const struct vk_acceleration_structure_build_state *state)
{
struct bvh_layout layout;
get_bvh_layout(vk_get_as_geometry_type(pBuildInfo), leaf_count, &layout);
get_bvh_layout(vk_get_as_geometry_type(state->build_info),
state->leaf_node_count, &layout);
return layout.size;
}
@ -162,20 +163,19 @@ enum tu_header_key {
};
static void
tu_get_build_config(
struct vk_device *device,
struct vk_build_config *config,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info)
tu_get_build_config(VkDevice device,
struct vk_acceleration_structure_build_state *state)
{
config->encode_key[1] =
(build_info->flags &
state->config.encode_key[1] =
(state->build_info->flags &
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR)
? HEADER_USE_DISPATCH
: HEADER_NO_DISPATCH;
}
static VkResult
encode_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
encode_bind_pipeline(VkCommandBuffer commandBuffer,
const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
struct tu_device *device = cmdbuf->device;
@ -195,17 +195,20 @@ encode_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
static void
encode(VkCommandBuffer commandBuffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr,
uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst)
const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst,
state->build_info->dstAccelerationStructure);
struct tu_device *device = cmdbuf->device;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
VkGeometryTypeKHR geometry_type =
vk_get_as_geometry_type(state->build_info);
uint64_t intermediate_header_addr =
state->build_info->scratchData.deviceAddress +
state->scratch.header_offset;
uint64_t intermediate_bvh_addr =
state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
VkPipeline pipeline;
VkPipelineLayout layout;
@ -213,14 +216,15 @@ encode(VkCommandBuffer commandBuffer,
sizeof(encode_args), &pipeline, &layout);
struct bvh_layout bvh_layout;
get_bvh_layout(geometry_type, leaf_count, &bvh_layout);
get_bvh_layout(geometry_type, state->leaf_node_count, &bvh_layout);
const struct encode_args args = {
.intermediate_bvh = intermediate_as_addr,
.output_bvh = vk_acceleration_structure_get_va(dst) + bvh_layout.bvh_offset,
.intermediate_bvh = intermediate_bvh_addr,
.output_bvh =
vk_acceleration_structure_get_va(dst) + bvh_layout.bvh_offset,
.header = intermediate_header_addr,
.output_bvh_offset = bvh_layout.bvh_offset,
.leaf_node_count = leaf_count,
.leaf_node_count = state->leaf_node_count,
.geometry_type = geometry_type,
};
vk_common_CmdPushConstants(commandBuffer, layout,
@ -238,12 +242,13 @@ encode(VkCommandBuffer commandBuffer,
}
static VkResult
header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
header_bind_pipeline(VkCommandBuffer commandBuffer,
const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
struct tu_device *device = cmdbuf->device;
if (key == HEADER_USE_DISPATCH) {
if (state->config.encode_key[1] == HEADER_USE_DISPATCH) {
VkPipeline pipeline;
VkPipelineLayout layout;
VkResult result =
@ -272,29 +277,30 @@ header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
static void
header(VkCommandBuffer commandBuffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr,
uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst)
const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst,
state->build_info->dstAccelerationStructure);
struct tu_device *device = cmdbuf->device;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
VkGeometryTypeKHR geometry_type =
vk_get_as_geometry_type(state->build_info);
struct bvh_layout bvh_layout;
get_bvh_layout(geometry_type, leaf_count, &bvh_layout);
get_bvh_layout(geometry_type, state->leaf_node_count, &bvh_layout);
uint64_t intermediate_header_addr =
state->build_info->scratchData.deviceAddress +
state->scratch.header_offset;
VkDeviceAddress header_addr = vk_acceleration_structure_get_va(dst);
size_t base = offsetof(struct tu_accel_struct_header, copy_dispatch_size);
uint32_t instance_count =
geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR ? leaf_count : 0;
uint32_t instance_count = geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR
? state->leaf_node_count
: 0;
if (key == HEADER_USE_DISPATCH) {
if (state->config.encode_key[1] == HEADER_USE_DISPATCH) {
base = offsetof(struct tu_accel_struct_header, instance_count);
VkPipeline pipeline;
VkPipelineLayout layout;

View file

@ -145,16 +145,10 @@ lvp_cmd_fill_buffer_addr(VkCommandBuffer cmdbuf, VkDeviceAddress addr,
}
static void
lvp_enqueue_encode_as(VkCommandBuffer commandBuffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr,
uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst)
lvp_enqueue_encode_as(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct vk_cmd_queue_entry *entry =
vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct vk_cmd_queue_entry),
@ -172,11 +166,14 @@ lvp_enqueue_encode_as(VkCommandBuffer commandBuffer,
return;
}
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
cmd->dst = dst;
cmd->intermediate_as_addr = intermediate_as_addr;
cmd->intermediate_as_addr = intermediate_bvh_addr;
cmd->intermediate_header_addr = intermediate_header_addr;
cmd->leaf_count = leaf_count;
cmd->geometry_type = vk_get_as_geometry_type(build_info);
cmd->leaf_count = state->leaf_node_count;
cmd->geometry_type = vk_get_as_geometry_type(state->build_info);
entry->driver_data = cmd;
@ -627,18 +624,16 @@ lvp_CopyAccelerationStructureToMemoryKHR(VkDevice _device, VkDeferredOperationKH
}
static VkDeviceSize
lvp_get_as_size(VkDevice device,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
uint32_t leaf_count)
lvp_get_as_size(VkDevice device, const struct vk_acceleration_structure_build_state *state)
{
uint32_t internal_node_count = MAX2(leaf_count, 2) - 1;
uint32_t internal_node_count = MAX2(state->leaf_node_count, 2) - 1;
uint32_t nodes_size = internal_node_count * sizeof(struct lvp_bvh_box_node);
uint32_t ir_leaf_node_size = 0;
uint32_t output_leaf_node_size = 0;
lvp_get_leaf_node_size(vk_get_as_geometry_type(build_info), &ir_leaf_node_size, &output_leaf_node_size);
lvp_get_leaf_node_size(vk_get_as_geometry_type(state->build_info), &ir_leaf_node_size, &output_leaf_node_size);
nodes_size += leaf_count * output_leaf_node_size;
nodes_size += state->leaf_node_count * output_leaf_node_size;
nodes_size = util_align_npot(nodes_size, LVP_BVH_NODE_PREFETCH_SIZE);
@ -646,8 +641,7 @@ lvp_get_as_size(VkDevice device,
}
static VkResult
lvp_encode_bind_pipeline(VkCommandBuffer cmd_buffer,
uint32_t key)
lvp_encode_bind_pipeline(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state)
{
return VK_SUCCESS;
}

View file

@ -347,24 +347,21 @@ get_bvh_layout(VkGeometryTypeKHR geometry_type, uint32_t leaf_count,
}
static VkDeviceSize
anv_get_as_size(VkDevice device,
const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo,
uint32_t leaf_count)
anv_get_as_size(VkDevice device, const struct vk_acceleration_structure_build_state *state)
{
struct bvh_layout layout;
get_bvh_layout(vk_get_as_geometry_type(pBuildInfo), leaf_count, &layout);
get_bvh_layout(vk_get_as_geometry_type(state->build_info), state->leaf_node_count, &layout);
return layout.size;
}
static void
anv_get_build_config(struct vk_device *device, struct vk_build_config *config,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info)
anv_get_build_config(VkDevice device, struct vk_acceleration_structure_build_state *state)
{
config->encode_key[1] = (build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR) ? 1 : 0;
state->config.encode_key[1] = (state->build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR) ? 1 : 0;
}
static VkResult
anv_encode_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
anv_encode_bind_pipeline(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_device *device = cmd_buffer->device;
@ -385,21 +382,19 @@ anv_encode_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
}
static void
anv_encode_as(VkCommandBuffer commandBuffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr, uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst)
anv_encode_as(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
if (INTEL_DEBUG(DEBUG_BVH_NO_BUILD))
return;
VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct anv_device *device = cmd_buffer->device;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(state->build_info);
VkPipeline pipeline;
VkPipelineLayout layout;
@ -413,15 +408,15 @@ anv_encode_as(VkCommandBuffer commandBuffer,
STATIC_ASSERT(sizeof(struct anv_internal_node) == ANV_RT_INTERNAL_NODE_SIZE);
struct bvh_layout bvh_layout;
get_bvh_layout(geometry_type, leaf_count, &bvh_layout);
get_bvh_layout(geometry_type, state->leaf_node_count, &bvh_layout);
const struct encode_args args = {
.intermediate_bvh = intermediate_as_addr,
.intermediate_bvh = intermediate_bvh_addr,
.output_bvh = vk_acceleration_structure_get_va(dst) +
bvh_layout.bvh_offset,
.header = intermediate_header_addr,
.output_bvh_offset = bvh_layout.bvh_offset,
.leaf_node_count = leaf_count,
.leaf_node_count = state->leaf_node_count,
.geometry_type = geometry_type,
};
@ -444,11 +439,11 @@ anv_encode_as(VkCommandBuffer commandBuffer,
}
static VkResult
anv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
anv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (key == 1) {
if (state->config.encode_key[1] == 1) {
VkPipeline pipeline;
VkPipelineLayout layout;
VkResult result = get_pipeline_spv(cmd_buffer->device, "header",
@ -466,21 +461,19 @@ anv_init_header_bind_pipeline(VkCommandBuffer commandBuffer, uint32_t key)
}
static void
anv_init_header(VkCommandBuffer commandBuffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr, uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst)
anv_init_header(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct anv_device *device = cmd_buffer->device;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(build_info);
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
VkGeometryTypeKHR geometry_type = vk_get_as_geometry_type(state->build_info);
struct bvh_layout bvh_layout;
get_bvh_layout(geometry_type, leaf_count, &bvh_layout);
get_bvh_layout(geometry_type, state->leaf_node_count, &bvh_layout);
VkDeviceAddress header_addr = vk_acceleration_structure_get_va(dst);
@ -488,9 +481,9 @@ anv_init_header(VkCommandBuffer commandBuffer,
copy_dispatch_size);
uint32_t instance_count = geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR ?
leaf_count : 0;
state->leaf_node_count : 0;
if (key == 1) {
if (state->config.encode_key[1] == 1) {
/* Add a barrier to ensure the writes from encode.comp is ready to be
* read by header.comp
*/
@ -573,8 +566,8 @@ anv_init_header(VkCommandBuffer commandBuffer,
ANV_PIPE_HDC_PIPELINE_FLUSH_BIT |
ANV_PIPE_UNTYPED_DATAPORT_CACHE_FLUSH_BIT);
debug_record_as_to_bvh_dump(cmd_buffer, header_addr, bvh_layout.size,
intermediate_header_addr, intermediate_as_addr,
leaf_count, geometry_type);
intermediate_header_addr, intermediate_bvh_addr,
state->leaf_node_count, geometry_type);
}
}

View file

@ -112,64 +112,38 @@ vk_common_GetAccelerationStructureDeviceAddressKHR(
#define KEY_ID_PAIR_SIZE 8
#define MORTON_BIT_SIZE 24
struct scratch_layout {
uint32_t size;
uint32_t update_size;
uint32_t header_offset;
/* Used for BUILD only. */
uint32_t sort_buffer_offset[2];
uint32_t sort_internal_offset;
uint32_t ploc_prefix_sum_partition_offset;
uint32_t lbvh_node_offset;
uint32_t ir_offset;
uint32_t internal_node_offset;
};
static struct vk_build_config
build_config(struct vk_device *device, uint32_t leaf_count,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const struct vk_acceleration_structure_build_ops *ops)
static void
vk_acceleration_structure_build_state_init(struct vk_acceleration_structure_build_state *state,
struct vk_device *device, uint32_t leaf_count,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const struct vk_acceleration_structure_build_args *args)
{
struct vk_build_config config = {0};
state->build_info = build_info;
state->leaf_node_count = leaf_count;
if (leaf_count <= 4)
config.internal_type = VK_INTERNAL_BUILD_TYPE_LBVH;
state->config.internal_type = VK_INTERNAL_BUILD_TYPE_LBVH;
else if (build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR)
config.internal_type = VK_INTERNAL_BUILD_TYPE_PLOC;
state->config.internal_type = VK_INTERNAL_BUILD_TYPE_PLOC;
else if (!(build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR) &&
!(build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR))
config.internal_type = VK_INTERNAL_BUILD_TYPE_PLOC;
state->config.internal_type = VK_INTERNAL_BUILD_TYPE_PLOC;
else
config.internal_type = VK_INTERNAL_BUILD_TYPE_LBVH;
state->config.internal_type = VK_INTERNAL_BUILD_TYPE_LBVH;
if (build_info->mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR &&
build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR &&
ops->update_as[0])
config.internal_type = VK_INTERNAL_BUILD_TYPE_UPDATE;
device->as_build_ops->update_as[0])
state->config.internal_type = VK_INTERNAL_BUILD_TYPE_UPDATE;
if ((build_info->flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR) &&
build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR &&
ops->update_as[0])
config.updateable = true;
device->as_build_ops->update_as[0])
state->config.updateable = true;
if (ops->get_build_config)
ops->get_build_config(device, &config, build_info);
if (device->as_build_ops->get_build_config)
device->as_build_ops->get_build_config(vk_device_to_handle(device), state);
return config;
}
static void
get_scratch_layout(struct vk_device *device,
uint32_t leaf_count,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const struct vk_acceleration_structure_build_args *args,
struct scratch_layout *scratch)
{
uint32_t internal_count = MAX2(leaf_count, 2) - 1;
radix_sort_vk_memory_requirements_t requirements = {
@ -193,76 +167,65 @@ get_scratch_layout(struct vk_device *device,
unreachable("Unknown VkGeometryTypeKHR");
}
uint32_t offset = 0;
uint32_t ploc_scratch_space = 0;
uint32_t lbvh_node_space = 0;
struct vk_build_config config = build_config(device, leaf_count, build_info,
device->as_build_ops);
if (config.internal_type == VK_INTERNAL_BUILD_TYPE_PLOC)
if (state->config.internal_type == VK_INTERNAL_BUILD_TYPE_PLOC)
ploc_scratch_space = DIV_ROUND_UP(leaf_count, PLOC_WORKGROUP_SIZE) * sizeof(struct ploc_prefix_scan_partition);
else
lbvh_node_space = sizeof(struct lbvh_node_info) * internal_count;
uint32_t encode_scratch_size = 0;
if (device->as_build_ops->get_encode_scratch_size) {
for (uint32_t i = 0; i < MAX_ENCODE_PASSES; i++) {
uint32_t tmp_size = device->as_build_ops->get_encode_scratch_size(device, config.encode_key[i], leaf_count);
encode_scratch_size = MAX2(encode_scratch_size, tmp_size);
}
}
if (device->as_build_ops->get_encode_scratch_size)
encode_scratch_size = device->as_build_ops->get_encode_scratch_size(vk_device_to_handle(device), state);
scratch->header_offset = offset;
state->scratch.header_offset = offset;
offset += sizeof(struct vk_ir_header);
/* The encode passes should not need node sorting state. Reuse the space reserved for node sorting. */
uint32_t encode_scratch_end = offset + encode_scratch_size;
scratch->sort_buffer_offset[0] = offset;
state->scratch.sort_buffer_offset[0] = offset;
offset += requirements.keyvals_size;
scratch->sort_buffer_offset[1] = offset;
state->scratch.sort_buffer_offset[1] = offset;
offset += requirements.keyvals_size;
scratch->sort_internal_offset = offset;
state->scratch.sort_internal_offset = offset;
/* Internal sorting data is not needed when PLOC/LBVH are invoked,
* save space by aliasing them */
scratch->ploc_prefix_sum_partition_offset = offset;
scratch->lbvh_node_offset = offset;
state->scratch.ploc_prefix_sum_partition_offset = offset;
state->scratch.lbvh_node_offset = offset;
offset += MAX3(requirements.internal_size, ploc_scratch_space, lbvh_node_space);
/* Make sure encode scratch space does not overlap the BVH. */
offset = MAX2(offset, encode_scratch_end);
scratch->ir_offset = offset;
state->scratch.ir_offset = offset;
offset += ir_leaf_size * leaf_count;
scratch->internal_node_offset = offset;
state->scratch.internal_node_offset = offset;
offset += sizeof(struct vk_ir_box_node) * internal_count;
scratch->size = offset;
state->scratch.size = offset;
if (build_info->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR &&
device->as_build_ops->update_as[0]) {
scratch->update_size =
device->as_build_ops->get_update_scratch_size(device, build_info, leaf_count);
state->scratch.update_size = device->as_build_ops->get_update_scratch_size(vk_device_to_handle(device), state);
} else {
scratch->update_size = offset;
state->scratch.update_size = offset;
}
}
struct bvh_state {
struct vk_acceleration_structure_build_state vk;
uint32_t scratch_offset;
uint32_t leaf_node_count;
uint32_t internal_node_count;
struct scratch_layout scratch;
struct vk_build_config config;
/* Radix sort state */
uint32_t scatter_blocks;
uint32_t count_ru_scatter;
@ -548,15 +511,15 @@ build_leaves(VkCommandBuffer commandBuffer,
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
if (bvh_states[i].config.updateable != updateable)
if (bvh_states[i].vk.config.updateable != updateable)
continue;
struct leaf_args leaf_consts = {
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
.ids = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[0],
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.header_offset,
.ids = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[0],
};
for (unsigned j = 0; j < pInfos[i].geometryCount; ++j) {
@ -568,13 +531,13 @@ build_leaves(VkCommandBuffer commandBuffer,
if (build_range_info->primitiveCount == 0)
continue;
leaf_consts.geom_data = vk_fill_geometry_data(pInfos[i].type, bvh_states[i].leaf_node_count, j, geom, build_range_info);
leaf_consts.geom_data = vk_fill_geometry_data(pInfos[i].type, bvh_states[i].vk.leaf_node_count, j, geom, build_range_info);
disp->CmdPushConstants(commandBuffer, layout,
VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(leaf_consts), &leaf_consts);
device->cmd_dispatch_unaligned(commandBuffer, build_range_info->primitiveCount, 1, 1);
bvh_states[i].leaf_node_count += build_range_info->primitiveCount;
bvh_states[i].vk.leaf_node_count += build_range_info->primitiveCount;
}
}
@ -617,17 +580,17 @@ morton_generate(VkCommandBuffer commandBuffer, struct vk_device *device,
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
const struct morton_args consts = {
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
.ids = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[0],
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.header_offset,
.ids = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[0],
};
disp->CmdPushConstants(commandBuffer, layout,
VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(consts), &consts);
device->cmd_dispatch_unaligned(commandBuffer, bvh_states[i].leaf_node_count, 1, 1);
device->cmd_dispatch_unaligned(commandBuffer, bvh_states[i].vk.leaf_node_count, 1, 1);
}
if (args->emit_markers)
@ -676,10 +639,10 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
uint32_t passes = (key_bits + RS_RADIX_LOG2 - 1) / RS_RADIX_LOG2;
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].leaf_node_count)
bvh_states[i].scratch_offset = bvh_states[i].scratch.sort_buffer_offset[passes & 1];
if (bvh_states[i].vk.leaf_node_count)
bvh_states[i].scratch_offset = bvh_states[i].vk.scratch.sort_buffer_offset[passes & 1];
else
bvh_states[i].scratch_offset = bvh_states[i].scratch.sort_buffer_offset[0];
bvh_states[i].scratch_offset = bvh_states[i].vk.scratch.sort_buffer_offset[0];
}
/*
@ -710,25 +673,25 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
uint32_t pass_idx = (keyval_bytes - passes);
for (uint32_t i = 0; i < infoCount; ++i) {
if (!bvh_states[i].leaf_node_count)
if (!bvh_states[i].vk.leaf_node_count)
continue;
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[0];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_internal_offset;
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[0];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_internal_offset;
bvh_states[i].scatter_blocks = (bvh_states[i].leaf_node_count + scatter_block_kvs - 1) / scatter_block_kvs;
bvh_states[i].scatter_blocks = (bvh_states[i].vk.leaf_node_count + scatter_block_kvs - 1) / scatter_block_kvs;
bvh_states[i].count_ru_scatter = bvh_states[i].scatter_blocks * scatter_block_kvs;
bvh_states[i].histo_blocks = (bvh_states[i].count_ru_scatter + histo_block_kvs - 1) / histo_block_kvs;
bvh_states[i].count_ru_histo = bvh_states[i].histo_blocks * histo_block_kvs;
/* Fill with max values */
if (bvh_states[i].count_ru_histo > bvh_states[i].leaf_node_count) {
if (bvh_states[i].count_ru_histo > bvh_states[i].vk.leaf_node_count) {
device->cmd_fill_buffer_addr(commandBuffer, keyvals_even_addr +
bvh_states[i].leaf_node_count * keyval_bytes,
(bvh_states[i].count_ru_histo - bvh_states[i].leaf_node_count) * keyval_bytes,
bvh_states[i].vk.leaf_node_count * keyval_bytes,
(bvh_states[i].count_ru_histo - bvh_states[i].vk.leaf_node_count) * keyval_bytes,
0xFFFFFFFF);
}
@ -764,13 +727,13 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
rs->pipelines.named.histogram);
for (uint32_t i = 0; i < infoCount; ++i) {
if (!bvh_states[i].leaf_node_count)
if (!bvh_states[i].vk.leaf_node_count)
continue;
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[0];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_internal_offset;
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[0];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_internal_offset;
/* Dispatch histogram */
struct rs_push_histogram push_histogram = {
@ -796,12 +759,12 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
rs->pipelines.named.prefix);
for (uint32_t i = 0; i < infoCount; ++i) {
if (!bvh_states[i].leaf_node_count)
if (!bvh_states[i].vk.leaf_node_count)
continue;
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_internal_offset;
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_internal_offset;
struct rs_push_prefix push_prefix = {
.devaddr_histograms = internal_addr + rs->internal.histograms.offset,
@ -819,9 +782,9 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
uint32_t histogram_offset = pass_idx * (RS_RADIX_SIZE * sizeof(uint32_t));
for (uint32_t i = 0; i < infoCount; i++) {
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[0];
uint64_t keyvals_odd_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_buffer_offset[1];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.sort_internal_offset;
uint64_t keyvals_even_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[0];
uint64_t keyvals_odd_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_buffer_offset[1];
uint64_t internal_addr = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.sort_internal_offset;
bvh_states[i].push_scatter = (struct rs_push_scatter){
.devaddr_keyvals_even = keyvals_even_addr,
@ -846,9 +809,9 @@ morton_sort(VkCommandBuffer commandBuffer, struct vk_device *device,
: rs->pipeline_layouts.named.scatter[pass_dword].odd;
for (uint32_t i = 0; i < infoCount; i++) {
if (!bvh_states[i].leaf_node_count)
if (!bvh_states[i].vk.leaf_node_count)
continue;
if (bvh_states[i].config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE)
continue;
bvh_states[i].push_scatter.pass_offset = (pass_idx & 3) * RS_RADIX_LOG2;
@ -906,18 +869,18 @@ lbvh_build_internal(VkCommandBuffer commandBuffer,
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].config.internal_type != VK_INTERNAL_BUILD_TYPE_LBVH)
if (bvh_states[i].vk.config.internal_type != VK_INTERNAL_BUILD_TYPE_LBVH)
continue;
uint32_t src_scratch_offset = bvh_states[i].scratch_offset;
uint32_t internal_node_count = MAX2(bvh_states[i].leaf_node_count, 2) - 1;
uint32_t internal_node_count = MAX2(bvh_states[i].vk.leaf_node_count, 2) - 1;
const struct lbvh_main_args consts = {
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ir_offset,
.src_ids = pInfos[i].scratchData.deviceAddress + src_scratch_offset,
.node_info = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.lbvh_node_offset,
.id_count = bvh_states[i].leaf_node_count,
.internal_node_base = bvh_states[i].scratch.internal_node_offset - bvh_states[i].scratch.ir_offset,
.node_info = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.lbvh_node_offset,
.id_count = bvh_states[i].vk.leaf_node_count,
.internal_node_base = bvh_states[i].vk.scratch.internal_node_offset - bvh_states[i].vk.scratch.ir_offset,
};
disp->CmdPushConstants(commandBuffer, layout,
@ -943,14 +906,14 @@ lbvh_build_internal(VkCommandBuffer commandBuffer,
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].config.internal_type != VK_INTERNAL_BUILD_TYPE_LBVH)
if (bvh_states[i].vk.config.internal_type != VK_INTERNAL_BUILD_TYPE_LBVH)
continue;
const struct lbvh_generate_ir_args consts = {
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.node_info = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.lbvh_node_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
.internal_node_base = bvh_states[i].scratch.internal_node_offset - bvh_states[i].scratch.ir_offset,
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ir_offset,
.node_info = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.lbvh_node_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.header_offset,
.internal_node_base = bvh_states[i].vk.scratch.internal_node_offset - bvh_states[i].vk.scratch.ir_offset,
};
disp->CmdPushConstants(commandBuffer, layout,
@ -995,27 +958,27 @@ ploc_build_internal(VkCommandBuffer commandBuffer,
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
for (uint32_t i = 0; i < infoCount; ++i) {
if (bvh_states[i].config.internal_type != VK_INTERNAL_BUILD_TYPE_PLOC)
if (bvh_states[i].vk.config.internal_type != VK_INTERNAL_BUILD_TYPE_PLOC)
continue;
uint32_t src_scratch_offset = bvh_states[i].scratch_offset;
uint32_t dst_scratch_offset = (src_scratch_offset == bvh_states[i].scratch.sort_buffer_offset[0])
? bvh_states[i].scratch.sort_buffer_offset[1]
: bvh_states[i].scratch.sort_buffer_offset[0];
uint32_t dst_scratch_offset = (src_scratch_offset == bvh_states[i].vk.scratch.sort_buffer_offset[0])
? bvh_states[i].vk.scratch.sort_buffer_offset[1]
: bvh_states[i].vk.scratch.sort_buffer_offset[0];
const struct ploc_args consts = {
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
.bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ir_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.header_offset,
.ids_0 = pInfos[i].scratchData.deviceAddress + src_scratch_offset,
.ids_1 = pInfos[i].scratchData.deviceAddress + dst_scratch_offset,
.prefix_scan_partitions =
pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ploc_prefix_sum_partition_offset,
.internal_node_offset = bvh_states[i].scratch.internal_node_offset - bvh_states[i].scratch.ir_offset,
pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.ploc_prefix_sum_partition_offset,
.internal_node_offset = bvh_states[i].vk.scratch.internal_node_offset - bvh_states[i].vk.scratch.ir_offset,
};
disp->CmdPushConstants(commandBuffer, layout,
VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(consts), &consts);
disp->CmdDispatch(commandBuffer, MAX2(DIV_ROUND_UP(bvh_states[i].leaf_node_count, PLOC_WORKGROUP_SIZE), 1), 1, 1);
disp->CmdDispatch(commandBuffer, MAX2(DIV_ROUND_UP(bvh_states[i].vk.leaf_node_count, PLOC_WORKGROUP_SIZE), 1), 1, 1);
}
if (args->emit_markers)
@ -1067,30 +1030,31 @@ vk_cmd_build_acceleration_structures(VkCommandBuffer commandBuffer,
leaf_node_count += ppBuildRangeInfos[i][j].primitiveCount;
}
get_scratch_layout(device, leaf_node_count, pInfos + i, args, &bvh_states[i].scratch);
vk_acceleration_structure_build_state_init(&bvh_states[i].vk, cmd_buffer->base.device, leaf_node_count,
pInfos + i, args);
struct vk_build_config config = build_config(cmd_buffer->base.device, leaf_node_count, pInfos + i,
device->as_build_ops);
bvh_states[i].config = config;
bvh_states[i].vk.build_range_infos = ppBuildRangeInfos[i];
/* The leaf node dispatch code uses leaf_node_count as a base index. */
bvh_states[i].vk.leaf_node_count = 0;
if (config.updateable)
if (bvh_states[i].vk.config.updateable)
batch_state.any_updateable = true;
else
batch_state.any_non_updateable = true;
if (config.internal_type == VK_INTERNAL_BUILD_TYPE_PLOC) {
if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_PLOC) {
batch_state.any_ploc = true;
} else if (config.internal_type == VK_INTERNAL_BUILD_TYPE_LBVH) {
} else if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_LBVH) {
batch_state.any_lbvh = true;
} else if (config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE) {
} else if (bvh_states[i].vk.config.internal_type == VK_INTERNAL_BUILD_TYPE_UPDATE) {
batch_state.any_update = true;
/* For updates, the leaf node pass never runs, so set leaf_node_count here. */
bvh_states[i].leaf_node_count = leaf_node_count;
bvh_states[i].vk.leaf_node_count = leaf_node_count;
} else {
unreachable("Unknown internal_build_type");
}
if (bvh_states[i].config.internal_type != VK_INTERNAL_BUILD_TYPE_UPDATE) {
if (bvh_states[i].vk.config.internal_type != VK_INTERNAL_BUILD_TYPE_UPDATE) {
/* The internal node count is updated in lbvh_build_internal for LBVH
* and from the PLOC shader for PLOC. */
struct vk_ir_header header = {
@ -1106,14 +1070,10 @@ vk_cmd_build_acceleration_structures(VkCommandBuffer commandBuffer,
},
};
device->write_buffer_cp(commandBuffer, pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
device->write_buffer_cp(commandBuffer, pInfos[i].scratchData.deviceAddress + bvh_states[i].vk.scratch.header_offset,
&header, sizeof(header));
} else {
VK_FROM_HANDLE(vk_acceleration_structure, src_as, pInfos[i].srcAccelerationStructure);
VK_FROM_HANDLE(vk_acceleration_structure, dst_as, pInfos[i].dstAccelerationStructure);
ops->init_update_scratch(commandBuffer, pInfos[i].scratchData.deviceAddress,
&pInfos[i], ppBuildRangeInfos[i], leaf_node_count, src_as, dst_as);
ops->init_update_scratch(commandBuffer, &bvh_states[i].vk);
}
}
@ -1202,7 +1162,7 @@ vk_cmd_build_acceleration_structures(VkCommandBuffer commandBuffer,
uint32_t num_leaves = 0;
uint32_t num_internal_node = 0;
for ( uint32_t i = 0; i < infoCount; i++) {
num_leaves += bvh_states[i].leaf_node_count;
num_leaves += bvh_states[i].vk.leaf_node_count;
num_internal_node += bvh_states[i].internal_node_count;
}
@ -1228,49 +1188,31 @@ vk_cmd_build_acceleration_structures(VkCommandBuffer commandBuffer,
continue;
if (!progress) {
update = (bvh_states[i].config.internal_type ==
update = (bvh_states[i].vk.config.internal_type ==
VK_INTERNAL_BUILD_TYPE_UPDATE);
if (update && !ops->update_as[pass])
continue;
if (!update && !ops->encode_as[pass])
continue;
encode_key = bvh_states[i].config.encode_key[pass];
update_key = bvh_states[i].config.update_key[pass];
encode_key = bvh_states[i].vk.config.encode_key[pass];
update_key = bvh_states[i].vk.config.update_key[pass];
progress = true;
if (update)
ops->update_bind_pipeline[pass](commandBuffer, update_key);
ops->update_bind_pipeline[pass](commandBuffer, &bvh_states[i].vk);
else
ops->encode_bind_pipeline[pass](commandBuffer, encode_key);
ops->encode_bind_pipeline[pass](commandBuffer, &bvh_states[i].vk);
} else {
if (update != (bvh_states[i].config.internal_type ==
if (update != (bvh_states[i].vk.config.internal_type ==
VK_INTERNAL_BUILD_TYPE_UPDATE) ||
encode_key != bvh_states[i].config.encode_key[pass] ||
update_key != bvh_states[i].config.update_key[pass])
encode_key != bvh_states[i].vk.config.encode_key[pass] ||
update_key != bvh_states[i].vk.config.update_key[pass])
continue;
}
VK_FROM_HANDLE(vk_acceleration_structure, accel_struct, pInfos[i].dstAccelerationStructure);
if (update) {
VK_FROM_HANDLE(vk_acceleration_structure, src, pInfos[i].srcAccelerationStructure);
ops->update_as[pass](commandBuffer,
&pInfos[i],
ppBuildRangeInfos[i],
bvh_states[i].leaf_node_count,
update_key,
src,
accel_struct);
} else {
ops->encode_as[pass](commandBuffer,
&pInfos[i],
ppBuildRangeInfos[i],
pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
bvh_states[i].leaf_node_count,
encode_key,
accel_struct);
}
if (update)
ops->update_as[pass](commandBuffer, &bvh_states[i].vk);
else
ops->encode_as[pass](commandBuffer, &bvh_states[i].vk);
bvh_states[i].last_encode_pass = pass + 1;
}
@ -1299,14 +1241,12 @@ vk_get_as_build_sizes(VkDevice _device, VkAccelerationStructureBuildTypeKHR buil
for (uint32_t i = 0; i < pBuildInfo->geometryCount; i++)
leaf_count += pMaxPrimitiveCounts[i];
struct scratch_layout scratch;
struct vk_acceleration_structure_build_state state = { 0 };
vk_acceleration_structure_build_state_init(&state, device, leaf_count, pBuildInfo, args);
get_scratch_layout(device, leaf_count, pBuildInfo, args, &scratch);
pSizeInfo->accelerationStructureSize =
device->as_build_ops->get_as_size(_device, pBuildInfo, leaf_count);
pSizeInfo->updateScratchSize = scratch.update_size;
pSizeInfo->buildScratchSize = scratch.size;
pSizeInfo->accelerationStructureSize = device->as_build_ops->get_as_size(_device, &state);
pSizeInfo->updateScratchSize = state.scratch.update_size;
pSizeInfo->buildScratchSize = state.scratch.size;
}
/* Return true if the common framework supports using this format for loading

View file

@ -81,46 +81,50 @@ struct vk_build_config {
uint32_t update_key[MAX_ENCODE_PASSES];
};
struct vk_scratch_layout {
uint32_t size;
uint32_t update_size;
uint32_t header_offset;
/* Used for BUILD only. */
uint32_t sort_buffer_offset[2];
uint32_t sort_internal_offset;
uint32_t ploc_prefix_sum_partition_offset;
uint32_t lbvh_node_offset;
uint32_t ir_offset;
uint32_t internal_node_offset;
};
struct vk_acceleration_structure_build_state {
const VkAccelerationStructureBuildGeometryInfoKHR *build_info;
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos;
uint32_t leaf_node_count;
struct vk_scratch_layout scratch;
struct vk_build_config config;
};
struct vk_acceleration_structure_build_ops {
void (*begin_debug_marker)(VkCommandBuffer commandBuffer,
enum vk_acceleration_structure_build_step step,
const char *format, ...);
void (*end_debug_marker)(VkCommandBuffer commandBuffer);
VkDeviceSize (*get_as_size)(VkDevice device,
const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo,
uint32_t leaf_count);
VkDeviceSize (*get_encode_scratch_size)(struct vk_device *device, uint32_t key, uint32_t leaf_count);
VkDeviceSize (*get_update_scratch_size)(struct vk_device *device,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
uint32_t leaf_count);
void (*get_build_config)(struct vk_device *device,
struct vk_build_config *config,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info);
VkResult (*encode_bind_pipeline[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer,
uint32_t key);
void (*encode_as[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr,
uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *dst);
void (*init_update_scratch)(VkCommandBuffer cmd_buffer,
VkDeviceAddress scratch,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
uint32_t leaf_count,
struct vk_acceleration_structure *src_as,
struct vk_acceleration_structure *dst_as);
void (*update_bind_pipeline[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer, uint32_t key);
void (*update_as[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer,
const VkAccelerationStructureBuildGeometryInfoKHR *build_info,
const VkAccelerationStructureBuildRangeInfoKHR *build_range_infos,
uint32_t leaf_count,
uint32_t key,
struct vk_acceleration_structure *src,
struct vk_acceleration_structure *dst);
void (*get_build_config)(VkDevice device, struct vk_acceleration_structure_build_state *state);
VkDeviceSize (*get_as_size)(VkDevice device, const struct vk_acceleration_structure_build_state *state);
VkDeviceSize (*get_encode_scratch_size)(VkDevice device, const struct vk_acceleration_structure_build_state *state);
VkDeviceSize (*get_update_scratch_size)(VkDevice device, const struct vk_acceleration_structure_build_state *state);
VkResult (*encode_bind_pipeline[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state);
void (*encode_as[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state);
void (*init_update_scratch)(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state);
void (*update_bind_pipeline[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state);
void (*update_as[MAX_ENCODE_PASSES])(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state);
const uint32_t *leaf_spirv_override;
size_t leaf_spirv_override_size;