From 19aae06692508ffcda14af4a771287eacf641bc4 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 23 Sep 2022 17:31:40 +0200 Subject: [PATCH] radv: Use deterministic order for dumping acceleration stuctures. To provide deterministic RRA dumps. Reviewed-by: Friedrich Vock Part-of: --- src/amd/vulkan/radv_rra.c | 41 +++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_rra.c b/src/amd/vulkan/radv_rra.c index 92933a8d4c8..574f1e5c1c0 100644 --- a/src/amd/vulkan/radv_rra.c +++ b/src/amd/vulkan/radv_rra.c @@ -920,7 +920,7 @@ fail: static VkResult rra_copy_acceleration_structures(VkQueue vk_queue, struct rra_accel_struct_copy *dst, - struct hash_entry **last_entry, uint32_t count, + struct hash_entry **entries, uint32_t count, uint32_t *copied_structure_count) { RADV_FROM_HANDLE(radv_queue, queue, vk_queue); @@ -948,13 +948,7 @@ rra_copy_acceleration_structures(VkQueue vk_queue, struct rra_accel_struct_copy uint64_t dst_offset = 0; for (uint32_t i = 0; i < count;) { - struct hash_entry *entry = - _mesa_hash_table_next_entry(device->rra_trace.accel_structs, *last_entry); - - if (!entry) - break; - - *last_entry = entry; + struct hash_entry *entry = entries[i]; VkResult event_result = radv_GetEventStatus(vk_device, radv_event_to_handle(entry->data)); if (event_result != VK_EVENT_SET) { @@ -1009,12 +1003,24 @@ fail: return result; } +static int +accel_struct_entry_cmp(const void *a, const void *b) +{ + struct hash_entry *entry_a = *(struct hash_entry *const *)a; + struct hash_entry *entry_b = *(struct hash_entry *const *)b; + const struct radv_acceleration_structure *s_a = entry_a->key; + const struct radv_acceleration_structure *s_b = entry_b->key; + + return s_a->va > s_b->va ? 1 : s_a->va < s_b->va ? -1 : 0; +} + VkResult radv_rra_dump_trace(VkQueue vk_queue, char *filename) { RADV_FROM_HANDLE(radv_queue, queue, vk_queue); struct radv_device *device = queue->device; VkDevice vk_device = radv_device_to_handle(device); + struct hash_entry **hash_entries = NULL; uint32_t accel_struct_count = _mesa_hash_table_num_entries(device->rra_trace.accel_structs); @@ -1052,10 +1058,24 @@ radv_rra_dump_trace(VkQueue vk_queue, char *filename) if (result != VK_SUCCESS) goto fail; + uint32_t struct_count = _mesa_hash_table_num_entries(device->rra_trace.accel_structs); + hash_entries = malloc(sizeof(*hash_entries) * struct_count); + if (!hash_entries) { + result = VK_ERROR_OUT_OF_HOST_MEMORY; + goto fail; + } + struct hash_entry *last_entry = NULL; - while (_mesa_hash_table_next_entry(device->rra_trace.accel_structs, last_entry)) { + for (unsigned i = 0; + (last_entry = _mesa_hash_table_next_entry(device->rra_trace.accel_structs, last_entry)); + ++i) + hash_entries[i] = last_entry; + + qsort(hash_entries, struct_count, sizeof(*hash_entries), accel_struct_entry_cmp); + for (unsigned j = 0; j < struct_count; j += RRA_COPY_BATCH_SIZE) { uint32_t copied_structure_count; - result = rra_copy_acceleration_structures(vk_queue, ©, &last_entry, RRA_COPY_BATCH_SIZE, + result = rra_copy_acceleration_structures(vk_queue, ©, hash_entries + j, + MIN2(RRA_COPY_BATCH_SIZE, struct_count - j), &copied_structure_count); if (result != VK_SUCCESS) goto copy_fail; @@ -1101,6 +1121,7 @@ copy_fail: radv_FreeMemory(vk_device, copy.memory, NULL); vk_common_DestroyCommandPool(vk_device, copy.pool, NULL); fail: + free(hash_entries); free(accel_struct_offsets); return result; }