~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/amd/vulkan/radv_rra.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
   uint64_t unused;
68
68
};
69
69
 
70
 
static_assert(sizeof(struct rra_file_chunk_description) == 64,
71
 
              "rra_file_chunk_description does not match RRA spec");
 
70
static_assert(sizeof(struct rra_file_chunk_description) == 64, "rra_file_chunk_description does not match RRA spec");
72
71
 
73
72
static uint64_t
74
73
node_to_addr(uint64_t node)
91
90
}
92
91
 
93
92
static void
94
 
rra_dump_chunk_description(uint64_t offset, uint64_t header_size, uint64_t data_size,
95
 
                           const char *name, enum rra_chunk_type type, FILE *output)
 
93
rra_dump_chunk_description(uint64_t offset, uint64_t header_size, uint64_t data_size, const char *name,
 
94
                           enum rra_chunk_type type, FILE *output)
96
95
{
97
96
   struct rra_file_chunk_description chunk = {
98
97
      .type = type,
159
158
}
160
159
 
161
160
static void
162
 
rra_dump_asic_info(struct radeon_info *rad_info, FILE *output)
 
161
rra_dump_asic_info(const struct radeon_info *rad_info, FILE *output)
163
162
{
164
163
   struct rra_asic_info asic_info = {
165
164
      /* All frequencies are in Hz */
178
177
      .rev_id = rad_info->pci_rev_id,
179
178
   };
180
179
 
181
 
   strncpy(asic_info.device_name,
182
 
           rad_info->marketing_name ? rad_info->marketing_name : rad_info->name,
 
180
   strncpy(asic_info.device_name, rad_info->marketing_name ? rad_info->marketing_name : rad_info->name,
183
181
           RRA_FILE_DEVICE_NAME_MAX_SIZE - 1);
184
182
 
185
183
   fwrite(&asic_info, sizeof(struct rra_asic_info), 1, output);
246
244
 
247
245
#define RRA_ROOT_NODE_OFFSET align(sizeof(struct rra_accel_struct_header), 64)
248
246
 
249
 
static_assert(sizeof(struct rra_accel_struct_header) == 120,
250
 
              "rra_accel_struct_header does not match RRA spec");
 
247
static_assert(sizeof(struct rra_accel_struct_header) == 120, "rra_accel_struct_header does not match RRA spec");
251
248
 
252
249
struct rra_accel_struct_metadata {
253
250
   uint64_t virtual_address;
255
252
   char unused[116];
256
253
};
257
254
 
258
 
static_assert(sizeof(struct rra_accel_struct_metadata) == 128,
259
 
              "rra_accel_struct_metadata does not match RRA spec");
 
255
static_assert(sizeof(struct rra_accel_struct_metadata) == 128, "rra_accel_struct_metadata does not match RRA spec");
260
256
 
261
257
struct rra_geometry_info {
262
258
   uint32_t primitive_count : 29;
268
264
static_assert(sizeof(struct rra_geometry_info) == 12, "rra_geometry_info does not match RRA spec");
269
265
 
270
266
static struct rra_accel_struct_header
271
 
rra_fill_accel_struct_header_common(struct radv_accel_struct_header *header,
272
 
                                    size_t parent_id_table_size, size_t leaf_node_data_size,
273
 
                                    size_t internal_node_data_size, uint64_t primitive_count)
 
267
rra_fill_accel_struct_header_common(struct radv_accel_struct_header *header, size_t parent_id_table_size,
 
268
                                    size_t leaf_node_data_size, size_t internal_node_data_size,
 
269
                                    uint64_t primitive_count)
274
270
{
275
271
   struct rra_accel_struct_header result = {
276
272
      .post_build_info =
288
284
   };
289
285
 
290
286
   result.metadata_size = sizeof(struct rra_accel_struct_metadata) + parent_id_table_size;
291
 
   result.file_size = result.metadata_size + sizeof(struct rra_accel_struct_header) +
292
 
                      internal_node_data_size + leaf_node_data_size;
 
287
   result.file_size =
 
288
      result.metadata_size + sizeof(struct rra_accel_struct_header) + internal_node_data_size + leaf_node_data_size;
293
289
 
294
290
   result.internal_nodes_offset = sizeof(struct rra_accel_struct_metadata);
295
291
   result.leaf_nodes_offset = result.internal_nodes_offset + internal_node_data_size;
331
327
   float otw_matrix[12];
332
328
};
333
329
 
334
 
static_assert(sizeof(struct rra_instance_node) == 128,
335
 
              "rra_instance_node does not match RRA spec!");
 
330
static_assert(sizeof(struct rra_instance_node) == 128, "rra_instance_node does not match RRA spec!");
336
331
 
337
332
/*
338
333
 * Format RRA uses for aabb nodes
361
356
static_assert(sizeof(struct rra_triangle_node) == 64, "rra_triangle_node does not match RRA spec!");
362
357
 
363
358
static void
364
 
rra_dump_tlas_header(struct radv_accel_struct_header *header, size_t parent_id_table_size,
365
 
                     size_t leaf_node_data_size, size_t internal_node_data_size,
366
 
                     uint64_t primitive_count, FILE *output)
 
359
rra_dump_tlas_header(struct radv_accel_struct_header *header, size_t parent_id_table_size, size_t leaf_node_data_size,
 
360
                     size_t internal_node_data_size, uint64_t primitive_count, FILE *output)
367
361
{
368
362
   struct rra_accel_struct_header file_header = rra_fill_accel_struct_header_common(
369
363
      header, parent_id_table_size, leaf_node_data_size, internal_node_data_size, primitive_count);
375
369
 
376
370
static void
377
371
rra_dump_blas_header(struct radv_accel_struct_header *header, size_t parent_id_table_size,
378
 
                     struct radv_accel_struct_geometry_info *geometry_infos,
379
 
                     size_t leaf_node_data_size, size_t internal_node_data_size,
380
 
                     uint64_t primitive_count, FILE *output)
 
372
                     struct radv_accel_struct_geometry_info *geometry_infos, size_t leaf_node_data_size,
 
373
                     size_t internal_node_data_size, uint64_t primitive_count, FILE *output)
381
374
{
382
375
   struct rra_accel_struct_header file_header = rra_fill_accel_struct_header_common(
383
376
      header, parent_id_table_size, leaf_node_data_size, internal_node_data_size, primitive_count);
384
377
   file_header.post_build_info.bvh_type = RRA_BVH_TYPE_BLAS;
385
 
   file_header.geometry_type =
386
 
      header->geometry_count ? geometry_infos->type : VK_GEOMETRY_TYPE_TRIANGLES_KHR;
 
378
   file_header.geometry_type = header->geometry_count ? geometry_infos->type : VK_GEOMETRY_TYPE_TRIANGLES_KHR;
387
379
 
388
380
   fwrite(&file_header, sizeof(struct rra_accel_struct_header), 1, output);
389
381
}
400
392
   char location[31];
401
393
};
402
394
 
403
 
static void PRINTFLIKE(2, 3)
404
 
rra_validation_fail(struct rra_validation_context *ctx, const char *message, ...)
 
395
static void PRINTFLIKE(2, 3) rra_validation_fail(struct rra_validation_context *ctx, const char *message, ...)
405
396
{
406
397
   if (!ctx->failed) {
407
398
      fprintf(stderr, "radv: rra: Validation failed at %s:\n", ctx->location);
419
410
}
420
411
 
421
412
static bool
422
 
rra_validate_header(struct radv_rra_accel_struct_data *accel_struct,
423
 
                    const struct radv_accel_struct_header *header)
 
413
rra_validate_header(struct radv_rra_accel_struct_data *accel_struct, const struct radv_accel_struct_header *header)
424
414
{
425
415
   struct rra_validation_context ctx = {
426
416
      .location = "header",
427
417
   };
428
418
 
429
 
   if (accel_struct->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR &&
430
 
       header->instance_count > 0)
 
419
   if (accel_struct->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR && header->instance_count > 0)
431
420
      rra_validation_fail(&ctx, "BLAS contains instances");
432
421
 
433
422
   if (header->bvh_offset >= accel_struct->size)
457
446
};
458
447
 
459
448
static bool
460
 
rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void *node,
461
 
                  uint32_t geometry_count, uint32_t size, bool is_bottom_level)
 
449
rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void *node, uint32_t geometry_count,
 
450
                  uint32_t size, bool is_bottom_level)
462
451
{
463
452
   struct rra_validation_context ctx = {0};
464
453
 
476
465
 
477
466
      if (!is_internal_node(type) && is_bottom_level == (type == radv_bvh_node_instance))
478
467
         rra_validation_fail(&ctx,
479
 
                             is_bottom_level ? "%s node in BLAS (child index %u)"
480
 
                                             : "%s node in TLAS (child index %u)",
 
468
                             is_bottom_level ? "%s node in BLAS (child index %u)" : "%s node in TLAS (child index %u)",
481
469
                             node_type_names[type], i);
482
470
 
483
471
      if (offset > size) {
486
474
      }
487
475
 
488
476
      struct rra_validation_context child_ctx = {0};
489
 
      snprintf(child_ctx.location, sizeof(child_ctx.location), "%s node (offset=%u)",
490
 
               node_type_names[type], offset);
 
477
      snprintf(child_ctx.location, sizeof(child_ctx.location), "%s node (offset=%u)", node_type_names[type], offset);
491
478
 
492
479
      if (is_internal_node(type)) {
493
 
         ctx.failed |= rra_validate_node(accel_struct_vas, data, data + offset, geometry_count,
494
 
                                         size, is_bottom_level);
 
480
         ctx.failed |= rra_validate_node(accel_struct_vas, data, data + offset, geometry_count, size, is_bottom_level);
495
481
      } else if (type == radv_bvh_node_instance) {
496
482
         struct radv_bvh_instance_node *src = (struct radv_bvh_instance_node *)(data + offset);
497
483
         uint64_t blas_va = node_to_addr(src->bvh_ptr) - src->bvh_offset;
525
511
};
526
512
 
527
513
static void
528
 
rra_transcode_triangle_node(struct rra_transcoding_context *ctx,
529
 
                            const struct radv_bvh_triangle_node *src)
 
514
rra_transcode_triangle_node(struct rra_transcoding_context *ctx, const struct radv_bvh_triangle_node *src)
530
515
{
531
516
   struct rra_triangle_node *dst = (struct rra_triangle_node *)(ctx->dst + ctx->dst_leaf_offset);
532
517
   ctx->dst_leaf_offset += sizeof(struct rra_triangle_node);
541
526
}
542
527
 
543
528
static void
544
 
rra_transcode_aabb_node(struct rra_transcoding_context *ctx, const struct radv_bvh_aabb_node *src,
545
 
                        radv_aabb bounds)
 
529
rra_transcode_aabb_node(struct rra_transcoding_context *ctx, const struct radv_bvh_aabb_node *src, radv_aabb bounds)
546
530
{
547
531
   struct rra_aabb_node *dst = (struct rra_aabb_node *)(ctx->dst + ctx->dst_leaf_offset);
548
532
   ctx->dst_leaf_offset += sizeof(struct rra_aabb_node);
560
544
}
561
545
 
562
546
static void
563
 
rra_transcode_instance_node(struct rra_transcoding_context *ctx,
564
 
                            const struct radv_bvh_instance_node *src)
 
547
rra_transcode_instance_node(struct rra_transcoding_context *ctx, const struct radv_bvh_instance_node *src)
565
548
{
566
549
   uint64_t blas_va = node_to_addr(src->bvh_ptr) - src->bvh_offset;
567
550
 
580
563
   memcpy(dst->otw_matrix, src->otw_matrix.values, sizeof(dst->otw_matrix));
581
564
}
582
565
 
583
 
static uint32_t rra_transcode_node(struct rra_transcoding_context *ctx, uint32_t parent_id,
584
 
                                   uint32_t src_id, radv_aabb bounds);
 
566
static uint32_t rra_transcode_node(struct rra_transcoding_context *ctx, uint32_t parent_id, uint32_t src_id,
 
567
                                   radv_aabb bounds);
585
568
 
586
569
static void
587
570
rra_transcode_box16_node(struct rra_transcoding_context *ctx, const struct radv_bvh_box16_node *src)
613
596
            },
614
597
      };
615
598
 
616
 
      dst->children[i] =
617
 
         rra_transcode_node(ctx, radv_bvh_node_box16 | (dst_offset >> 3), src->children[i], bounds);
 
599
      dst->children[i] = rra_transcode_node(ctx, radv_bvh_node_box16 | (dst_offset >> 3), src->children[i], bounds);
618
600
   }
619
601
}
620
602
 
633
615
         continue;
634
616
      }
635
617
 
636
 
      dst->children[i] = rra_transcode_node(ctx, radv_bvh_node_box32 | (dst_offset >> 3),
637
 
                                            src->children[i], src->coords[i]);
 
618
      dst->children[i] =
 
619
         rra_transcode_node(ctx, radv_bvh_node_box32 | (dst_offset >> 3), src->children[i], src->coords[i]);
638
620
   }
639
621
}
640
622
 
655
637
}
656
638
 
657
639
static uint32_t
658
 
rra_transcode_node(struct rra_transcoding_context *ctx, uint32_t parent_id, uint32_t src_id,
659
 
                   radv_aabb bounds)
 
640
rra_transcode_node(struct rra_transcoding_context *ctx, uint32_t parent_id, uint32_t src_id, radv_aabb bounds)
660
641
{
661
642
   uint32_t node_type = src_id & 7;
662
643
   uint32_t src_offset = (src_id & (~7u)) << 3;
681
662
         rra_transcode_instance_node(ctx, src_child_node);
682
663
   }
683
664
 
684
 
   uint32_t parent_id_index =
685
 
      rra_parent_table_index_from_offset(dst_offset, ctx->parent_id_table_size);
 
665
   uint32_t parent_id_index = rra_parent_table_index_from_offset(dst_offset, ctx->parent_id_table_size);
686
666
   ctx->parent_id_table[parent_id_index] = parent_id;
687
667
 
688
668
   uint32_t dst_id = node_type | (dst_offset >> 3);
737
717
 
738
718
static VkResult
739
719
rra_dump_acceleration_structure(struct radv_rra_accel_struct_data *accel_struct, uint8_t *data,
740
 
                                struct hash_table_u64 *accel_struct_vas, bool should_validate,
741
 
                                FILE *output)
 
720
                                struct hash_table_u64 *accel_struct_vas, bool should_validate, FILE *output)
742
721
{
743
722
   struct radv_accel_struct_header *header = (struct radv_accel_struct_header *)data;
744
723
 
753
732
      if (rra_validate_header(accel_struct, header)) {
754
733
         return VK_ERROR_VALIDATION_FAILED_EXT;
755
734
      }
756
 
      if (rra_validate_node(accel_struct_vas, data + header->bvh_offset,
757
 
                            data + header->bvh_offset + src_root_offset, header->geometry_count,
758
 
                            accel_struct->size, !is_tlas)) {
 
735
      if (rra_validate_node(accel_struct_vas, data + header->bvh_offset, data + header->bvh_offset + src_root_offset,
 
736
                            header->geometry_count, accel_struct->size, !is_tlas)) {
759
737
         return VK_ERROR_VALIDATION_FAILED_EXT;
760
738
      }
761
739
   }
811
789
      result = VK_ERROR_OUT_OF_HOST_MEMORY;
812
790
      goto exit;
813
791
   }
814
 
   dst_structure_data =
815
 
      calloc(RRA_ROOT_NODE_OFFSET + bvh_info.internal_nodes_size + bvh_info.leaf_nodes_size, 1);
 
792
   dst_structure_data = calloc(RRA_ROOT_NODE_OFFSET + bvh_info.internal_nodes_size + bvh_info.leaf_nodes_size, 1);
816
793
   if (!dst_structure_data) {
817
794
      result = VK_ERROR_OUT_OF_HOST_MEMORY;
818
795
      goto exit;
858
835
 
859
836
   struct rra_accel_struct_metadata rra_metadata = {
860
837
      .virtual_address = va,
861
 
      .byte_size = bvh_info.leaf_nodes_size + bvh_info.internal_nodes_size +
862
 
                   sizeof(struct rra_accel_struct_header),
 
838
      .byte_size = bvh_info.leaf_nodes_size + bvh_info.internal_nodes_size + sizeof(struct rra_accel_struct_header),
863
839
   };
864
840
 
865
841
   fwrite(&chunk_header, sizeof(struct rra_accel_struct_chunk_header), 1, output);
869
845
   fwrite(node_parent_table, 1, node_parent_table_size, output);
870
846
 
871
847
   if (is_tlas)
872
 
      rra_dump_tlas_header(header, node_parent_table_size, bvh_info.leaf_nodes_size,
873
 
                           bvh_info.internal_nodes_size, primitive_count, output);
 
848
      rra_dump_tlas_header(header, node_parent_table_size, bvh_info.leaf_nodes_size, bvh_info.internal_nodes_size,
 
849
                           primitive_count, output);
874
850
   else
875
851
      rra_dump_blas_header(header, node_parent_table_size, geometry_infos, bvh_info.leaf_nodes_size,
876
852
                           bvh_info.internal_nodes_size, primitive_count, output);
877
853
 
878
854
   /* Write acceleration structure data  */
879
 
   fwrite(dst_structure_data + RRA_ROOT_NODE_OFFSET, 1,
880
 
          bvh_info.internal_nodes_size + bvh_info.leaf_nodes_size, output);
 
855
   fwrite(dst_structure_data + RRA_ROOT_NODE_OFFSET, 1, bvh_info.internal_nodes_size + bvh_info.leaf_nodes_size,
 
856
          output);
881
857
 
882
858
   if (!is_tlas)
883
859
      fwrite(rra_geometry_infos, sizeof(struct rra_geometry_info), header->geometry_count, output);
896
872
   return result;
897
873
}
898
874
 
899
 
int
900
 
radv_rra_trace_frame()
901
 
{
902
 
   return radv_get_int_debug_option("RADV_RRA_TRACE", -1);
903
 
}
904
 
 
905
 
char *
906
 
radv_rra_trace_trigger_file()
907
 
{
908
 
   return getenv("RADV_RRA_TRACE_TRIGGER");
909
 
}
910
 
 
911
 
bool
912
 
radv_rra_trace_enabled()
913
 
{
914
 
   return radv_rra_trace_frame() != -1 || radv_rra_trace_trigger_file();
915
 
}
916
 
 
917
875
void
918
876
radv_rra_trace_init(struct radv_device *device)
919
877
{
920
 
   device->rra_trace.trace_frame = radv_rra_trace_frame();
921
 
   device->rra_trace.elapsed_frames = 0;
922
 
   device->rra_trace.trigger_file = radv_rra_trace_trigger_file();
923
 
   device->rra_trace.validate_as = radv_get_int_debug_option("RADV_RRA_TRACE_VALIDATE", 0) != 0;
924
 
   device->rra_trace.copy_after_build =
925
 
      radv_get_int_debug_option("RADV_RRA_TRACE_COPY_AFTER_BUILD", 0) != 0;
 
878
   device->rra_trace.validate_as = debug_get_bool_option("RADV_RRA_TRACE_VALIDATE", false);
 
879
   device->rra_trace.copy_after_build = debug_get_bool_option("RADV_RRA_TRACE_COPY_AFTER_BUILD", false);
926
880
   device->rra_trace.accel_structs = _mesa_pointer_hash_table_create(NULL);
927
881
   device->rra_trace.accel_struct_vas = _mesa_hash_table_u64_create(NULL);
928
882
   simple_mtx_init(&device->rra_trace.data_mtx, mtx_plain);
929
883
 
930
 
   device->rra_trace.copy_memory_index =
931
 
      radv_find_memory_index(device->physical_device, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
932
 
                                                         VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
933
 
                                                         VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
 
884
   device->rra_trace.copy_memory_index = radv_find_memory_index(
 
885
      device->physical_device,
 
886
      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
934
887
}
935
888
 
936
889
void
1036
989
   if (result != VK_SUCCESS)
1037
990
      goto fail_buffer;
1038
991
 
1039
 
   result =
1040
 
      vk_common_MapMemory(ctx->device, ctx->memory, 0, VK_WHOLE_SIZE, 0, (void **)&ctx->mapped_data);
 
992
   result = vk_common_MapMemory(ctx->device, ctx->memory, 0, VK_WHOLE_SIZE, 0, (void **)&ctx->mapped_data);
1041
993
   if (result != VK_SUCCESS)
1042
994
      goto fail_memory;
1043
995
 
1186
1138
   uint64_t written_accel_struct_count = 0;
1187
1139
 
1188
1140
   struct hash_entry *last_entry = NULL;
1189
 
   for (unsigned i = 0;
1190
 
        (last_entry = _mesa_hash_table_next_entry(device->rra_trace.accel_structs, last_entry));
1191
 
        ++i)
 
1141
   for (unsigned i = 0; (last_entry = _mesa_hash_table_next_entry(device->rra_trace.accel_structs, last_entry)); ++i)
1192
1142
      hash_entries[i] = last_entry;
1193
1143
 
1194
1144
   qsort(hash_entries, struct_count, sizeof(*hash_entries), accel_struct_entry_cmp);
1215
1165
         continue;
1216
1166
 
1217
1167
      accel_struct_offsets[written_accel_struct_count] = (uint64_t)ftell(file);
1218
 
      result =
1219
 
         rra_dump_acceleration_structure(data, mapped_data, device->rra_trace.accel_struct_vas,
1220
 
                                         device->rra_trace.validate_as, file);
 
1168
      result = rra_dump_acceleration_structure(data, mapped_data, device->rra_trace.accel_struct_vas,
 
1169
                                               device->rra_trace.validate_as, file);
1221
1170
 
1222
1171
      rra_unmap_accel_struct_data(&copy_ctx, i);
1223
1172
 
1228
1177
   rra_copy_context_finish(&copy_ctx);
1229
1178
 
1230
1179
   uint64_t chunk_info_offset = (uint64_t)ftell(file);
1231
 
   rra_dump_chunk_description(api_info_offset, 0, 8, "ApiInfo", RADV_RRA_CHUNK_ID_ASIC_API_INFO,
1232
 
                              file);
 
1180
   rra_dump_chunk_description(api_info_offset, 0, 8, "ApiInfo", RADV_RRA_CHUNK_ID_ASIC_API_INFO, file);
1233
1181
   rra_dump_chunk_description(asic_info_offset, 0, sizeof(struct rra_asic_info), "AsicInfo",
1234
1182
                              RADV_RRA_CHUNK_ID_ASIC_API_INFO, file);
1235
1183
 
1240
1188
      else
1241
1189
         accel_struct_size = (uint64_t)(accel_struct_offsets[i + 1] - accel_struct_offsets[i]);
1242
1190
 
1243
 
      rra_dump_chunk_description(accel_struct_offsets[i],
1244
 
                                 sizeof(struct rra_accel_struct_chunk_header), accel_struct_size,
1245
 
                                 "RawAccelStruc", RADV_RRA_CHUNK_ID_ACCEL_STRUCT, file);
 
1191
      rra_dump_chunk_description(accel_struct_offsets[i], sizeof(struct rra_accel_struct_chunk_header),
 
1192
                                 accel_struct_size, "RawAccelStruct", RADV_RRA_CHUNK_ID_ACCEL_STRUCT, file);
1246
1193
   }
1247
1194
 
1248
1195
   uint64_t file_end = (uint64_t)ftell(file);