From 868107e16c42ec3ff34958fce7f70f2d62385484 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Sat, 5 Nov 2022 13:08:37 +0100 Subject: [PATCH] radv/rra: Improve validation message formatting Part-of: --- src/amd/vulkan/radv_rra.c | 94 ++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/src/amd/vulkan/radv_rra.c b/src/amd/vulkan/radv_rra.c index 17a6c7982e9..67ddc1e88ce 100644 --- a/src/amd/vulkan/radv_rra.c +++ b/src/amd/vulkan/radv_rra.c @@ -400,14 +400,24 @@ rra_parent_table_index_from_offset(uint32_t offset, uint32_t parent_table_size) return max_parent_table_index - (offset - RRA_ROOT_NODE_OFFSET) / 64; } +struct rra_validation_context { + bool failed; + char location[31]; +}; + static void PRINTFLIKE(2, 3) -rra_validation_fail(uint32_t offset, const char *reason, ...) +rra_validation_fail(struct rra_validation_context *ctx, const char *message, ...) { - fprintf(stderr, "radv: AS validation failed at offset 0x%x with reason: ", offset); + if (!ctx->failed) { + fprintf(stderr, "radv: rra: Validation failed at %s:\n", ctx->location); + ctx->failed = true; + } + + fprintf(stderr, " "); va_list list; - va_start(list, reason); - vfprintf(stderr, reason, list); + va_start(list, message); + vfprintf(stderr, message, list); va_end(list); fprintf(stderr, "\n"); @@ -417,25 +427,21 @@ static bool rra_validate_header(struct radv_acceleration_structure *accel_struct, const struct radv_accel_struct_header *header) { - bool result = true; + struct rra_validation_context ctx = { + .location = "header", + }; if (accel_struct->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR && - header->instance_count > 0) { - rra_validation_fail(0, "BLAS contains instances"); - result = false; - } + header->instance_count > 0) + rra_validation_fail(&ctx, "BLAS contains instances"); - if (header->bvh_offset >= accel_struct->size) { - rra_validation_fail(0, "Invalid BVH offset %u", header->bvh_offset); - result = false; - } + if (header->bvh_offset >= accel_struct->size) + rra_validation_fail(&ctx, "Invalid BVH offset %u", header->bvh_offset); - if (header->instance_count * sizeof(struct radv_bvh_instance_node) >= accel_struct->size) { - rra_validation_fail(0, "Too many instances"); - result = false; - } + if (header->instance_count * sizeof(struct radv_bvh_instance_node) >= accel_struct->size) + rra_validation_fail(&ctx, "Too many instances"); - return result; + return ctx.failed; } static bool @@ -459,10 +465,13 @@ static bool rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void *node, uint32_t root_node_offset, uint32_t size, bool is_bottom_level) { + struct rra_validation_context ctx = {0}; + + uint32_t cur_offset = (uint8_t *)node - data; + snprintf(ctx.location, sizeof(ctx.location), "internal node (offset=%u)", cur_offset); + /* The child ids are located at offset=0 for both box16 and box32 nodes. */ uint32_t *children = node; - bool result = true; - uint32_t cur_offset = (uint8_t *)node - data; for (uint32_t i = 0; i < 4; ++i) { if (children[i] == 0xFFFFFFFF) continue; @@ -487,39 +496,40 @@ rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void * default: is_node_type_valid = false; } - if (!is_node_type_valid) { - rra_validation_fail(cur_offset, "Invalid node type %u (child index %u)", type, i); - result = false; - } - if (!node_type_matches_as_type) { - rra_validation_fail(offset, + + if (!is_node_type_valid) + rra_validation_fail(&ctx, "Invalid node type %u (child index %u)", type, i); + + if (!node_type_matches_as_type) + rra_validation_fail(&ctx, is_bottom_level ? "%s node in BLAS (child index %u)" : "%s node in TLAS (child index %u)", node_type_names[type], i); - result = false; - } - if (offset > size) { - rra_validation_fail(cur_offset, "Invalid child offset (child index %u)", i); - result = false; + rra_validation_fail(&ctx, "Invalid child offset (child index %u)", i); continue; } if (is_internal_node(type)) { - result &= rra_validate_node(accel_struct_vas, data, data + offset, root_node_offset, size, - is_bottom_level); + ctx.failed |= rra_validate_node(accel_struct_vas, data, data + offset, root_node_offset, + size, is_bottom_level); } else if (type == radv_bvh_node_instance) { + struct rra_validation_context instance_ctx = {0}; + snprintf(instance_ctx.location, sizeof(instance_ctx.location), "instance node (offset=%u)", + offset); + struct radv_bvh_instance_node *src = (struct radv_bvh_instance_node *)(data + offset); uint64_t blas_va = src->bvh_ptr - src->bvh_offset; - if (!_mesa_hash_table_u64_search(accel_struct_vas, blas_va)) { - rra_validation_fail(offset, "Invalid instance node pointer 0x%llx (offset: 0x%x)", + if (!_mesa_hash_table_u64_search(accel_struct_vas, blas_va)) + rra_validation_fail(&instance_ctx, + "Invalid instance node pointer 0x%llx (offset: 0x%x)", (unsigned long long)src->bvh_ptr, src->bvh_offset); - result = false; - } + + ctx.failed |= instance_ctx.failed; } } - return result; + return ctx.failed; } struct rra_transcoding_context { @@ -734,12 +744,12 @@ rra_dump_acceleration_structure(struct rra_copied_accel_struct *copied_struct, uint32_t src_root_offset = (RADV_BVH_ROOT_NODE & ~7) << 3; if (should_validate) { - if (!rra_validate_header(accel_struct, header)) { + if (rra_validate_header(accel_struct, header)) { return VK_ERROR_VALIDATION_FAILED_EXT; } - if (!rra_validate_node(accel_struct_vas, data + header->bvh_offset, - data + header->bvh_offset + src_root_offset, src_root_offset, - accel_struct->size, !is_tlas)) { + if (rra_validate_node(accel_struct_vas, data + header->bvh_offset, + data + header->bvh_offset + src_root_offset, src_root_offset, + accel_struct->size, !is_tlas)) { return VK_ERROR_VALIDATION_FAILED_EXT; } } -- 2.34.1