1 /*
2 * Copyright 2024 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "panvk_utrace.h"
7
8 #include "kmod/pan_kmod.h"
9 #include "util/log.h"
10 #include "util/timespec.h"
11 #include "panvk_device.h"
12 #include "panvk_physical_device.h"
13 #include "panvk_priv_bo.h"
14 #include "vk_sync.h"
15
16 static struct panvk_device *
to_dev(struct u_trace_context * utctx)17 to_dev(struct u_trace_context *utctx)
18 {
19 return container_of(utctx, struct panvk_device, utrace.utctx);
20 }
21
22 void *
panvk_utrace_create_buffer(struct u_trace_context * utctx,uint64_t size_B)23 panvk_utrace_create_buffer(struct u_trace_context *utctx, uint64_t size_B)
24 {
25 struct panvk_device *dev = to_dev(utctx);
26 struct panvk_priv_bo *bo;
27
28 if (panvk_priv_bo_create(dev, size_B, 0, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE,
29 &bo) != VK_SUCCESS)
30 return NULL;
31
32 return bo;
33 }
34
35 void
panvk_utrace_delete_buffer(struct u_trace_context * utctx,void * buffer)36 panvk_utrace_delete_buffer(struct u_trace_context *utctx, void *buffer)
37 {
38 struct panvk_priv_bo *bo = buffer;
39 panvk_priv_bo_unref(bo);
40 }
41
42 uint64_t
panvk_utrace_read_ts(struct u_trace_context * utctx,void * timestamps,uint64_t offset_B,void * flush_data)43 panvk_utrace_read_ts(struct u_trace_context *utctx, void *timestamps,
44 uint64_t offset_B, void *flush_data)
45 {
46 struct panvk_device *dev = to_dev(utctx);
47 const struct panvk_physical_device *pdev =
48 to_panvk_physical_device(dev->vk.physical);
49 const struct pan_kmod_dev_props *props = &pdev->kmod.props;
50 const struct panvk_priv_bo *bo = timestamps;
51 struct panvk_utrace_flush_data *data = flush_data;
52
53 assert(props->timestamp_frequency);
54
55 /* wait for the submit */
56 if (data->sync) {
57 if (vk_sync_wait(&dev->vk, data->sync, data->wait_value,
58 VK_SYNC_WAIT_COMPLETE, UINT64_MAX) != VK_SUCCESS)
59 mesa_logw("failed to wait for utrace timestamps");
60
61 data->sync = NULL;
62 data->wait_value = 0;
63 }
64
65 const uint64_t *ts_ptr = bo->addr.host + offset_B;
66 uint64_t ts = *ts_ptr;
67 if (ts != U_TRACE_NO_TIMESTAMP)
68 ts = (ts * NSEC_PER_SEC) / props->timestamp_frequency;
69
70 return ts;
71 }
72
73 void
panvk_utrace_delete_flush_data(struct u_trace_context * utctx,void * flush_data)74 panvk_utrace_delete_flush_data(struct u_trace_context *utctx, void *flush_data)
75 {
76 struct panvk_utrace_flush_data *data = flush_data;
77
78 if (data->clone_pool.dev)
79 panvk_pool_cleanup(&data->clone_pool);
80
81 free(data);
82 }
83