xref: /aosp_15_r20/external/mesa3d/src/intel/vulkan/anv_rmv.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2023 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "anv_private.h"
29 
30 static VkResult
capture_trace(VkQueue _queue)31 capture_trace(VkQueue _queue)
32 {
33    ANV_FROM_HANDLE(anv_queue, queue, _queue);
34 
35    simple_mtx_lock(&queue->device->vk.memory_trace_data.token_mtx);
36    vk_dump_rmv_capture(&queue->device->vk.memory_trace_data);
37    simple_mtx_unlock(&queue->device->vk.memory_trace_data.token_mtx);
38 
39    return VK_SUCCESS;
40 }
41 
42 void
anv_memory_trace_init(struct anv_device * device)43 anv_memory_trace_init(struct anv_device *device)
44 {
45    struct vk_rmv_device_info info;
46    memset(&info, 0, sizeof(info));
47    anv_rmv_fill_device_info(device->physical, &info);
48    vk_memory_trace_init(&device->vk, &info);
49 
50    if (!device->vk.memory_trace_data.is_enabled)
51       return;
52 
53    device->vk.capture_trace = capture_trace;
54 }
55 
56 static void
fill_memory_info(const struct anv_physical_device * device,struct vk_rmv_memory_info * out_info,int32_t index)57 fill_memory_info(const struct anv_physical_device *device,
58                  struct vk_rmv_memory_info *out_info,
59                  int32_t index)
60 {
61    switch (index) {
62    case VK_RMV_MEMORY_LOCATION_DEVICE:
63       out_info->physical_base_address = 0;
64       out_info->size = device->memory.heaps[0].size;
65       break;
66    case VK_RMV_MEMORY_LOCATION_DEVICE_INVISIBLE:
67       out_info->physical_base_address = device->memory.heaps[0].size;
68       out_info->size = device->vram_non_mappable.size;
69       break;
70    case VK_RMV_MEMORY_LOCATION_HOST:
71       out_info->physical_base_address = 0;
72       out_info->size = device->memory.heaps[1].size;
73       break;
74    default:
75       unreachable("invalid memory index");
76    }
77 }
78 
79 void
anv_rmv_fill_device_info(const struct anv_physical_device * device,struct vk_rmv_device_info * info)80 anv_rmv_fill_device_info(const struct anv_physical_device *device,
81                          struct vk_rmv_device_info *info)
82 {
83    for (int32_t i = 0; i < VK_RMV_MEMORY_LOCATION_COUNT; ++i)
84       fill_memory_info(device, &info->memory_infos[i], i);
85 
86    strncpy(info->device_name, device->info.name, sizeof(info->device_name) - 1);
87    info->pcie_revision_id = device->info.pci_revision_id;
88    info->pcie_device_id = device->info.pci_device_id;
89    /* TODO: */
90    info->pcie_family_id = 0;
91    info->minimum_shader_clock = 0;
92    info->maximum_shader_clock = 1 * 1024 * 1024 * 1024;
93    info->vram_type = VK_RMV_MEMORY_TYPE_DDR4;
94    info->vram_bus_width = 256;
95    info->vram_operations_per_clock = 1;
96    info->minimum_memory_clock = 0;
97    info->maximum_memory_clock = 1;
98    info->vram_bandwidth = 256;
99 }
100 
101 void
anv_memory_trace_finish(struct anv_device * device)102 anv_memory_trace_finish(struct anv_device *device)
103 {
104 }
105 
106 static uint32_t
resource_id_locked(struct anv_device * device,const void * obj)107 resource_id_locked(struct anv_device *device, const void *obj)
108 {
109    return vk_rmv_get_resource_id_locked(&device->vk, (uint64_t)(uintptr_t)obj);
110 }
111 
112 static void
resource_destroy_locked(struct anv_device * device,const void * obj)113 resource_destroy_locked(struct anv_device *device, const void *obj)
114 {
115    vk_rmv_destroy_resource_id_locked(&device->vk, (uint64_t)(uintptr_t)obj);
116 }
117 
118 /* The token lock must be held when entering _locked functions */
119 static void
log_resource_bind_locked(struct anv_device * device,uint64_t resource_id,struct anv_bo * bo,uint64_t offset,uint64_t size)120 log_resource_bind_locked(struct anv_device *device, uint64_t resource_id,
121                          struct anv_bo *bo, uint64_t offset,
122                          uint64_t size)
123 {
124    struct vk_rmv_resource_bind_token token = {
125       .resource_id      = resource_id,
126       .is_system_memory = bo ? (bo->alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM) : 0,
127       .address          = (bo ? bo->offset : 0) + offset,
128       .size             = size,
129    };
130 
131    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_BIND, &token);
132 }
133 
134 static void
log_state_pool_bind_locked(struct anv_device * device,uint64_t resource_id,struct anv_state_pool * pool,struct anv_state * state)135 log_state_pool_bind_locked(struct anv_device *device, uint64_t resource_id,
136                            struct anv_state_pool *pool, struct anv_state *state)
137 {
138    struct vk_rmv_resource_bind_token token = {
139       .resource_id      = resource_id,
140       .is_system_memory = (pool->block_pool.bo_alloc_flags &
141                            ANV_BO_ALLOC_NO_LOCAL_MEM) != 0,
142       .address          = anv_address_physical(
143          anv_state_pool_state_address(pool, *state)),
144       .size             = state->alloc_size,
145    };
146 
147    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_BIND, &token);
148 }
149 
150 static enum vk_rmv_memory_location
anv_heap_index_to_memory_location(struct anv_device * device,unsigned heap_index)151 anv_heap_index_to_memory_location(struct anv_device *device,
152                                   unsigned heap_index)
153 {
154    if (heap_index == 0)
155       return device->physical->vram_non_mappable.size != 0 ?
156              VK_RMV_MEMORY_LOCATION_DEVICE_INVISIBLE :
157              VK_RMV_MEMORY_LOCATION_DEVICE;
158    else if (heap_index == 1)
159       return VK_RMV_MEMORY_LOCATION_HOST;
160    else
161       return VK_RMV_MEMORY_LOCATION_DEVICE;
162 }
163 
164 static void
anv_rmv_log_bo_gtt_unmap_locked(struct anv_device * device,struct anv_bo * bo)165 anv_rmv_log_bo_gtt_unmap_locked(struct anv_device *device,
166                                 struct anv_bo *bo)
167 {
168    if (!bo->gtt_mapped)
169       return;
170 
171    struct vk_rmv_token token = {
172       .type      = VK_RMV_TOKEN_TYPE_PAGE_TABLE_UPDATE,
173       .timestamp = (uint64_t)os_time_get_nano(),
174       .data      = {
175          .page_table_update = {
176             .type             = VK_RMV_PAGE_TABLE_UPDATE_TYPE_UPDATE,
177             .page_size        = device->info->mem_alignment,
178             .page_count       = DIV_ROUND_UP(bo->size,
179                                              device->info->mem_alignment),
180             .pid              = getpid(),
181             .virtual_address  = bo->offset,
182             .physical_address = bo->offset,
183             .is_unmap         = true,
184          },
185       },
186    };
187    util_dynarray_append(&device->vk.memory_trace_data.tokens,
188                         struct vk_rmv_token, token);
189 
190    bo->gtt_mapped = false;
191 }
192 
193 void
anv_rmv_log_bo_gtt_unmap(struct anv_device * device,struct anv_bo * bo)194 anv_rmv_log_bo_gtt_unmap(struct anv_device *device,
195                          struct anv_bo *bo)
196 {
197    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
198    anv_rmv_log_bo_gtt_unmap_locked(device, bo);
199    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
200 }
201 
202 void
anv_rmv_log_bo_gtt_map(struct anv_device * device,struct anv_bo * bo)203 anv_rmv_log_bo_gtt_map(struct anv_device *device,
204                        struct anv_bo *bo)
205 {
206    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
207    struct vk_rmv_token token = {
208       .type      = VK_RMV_TOKEN_TYPE_PAGE_TABLE_UPDATE,
209       .timestamp = (uint64_t)os_time_get_nano(),
210       .data      = {
211          .page_table_update = {
212             .type             = VK_RMV_PAGE_TABLE_UPDATE_TYPE_UPDATE,
213             .page_size        = device->info->mem_alignment,
214             .page_count       = DIV_ROUND_UP(bo->size,
215                                                 device->info->mem_alignment),
216             .pid              = getpid(),
217             .virtual_address  = bo->offset,
218             .physical_address = bo->offset,
219             .is_unmap         = false,
220             },
221       },
222    };
223    util_dynarray_append(&device->vk.memory_trace_data.tokens,
224                         struct vk_rmv_token, token);
225 
226    bo->gtt_mapped = true;
227 
228    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
229 }
230 
231 void
anv_rmv_log_bos_gtt_map(struct anv_device * device,struct anv_bo ** bos,uint32_t bo_count)232 anv_rmv_log_bos_gtt_map(struct anv_device *device,
233                         struct anv_bo **bos,
234                         uint32_t bo_count)
235 {
236    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
237    for (uint32_t i = 0; i < bo_count; i++) {
238       struct anv_bo *bo = bos[i];
239 
240       if (bo->gtt_mapped)
241          continue;
242 
243       struct vk_rmv_token token = {
244          .type      = VK_RMV_TOKEN_TYPE_PAGE_TABLE_UPDATE,
245          .timestamp = (uint64_t)os_time_get_nano(),
246          .data      = {
247             .page_table_update = {
248                .type             = VK_RMV_PAGE_TABLE_UPDATE_TYPE_UPDATE,
249                .page_size        = device->info->mem_alignment,
250                .page_count       = DIV_ROUND_UP(bo->size,
251                                                 device->info->mem_alignment),
252                .pid              = getpid(),
253                .virtual_address  = bo->offset,
254                .physical_address = bo->offset,
255                .is_unmap         = false,
256             },
257          },
258       };
259       util_dynarray_append(&device->vk.memory_trace_data.tokens,
260                            struct vk_rmv_token, token);
261 
262       bo->gtt_mapped = true;
263    }
264    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
265 }
266 
267 void
anv_rmv_log_vm_binds(struct anv_device * device,struct anv_vm_bind * binds,uint32_t bind_count)268 anv_rmv_log_vm_binds(struct anv_device *device,
269                      struct anv_vm_bind *binds,
270                      uint32_t bind_count)
271 {
272    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
273    for (uint32_t i = 0; i < bind_count; i++) {
274 
275       struct vk_rmv_token token = {
276          .type      = VK_RMV_TOKEN_TYPE_PAGE_TABLE_UPDATE,
277          .timestamp = (uint64_t)os_time_get_nano(),
278          .data      = {
279             .page_table_update = {
280                .type             = VK_RMV_PAGE_TABLE_UPDATE_TYPE_UPDATE,
281                .page_size        = device->info->mem_alignment,
282                .page_count       = DIV_ROUND_UP(binds[i].size,
283                                                 device->info->mem_alignment),
284                .pid              = getpid(),
285                .virtual_address  = binds[i].address,
286                .physical_address = binds[i].bo_offset,
287                .is_unmap         = binds[i].op == ANV_VM_UNBIND,
288             },
289          },
290       };
291       util_dynarray_append(&device->vk.memory_trace_data.tokens,
292                            struct vk_rmv_token, token);
293    }
294    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
295 }
296 
297 void
anv_rmv_log_heap_create(struct anv_device * device,struct anv_device_memory * memory,bool is_internal,VkMemoryAllocateFlags alloc_flags)298 anv_rmv_log_heap_create(struct anv_device *device,
299                         struct anv_device_memory *memory,
300                         bool is_internal,
301                         VkMemoryAllocateFlags alloc_flags)
302 {
303    /* Do not log zero-sized device memory objects. */
304    if (!memory->vk.size)
305       return;
306 
307    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
308 
309    struct vk_rmv_resource_create_token token = {
310       .type               = VK_RMV_RESOURCE_TYPE_HEAP,
311       .resource_id        = resource_id_locked(device, memory),
312       .is_driver_internal = is_internal,
313       .heap = {
314          .alignment   = device->info->mem_alignment,
315          .size        = memory->vk.size,
316          .heap_index  = anv_heap_index_to_memory_location(device,
317                                                           memory->type->heapIndex),
318          .alloc_flags = alloc_flags,
319       },
320    };
321 
322    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token);
323    log_resource_bind_locked(device, token.resource_id, memory->bo, 0, memory->vk.size);
324    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
325 }
326 
327 static void
anv_rmv_log_vma_locked(struct anv_device * device,uint64_t address,uint64_t size,bool internal,bool vram,bool in_invisible_vram)328 anv_rmv_log_vma_locked(struct anv_device *device, uint64_t address, uint64_t size,
329                        bool internal, bool vram, bool in_invisible_vram)
330 {
331    struct vk_rmv_virtual_allocate_token token = {
332       .address              = address,
333       /* If all VRAM is visible, no bo will be in invisible memory. */
334       .is_in_invisible_vram = in_invisible_vram,
335       .preferred_domains    = (vram ?
336                                VK_RMV_KERNEL_MEMORY_DOMAIN_VRAM :
337                                VK_RMV_KERNEL_MEMORY_DOMAIN_GTT),
338       .is_driver_internal   = internal,
339       .page_count           = DIV_ROUND_UP(size, 4096),
340    };
341 
342 
343    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_ALLOCATE, &token);
344 }
345 
346 void
anv_rmv_log_bo_allocate(struct anv_device * device,struct anv_bo * bo)347 anv_rmv_log_bo_allocate(struct anv_device *device,
348                         struct anv_bo *bo)
349 {
350    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
351    anv_rmv_log_vma_locked(device, bo->offset, bo->size,
352                           bo->alloc_flags & ANV_BO_ALLOC_INTERNAL,
353                           (bo->alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM) == 0,
354                           device->physical->vram_non_mappable.size != 0 &&
355                           (bo->alloc_flags & (ANV_BO_ALLOC_MAPPED |
356                                               ANV_BO_ALLOC_HOST_CACHED_COHERENT |
357                                               ANV_BO_ALLOC_LOCAL_MEM_CPU_VISIBLE |
358                                               ANV_BO_ALLOC_NO_LOCAL_MEM)) == 0);
359    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
360 
361    if (bo->alloc_flags & ANV_BO_ALLOC_MAPPED)
362       vk_rmv_log_cpu_map(&device->vk, bo->offset, false);
363 }
364 
365 void
anv_rmv_log_bo_destroy(struct anv_device * device,struct anv_bo * bo)366 anv_rmv_log_bo_destroy(struct anv_device *device, struct anv_bo *bo)
367 {
368    struct vk_rmv_virtual_free_token token = {
369       .address = bo->offset,
370    };
371 
372    if (bo->alloc_flags & ANV_BO_ALLOC_MAPPED)
373       vk_rmv_log_cpu_map(&device->vk, bo->offset, true);
374    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
375    anv_rmv_log_bo_gtt_unmap_locked(device, bo);
376    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token);
377    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
378 }
379 
380 void
anv_rmv_log_buffer_create(struct anv_device * device,bool is_internal,struct anv_buffer * buffer)381 anv_rmv_log_buffer_create(struct anv_device *device,
382                           bool is_internal,
383                           struct anv_buffer *buffer)
384 {
385    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
386    struct vk_rmv_resource_create_token token = {
387       .type               = VK_RMV_RESOURCE_TYPE_BUFFER,
388       .is_driver_internal = is_internal,
389       .resource_id        = resource_id_locked(device, buffer),
390       .buffer             = {
391          .create_flags = buffer->vk.create_flags,
392          .size         = buffer->vk.size,
393          .usage_flags  = buffer->vk.usage,
394       },
395    };
396 
397    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token);
398    if (buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
399       assert(buffer->sparse_data.size != 0);
400       anv_rmv_log_vma_locked(device,
401                              buffer->sparse_data.address,
402                              buffer->sparse_data.size,
403                              false /* internal */, true /* TODO: vram */,
404                              true /* in_invisible_vram */);
405       log_resource_bind_locked(device,
406                                resource_id_locked(device, buffer),
407                                NULL,
408                                buffer->sparse_data.address,
409                                buffer->sparse_data.size);
410    }
411    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
412 
413 }
414 
415 void
anv_rmv_log_buffer_destroy(struct anv_device * device,struct anv_buffer * buffer)416 anv_rmv_log_buffer_destroy(struct anv_device *device,
417                            struct anv_buffer *buffer)
418 {
419    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
420    if (buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
421       struct vk_rmv_virtual_free_token token = {
422          .address = buffer->sparse_data.address,
423       };
424       vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token);
425    }
426    resource_destroy_locked(device, buffer);
427    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
428 
429 }
430 
431 void
anv_rmv_log_buffer_bind(struct anv_device * device,struct anv_buffer * buffer)432 anv_rmv_log_buffer_bind(struct anv_device *device, struct anv_buffer *buffer)
433 {
434    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
435    log_resource_bind_locked(device,
436                             resource_id_locked(device, buffer),
437                             buffer->address.bo,
438                             buffer->address.offset, buffer->vk.size);
439    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
440 }
441 
442 void
anv_rmv_log_image_create(struct anv_device * device,bool is_internal,struct anv_image * image)443 anv_rmv_log_image_create(struct anv_device *device,
444                          bool is_internal,
445                          struct anv_image *image)
446 {
447    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
448    struct vk_rmv_resource_create_token token = {
449       .type               = VK_RMV_RESOURCE_TYPE_IMAGE,
450       .resource_id        = resource_id_locked(device, image),
451       .is_driver_internal = is_internal,
452       .image              = {
453          .create_flags            = image->vk.create_flags,
454          .usage_flags             = image->vk.usage,
455          .type                    = image->vk.image_type,
456          .extent                  = image->vk.extent,
457          .format                  = image->vk.format,
458          .num_mips                = image->vk.mip_levels,
459          .num_slices              = image->vk.array_layers,
460          .tiling                  = image->vk.tiling,
461          .alignment_log2          = util_logbase2(
462             image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].memory_range.alignment),
463          .log2_samples            = util_logbase2(image->vk.samples),
464          .metadata_alignment_log2 = util_logbase2(
465             image->planes[0].aux_surface.isl.alignment_B),
466          .image_alignment_log2    = util_logbase2(
467             image->planes[0].primary_surface.isl.alignment_B),
468          .size                    = image->planes[0].primary_surface.memory_range.size,
469          .metadata_size           = image->planes[0].aux_surface.memory_range.size,
470          .metadata_header_size    = 0,
471          .metadata_offset         = image->planes[0].aux_surface.memory_range.offset,
472          .metadata_header_offset  = image->planes[0].aux_surface.memory_range.offset,
473          .presentable             = (image->planes[0].primary_surface.isl.usage &
474                                      ISL_SURF_USAGE_DISPLAY_BIT) != 0,
475       },
476    };
477 
478    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token);
479    if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
480       for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) {
481          if (image->bindings[b].sparse_data.size != 0) {
482             anv_rmv_log_vma_locked(device,
483                                    image->bindings[b].sparse_data.address,
484                                    image->bindings[b].sparse_data.size,
485                                    false /* internal */, true /* TODO: vram */,
486                                    true /* in_invisible_vram */);
487             log_resource_bind_locked(device,
488                                      resource_id_locked(device, image),
489                                      NULL,
490                                      image->bindings[b].sparse_data.address,
491                                      image->bindings[b].sparse_data.size);
492          }
493       }
494    }
495    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
496 }
497 
498 void
anv_rmv_log_image_destroy(struct anv_device * device,struct anv_image * image)499 anv_rmv_log_image_destroy(struct anv_device *device,
500                           struct anv_image *image)
501 {
502    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
503    if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
504       for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) {
505          if (image->bindings[b].sparse_data.size != 0) {
506             struct vk_rmv_virtual_free_token token = {
507                .address = image->bindings[b].sparse_data.address,
508             };
509 
510             vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token);
511          }
512       }
513    }
514    resource_destroy_locked(device, image);
515    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
516 }
517 
518 void
anv_rmv_log_image_bind(struct anv_device * device,struct anv_image * image,enum anv_image_memory_binding binding)519 anv_rmv_log_image_bind(struct anv_device *device,
520                        struct anv_image *image,
521                        enum anv_image_memory_binding binding)
522 {
523    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
524    log_resource_bind_locked(device,
525                             resource_id_locked(device, image),
526                             image->bindings[binding].address.bo,
527                             image->bindings[binding].address.offset,
528                             image->bindings[binding].memory_range.size);
529    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
530 }
531 
532 void
anv_rmv_log_query_pool_create(struct anv_device * device,struct anv_query_pool * pool,bool is_internal)533 anv_rmv_log_query_pool_create(struct anv_device *device,
534                               struct anv_query_pool *pool,
535                               bool is_internal)
536 {
537    if (pool->vk.query_type != VK_QUERY_TYPE_OCCLUSION &&
538        pool->vk.query_type != VK_QUERY_TYPE_PIPELINE_STATISTICS &&
539        pool->vk.query_type != VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)
540       return;
541 
542    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
543    struct vk_rmv_resource_create_token create_token = {
544       .type               = VK_RMV_RESOURCE_TYPE_QUERY_HEAP,
545       .resource_id        = resource_id_locked(device, pool),
546       .is_driver_internal = is_internal,
547       .query_pool = {
548          .type           = pool->vk.query_type,
549          .has_cpu_access = true,
550       },
551    };
552 
553    vk_rmv_emit_token(&device->vk.memory_trace_data,
554                      VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
555    log_resource_bind_locked(device, create_token.resource_id,
556                             pool->bo, 0, pool->bo->size);
557    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
558 }
559 
560 static void
bind_cmd_buffer_state_stream_locked(struct anv_device * device,uint64_t resource_id,struct anv_state_stream * stream)561 bind_cmd_buffer_state_stream_locked(struct anv_device *device,
562                                     uint64_t resource_id,
563                                     struct anv_state_stream *stream)
564 {
565    util_dynarray_foreach(&stream->all_blocks, struct anv_state, block)
566       log_state_pool_bind_locked(device, resource_id, stream->state_pool, block);
567 }
568 
569 void
anv_rmv_log_cmd_buffer_create(struct anv_device * device,struct anv_cmd_buffer * cmd_buffer)570 anv_rmv_log_cmd_buffer_create(struct anv_device *device,
571                               struct anv_cmd_buffer *cmd_buffer)
572 {
573    uint64_t data_size =
574       cmd_buffer->surface_state_stream.total_size +
575       cmd_buffer->dynamic_state_stream.total_size +
576       cmd_buffer->general_state_stream.total_size +
577       cmd_buffer->indirect_push_descriptor_stream.total_size;
578 
579    uint64_t executable_size = 0;
580    list_for_each_entry(struct anv_batch_bo, bbo, &cmd_buffer->batch_bos, link)
581       executable_size += bbo->length;
582 
583    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
584    struct vk_rmv_resource_create_token create_token = {
585       .type               = VK_RMV_RESOURCE_TYPE_COMMAND_ALLOCATOR,
586       .resource_id        = resource_id_locked(device, cmd_buffer),
587       .is_driver_internal = true,
588       .command_buffer     = {
589          .preferred_domain                 = VK_RMV_KERNEL_MEMORY_DOMAIN_GTT /* TODO */,
590          .executable_size                  = executable_size,
591          .app_available_executable_size    = executable_size,
592          .embedded_data_size               = data_size,
593          .app_available_embedded_data_size = data_size,
594          .scratch_size                     = 0,
595          .app_available_scratch_size       = 0,
596       },
597    };
598 
599    vk_rmv_emit_token(&device->vk.memory_trace_data,
600                      VK_RMV_TOKEN_TYPE_RESOURCE_CREATE,
601                      &create_token);
602    list_for_each_entry(struct anv_batch_bo, bbo, &cmd_buffer->batch_bos, link) {
603       log_resource_bind_locked(device, create_token.resource_id,
604                                bbo->bo, 0, bbo->length);
605    }
606    bind_cmd_buffer_state_stream_locked(device, create_token.resource_id,
607                                        &cmd_buffer->surface_state_stream);
608    bind_cmd_buffer_state_stream_locked(device, create_token.resource_id,
609                                        &cmd_buffer->dynamic_state_stream);
610    bind_cmd_buffer_state_stream_locked(device, create_token.resource_id,
611                                        &cmd_buffer->general_state_stream);
612    bind_cmd_buffer_state_stream_locked(device, create_token.resource_id,
613                                        &cmd_buffer->indirect_push_descriptor_stream);
614    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
615 }
616 
617 void
anv_rmv_log_cmd_buffer_destroy(struct anv_device * device,struct anv_cmd_buffer * cmd_buffer)618 anv_rmv_log_cmd_buffer_destroy(struct anv_device *device,
619                                struct anv_cmd_buffer *cmd_buffer)
620 {
621    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
622    struct vk_rmv_resource_destroy_token destroy_token = {
623       .resource_id = resource_id_locked(device, cmd_buffer),
624    };
625 
626    vk_rmv_emit_token(&device->vk.memory_trace_data,
627                      VK_RMV_TOKEN_TYPE_RESOURCE_DESTROY, &destroy_token);
628    resource_destroy_locked(device, cmd_buffer);
629    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
630 }
631 
632 void
anv_rmv_log_sparse_add_residency(struct anv_device * device,struct anv_bo * src_bo,uint64_t offset)633 anv_rmv_log_sparse_add_residency(struct anv_device *device,
634                                  struct anv_bo *src_bo,
635                                  uint64_t offset)
636 {
637    struct vk_rmv_resource_reference_token token = {
638       .virtual_address   = src_bo->offset + offset,
639       .residency_removed = false,
640    };
641 
642    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
643    vk_rmv_emit_token(&device->vk.memory_trace_data,
644                      VK_RMV_TOKEN_TYPE_RESOURCE_REFERENCE, &token);
645    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
646 }
647 
648 void
anv_rmv_log_sparse_remove_residency(struct anv_device * device,struct anv_bo * src_bo,uint64_t offset)649 anv_rmv_log_sparse_remove_residency(struct anv_device *device,
650                                     struct anv_bo *src_bo,
651                                     uint64_t offset)
652 {
653    struct vk_rmv_resource_reference_token token = {
654       .virtual_address   = src_bo->offset + offset,
655       .residency_removed = true,
656    };
657 
658    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
659    vk_rmv_emit_token(&device->vk.memory_trace_data,
660                      VK_RMV_TOKEN_TYPE_RESOURCE_REFERENCE, &token);
661    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
662 }
663 
664 void
anv_rmv_log_descriptor_pool_create(struct anv_device * device,const VkDescriptorPoolCreateInfo * create_info,struct anv_descriptor_pool * pool,bool is_internal)665 anv_rmv_log_descriptor_pool_create(struct anv_device *device,
666                                    const VkDescriptorPoolCreateInfo *create_info,
667                                    struct anv_descriptor_pool *pool,
668                                    bool is_internal)
669 {
670    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
671    struct vk_rmv_resource_create_token create_token = {
672       .type               = VK_RMV_RESOURCE_TYPE_DESCRIPTOR_POOL,
673       .resource_id        = resource_id_locked(device, pool),
674       .is_driver_internal = false,
675       .descriptor_pool    = {
676          .max_sets        = create_info->maxSets,
677          .pool_size_count = create_info->poolSizeCount,
678          /* Using vk_rmv_token_pool_alloc frees the allocation automatically
679           * when the trace is done. */
680          .pool_sizes      = malloc(create_info->poolSizeCount *
681                                    sizeof(VkDescriptorPoolSize)),
682       },
683    };
684 
685    if (!create_token.descriptor_pool.pool_sizes) {
686       simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
687       return;
688    }
689 
690    memcpy(create_token.descriptor_pool.pool_sizes, create_info->pPoolSizes,
691           create_info->poolSizeCount * sizeof(VkDescriptorPoolSize));
692 
693    vk_rmv_emit_token(&device->vk.memory_trace_data,
694                      VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
695    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
696 
697    if (pool->surfaces.bo) {
698       struct vk_rmv_resource_bind_token bind_token = {
699          .resource_id      = create_token.resource_id,
700          .is_system_memory = false,
701          .address          = pool->surfaces.bo->offset,
702          .size             = pool->surfaces.bo->size,
703       };
704 
705       simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
706       vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_BIND, &bind_token);
707       simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
708    }
709    if (pool->samplers.bo) {
710       struct vk_rmv_resource_bind_token bind_token = {
711          .resource_id      = create_token.resource_id,
712          .is_system_memory = false,
713          .address          = pool->samplers.bo->offset,
714          .size             = pool->samplers.bo->size,
715       };
716 
717       simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
718       vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_BIND, &bind_token);
719       simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
720    }
721 }
722 
723 void
anv_rmv_log_graphics_pipeline_create(struct anv_device * device,struct anv_graphics_pipeline * pipeline,bool is_internal)724 anv_rmv_log_graphics_pipeline_create(struct anv_device *device,
725                                      struct anv_graphics_pipeline *pipeline,
726                                      bool is_internal)
727 {
728    struct vk_rmv_resource_create_token create_token = {
729       .type               = VK_RMV_RESOURCE_TYPE_PIPELINE,
730       .resource_id        = resource_id_locked(device, pipeline),
731       .is_driver_internal = is_internal,
732       .pipeline           = {
733          .is_internal   = is_internal,
734          .hash_lo       = 0,/* TODO pipeline->pipeline_hash; */
735          .shader_stages = pipeline->base.base.active_stages,
736       },
737    };
738 
739    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
740    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
741    for (unsigned s = 0; s < ARRAY_SIZE(pipeline->base.shaders); s++) {
742       struct anv_shader_bin *shader = pipeline->base.shaders[s];
743 
744       if (!shader)
745          continue;
746 
747       log_state_pool_bind_locked(device, create_token.resource_id,
748                                  &device->instruction_state_pool,
749                                  &shader->kernel);
750    }
751    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
752 }
753 
754 void
anv_rmv_log_compute_pipeline_create(struct anv_device * device,struct anv_compute_pipeline * pipeline,bool is_internal)755 anv_rmv_log_compute_pipeline_create(struct anv_device *device,
756                                     struct anv_compute_pipeline *pipeline,
757                                     bool is_internal)
758 {
759    VkShaderStageFlagBits active_stages =
760       pipeline->base.type == ANV_PIPELINE_COMPUTE ?
761       VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_RAYGEN_BIT_KHR;
762 
763    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
764    struct vk_rmv_resource_create_token create_token = {
765       .type               = VK_RMV_RESOURCE_TYPE_PIPELINE,
766       .resource_id        = resource_id_locked(device, pipeline),
767       .is_driver_internal = is_internal,
768       .pipeline           = {
769          .is_internal   = is_internal,
770          .hash_lo       = 0,/* TODO pipeline->pipeline_hash; */
771          .shader_stages = active_stages,
772       },
773    };
774 
775    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
776    struct anv_shader_bin *shader = pipeline->cs;
777    log_state_pool_bind_locked(device, create_token.resource_id,
778                               &device->instruction_state_pool,
779                               &shader->kernel);
780    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
781 }
782 
783 void
anv_rmv_log_rt_pipeline_create(struct anv_device * device,struct anv_ray_tracing_pipeline * pipeline,bool is_internal)784 anv_rmv_log_rt_pipeline_create(struct anv_device *device,
785                                struct anv_ray_tracing_pipeline *pipeline,
786                                bool is_internal)
787 {
788    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
789 
790    struct vk_rmv_resource_create_token create_token = {
791       .resource_id        = resource_id_locked(device, pipeline),
792       .type               = VK_RMV_RESOURCE_TYPE_PIPELINE,
793       .is_driver_internal = is_internal,
794       .pipeline           = {
795          .is_internal   = is_internal,
796          .hash_lo       = 0, /* TODO */
797          .shader_stages = pipeline->base.active_stages,
798       },
799    };
800    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
801 
802    struct anv_state_pool *state_pool = &device->instruction_state_pool;
803    for (uint32_t i = 0; i < pipeline->group_count; i++) {
804       struct anv_rt_shader_group *group = &pipeline->groups[i];
805 
806       if (group->imported)
807          continue;
808 
809       if (group->general) {
810          log_state_pool_bind_locked(device, create_token.resource_id, state_pool,
811                                     &group->general->kernel);
812       }
813       if (group->closest_hit) {
814          log_state_pool_bind_locked(device, create_token.resource_id, state_pool,
815                                     &group->closest_hit->kernel);
816       }
817       if (group->any_hit) {
818          log_state_pool_bind_locked(device, create_token.resource_id, state_pool,
819                                     &group->any_hit->kernel);
820       }
821       if (group->intersection) {
822          log_state_pool_bind_locked(device, create_token.resource_id, state_pool,
823                                     &group->intersection->kernel);
824       }
825    }
826 
827    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
828 }
829 
830 void
anv_rmv_log_event_create(struct anv_device * device,struct anv_event * event,VkEventCreateFlags flags,bool is_internal)831 anv_rmv_log_event_create(struct anv_device *device,
832                          struct anv_event *event,
833                          VkEventCreateFlags flags,
834                          bool is_internal)
835 {
836    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
837    struct vk_rmv_resource_create_token create_token = {
838       .type               = VK_RMV_RESOURCE_TYPE_GPU_EVENT,
839       .resource_id        = resource_id_locked(device, event),
840       .is_driver_internal = is_internal,
841       .event              = {
842          .flags = flags,
843       },
844    };
845 
846    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &create_token);
847    log_state_pool_bind_locked(device, create_token.resource_id,
848                               &device->dynamic_state_pool,
849                               &event->state);
850    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
851 }
852 
853 void
anv_rmv_log_resource_destroy(struct anv_device * device,const void * obj)854 anv_rmv_log_resource_destroy(struct anv_device *device, const void *obj)
855 {
856    simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
857    struct vk_rmv_resource_destroy_token token = {
858       .resource_id = resource_id_locked(device, obj),
859    };
860 
861    vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_DESTROY, &token);
862    resource_destroy_locked(device, obj);
863    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
864 }
865