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