radv/rra: Improve validation message formatting
authorKonstantin Seurer <konstantin.seurer@gmail.com>
Sat, 5 Nov 2022 12:08:37 +0000 (13:08 +0100)
committerMarge Bot <emma+marge@anholt.net>
Sun, 6 Nov 2022 17:03:52 +0000 (17:03 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19544>

src/amd/vulkan/radv_rra.c

index 17a6c7982e99647d2b8b44798fe0cd7b24dd5e95..67ddc1e88ce5098e0e6fe7354475d86f2de70cf0 100644 (file)
@@ -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;
       }
    }