radv: Fix creating accel structs with unbound buffers

If the buffer hasn't been bound to memory yet, we will dereference a
NULL pointer in radv_CreateAccelerationStructureKHR.

cc: mesa-stable

Closes: #8199
Reviewed-by: Friedrich Vock <friedrich.vock@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21019>
This commit is contained in:
Konstantin Seurer 2023-01-31 17:03:15 +01:00 committed by Marge Bot
parent 37652da616
commit a568a5492f
5 changed files with 54 additions and 45 deletions

View file

@ -180,7 +180,7 @@ rra_CreateAccelerationStructureKHR(VkDevice _device,
goto fail_as;
}
data->va = structure->va;
data->va = structure->buffer->bo ? radv_acceleration_structure_get_va(structure) : 0;
data->size = structure->size;
data->type = pCreateInfo->type;
data->is_dead = false;
@ -198,7 +198,9 @@ rra_CreateAccelerationStructureKHR(VkDevice _device,
goto fail_event;
_mesa_hash_table_insert(device->rra_trace.accel_structs, structure, data);
_mesa_hash_table_u64_insert(device->rra_trace.accel_struct_vas, structure->va, structure);
if (data->va)
_mesa_hash_table_u64_insert(device->rra_trace.accel_struct_vas, data->va, structure);
goto exit;
fail_event:
@ -239,18 +241,15 @@ copy_accel_struct_to_data(VkCommandBuffer commandBuffer,
vk_common_CmdSetEvent(commandBuffer, data->build_event, 0);
struct radv_buffer tmp_buffer;
radv_buffer_init(&tmp_buffer, cmd_buffer->device, accel_struct->bo, accel_struct->size,
accel_struct->mem_offset);
VkBufferCopy2 region = {
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.srcOffset = accel_struct->offset,
.size = accel_struct->size,
};
VkCopyBufferInfo2 copyInfo = {
.sType = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2,
.srcBuffer = radv_buffer_to_handle(&tmp_buffer),
.srcBuffer = radv_buffer_to_handle(accel_struct->buffer),
.dstBuffer = data->buffer,
.regionCount = 1,
.pRegions = &region,
@ -258,7 +257,11 @@ copy_accel_struct_to_data(VkCommandBuffer commandBuffer,
radv_CmdCopyBuffer2(commandBuffer, &copyInfo);
radv_buffer_finish(&tmp_buffer);
if (!data->va) {
data->va = radv_acceleration_structure_get_va(accel_struct);
_mesa_hash_table_u64_insert(cmd_buffer->device->rra_trace.accel_struct_vas, data->va,
accel_struct);
}
}
VKAPI_ATTR void VKAPI_CALL

View file

@ -256,25 +256,21 @@ radv_CreateAccelerationStructureKHR(VkDevice _device,
{
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
struct radv_acceleration_structure *accel;
uint64_t mem_offset, va;
mem_offset = buffer->offset + pCreateInfo->offset;
va = radv_buffer_get_va(buffer->bo) + mem_offset;
if (pCreateInfo->deviceAddress && va != pCreateInfo->deviceAddress)
return vk_error(device, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR);
accel = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*accel), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
struct radv_acceleration_structure *accel = vk_alloc2(
&device->vk.alloc, pAllocator, sizeof(*accel), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (accel == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk, &accel->base, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR);
accel->mem_offset = mem_offset;
accel->buffer = buffer;
accel->offset = pCreateInfo->offset;
accel->size = pCreateInfo->size;
accel->bo = buffer->bo;
accel->va = va;
if (pCreateInfo->deviceAddress && buffer->bo &&
radv_acceleration_structure_get_va(accel) != pCreateInfo->deviceAddress)
return vk_error(device, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR);
*pAccelerationStructure = radv_acceleration_structure_to_handle(accel);
return VK_SUCCESS;
@ -300,7 +296,7 @@ radv_GetAccelerationStructureDeviceAddressKHR(
VkDevice _device, const VkAccelerationStructureDeviceAddressInfoKHR *pInfo)
{
RADV_FROM_HANDLE(radv_acceleration_structure, accel, pInfo->accelerationStructure);
return accel->va;
return radv_acceleration_structure_get_va(accel);
}
VKAPI_ATTR VkResult VKAPI_CALL
@ -947,7 +943,8 @@ encode_nodes(VkCommandBuffer commandBuffer, uint32_t infoCount,
const struct encode_args args = {
.intermediate_bvh = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.ir_offset,
.output_bvh = accel_struct->va + bvh_states[i].accel_struct.bvh_offset,
.output_bvh = radv_acceleration_structure_get_va(accel_struct) +
bvh_states[i].accel_struct.bvh_offset,
.header = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset,
.output_bvh_offset = bvh_states[i].accel_struct.bvh_offset,
.leaf_node_count = bvh_states[i].leaf_node_count,
@ -1078,17 +1075,14 @@ radv_CmdBuildAccelerationStructuresKHR(
geometry_infos[j].primitive_count = ppBuildRangeInfos[i][j].primitiveCount;
}
radv_update_buffer_cp(cmd_buffer, accel_struct->va + base, (const char *)&header + base,
sizeof(header) - base);
radv_update_buffer_cp(cmd_buffer, radv_acceleration_structure_get_va(accel_struct) + base,
(const char *)&header + base, sizeof(header) - base);
VkDeviceSize geometry_infos_offset = header.compacted_size - geometry_infos_size;
struct radv_buffer accel_struct_buffer;
radv_buffer_init(&accel_struct_buffer, cmd_buffer->device, accel_struct->bo,
accel_struct->size, accel_struct->mem_offset);
radv_CmdUpdateBuffer(commandBuffer, radv_buffer_to_handle(&accel_struct_buffer),
geometry_infos_offset, geometry_infos_size, geometry_infos);
radv_buffer_finish(&accel_struct_buffer);
radv_CmdUpdateBuffer(commandBuffer, radv_buffer_to_handle(accel_struct->buffer),
accel_struct->offset + geometry_infos_offset, geometry_infos_size,
geometry_infos);
free(geometry_infos);
}
@ -1121,8 +1115,8 @@ radv_CmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
cmd_buffer->device->meta_state.accel_struct_build.copy_pipeline);
struct copy_args consts = {
.src_addr = src->va,
.dst_addr = dst->va,
.src_addr = radv_acceleration_structure_get_va(src),
.dst_addr = radv_acceleration_structure_get_va(dst),
.mode = RADV_COPY_MODE_COPY,
};
@ -1133,8 +1127,9 @@ radv_CmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
cmd_buffer->state.flush_bits |=
radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT, NULL);
radv_indirect_dispatch(cmd_buffer, src->bo,
src->va + offsetof(struct radv_accel_struct_header, copy_dispatch_size));
radv_indirect_dispatch(cmd_buffer, src->buffer->bo,
radv_acceleration_structure_get_va(src) +
offsetof(struct radv_accel_struct_header, copy_dispatch_size));
radv_meta_restore(&saved_state, cmd_buffer);
}
@ -1193,7 +1188,7 @@ radv_CmdCopyMemoryToAccelerationStructureKHR(
const struct copy_args consts = {
.src_addr = pInfo->src.deviceAddress,
.dst_addr = dst->va,
.dst_addr = radv_acceleration_structure_get_va(dst),
.mode = RADV_COPY_MODE_DESERIALIZE,
};
@ -1227,7 +1222,7 @@ radv_CmdCopyAccelerationStructureToMemoryKHR(
cmd_buffer->device->meta_state.accel_struct_build.copy_pipeline);
const struct copy_args consts = {
.src_addr = src->va,
.src_addr = radv_acceleration_structure_get_va(src),
.dst_addr = pInfo->dst.deviceAddress,
.mode = RADV_COPY_MODE_SERIALIZE,
};
@ -1239,8 +1234,9 @@ radv_CmdCopyAccelerationStructureToMemoryKHR(
cmd_buffer->state.flush_bits |=
radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT, NULL);
radv_indirect_dispatch(cmd_buffer, src->bo,
src->va + offsetof(struct radv_accel_struct_header, copy_dispatch_size));
radv_indirect_dispatch(cmd_buffer, src->buffer->bo,
radv_acceleration_structure_get_va(src) +
offsetof(struct radv_accel_struct_header, copy_dispatch_size));
radv_meta_restore(&saved_state, cmd_buffer);
/* Set the header of the serialized data. */
@ -1261,3 +1257,10 @@ radv_CmdBuildAccelerationStructuresIndirectKHR(
{
unreachable("Unimplemented");
}
uint64_t
radv_acceleration_structure_get_va(struct radv_acceleration_structure *accel_struct)
{
return radv_buffer_get_va(accel_struct->buffer->bo) + accel_struct->buffer->offset +
accel_struct->offset;
}

View file

@ -31,12 +31,13 @@
struct radv_acceleration_structure {
struct vk_object_base base;
struct radeon_winsys_bo *bo;
uint64_t mem_offset;
struct radv_buffer *buffer;
uint64_t offset;
uint64_t size;
uint64_t va;
};
uint64_t radv_acceleration_structure_get_va(struct radv_acceleration_structure *accel_struct);
VK_DEFINE_NONDISP_HANDLE_CASTS(radv_acceleration_structure, base, VkAccelerationStructureKHR,
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR)

View file

@ -1311,7 +1311,7 @@ write_accel_struct(struct radv_device *device, void *ptr, VkDeviceAddress va)
if (!va) {
RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct,
device->meta_state.accel_struct_build.null.accel_struct);
va = accel_struct->va;
va = radv_acceleration_structure_get_va(accel_struct);
}
memcpy(ptr, &va, sizeof(va));
@ -1412,7 +1412,8 @@ radv_update_descriptor_sets_impl(struct radv_device *device, struct radv_cmd_buf
RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct,
accel_structs->pAccelerationStructures[j]);
write_accel_struct(device, ptr, accel_struct ? accel_struct->va : 0);
write_accel_struct(device, ptr,
accel_struct ? radv_acceleration_structure_get_va(accel_struct) : 0);
break;
}
default:
@ -1708,7 +1709,8 @@ radv_update_descriptor_set_with_template_impl(struct radv_device *device,
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct,
*(const VkAccelerationStructureKHR *)pSrc);
write_accel_struct(device, pDst, accel_struct ? accel_struct->va : 0);
write_accel_struct(device, pDst,
accel_struct ? radv_acceleration_structure_get_va(accel_struct) : 0);
break;
}
default:

View file

@ -2182,7 +2182,7 @@ radv_CmdWriteAccelerationStructuresPropertiesKHR(
for (uint32_t i = 0; i < accelerationStructureCount; ++i) {
RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct, pAccelerationStructures[i]);
uint64_t va = accel_struct->va;
uint64_t va = radv_acceleration_structure_get_va(accel_struct);
switch (queryType) {
case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR: