1 /*
2  * Copyright © 2022 Friedrich Vock
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 #ifndef VK_RMV_COMMON_H
25 #define VK_RMV_COMMON_H
26 
27 #include <stdbool.h>
28 #include "util/hash_table.h"
29 #include "util/simple_mtx.h"
30 #include "util/u_debug.h"
31 #include "util/u_dynarray.h"
32 #include <vulkan/vulkan_core.h>
33 #include "vk_rmv_tokens.h"
34 
35 struct vk_memory_trace_data;
36 
37 /*
38  * The different memory domains RMV supports.
39  */
40 enum vk_rmv_memory_location {
41    /* DEVICE_LOCAL | HOST_VISIBLE */
42    VK_RMV_MEMORY_LOCATION_DEVICE,
43    /* DEVICE_LOCAL */
44    VK_RMV_MEMORY_LOCATION_DEVICE_INVISIBLE,
45    /* HOST_VISIBLE | HOST_COHERENT */
46    VK_RMV_MEMORY_LOCATION_HOST,
47 
48    /* add above here */
49    VK_RMV_MEMORY_LOCATION_COUNT
50 };
51 
52 /*
53  * Information about a memory domain.
54  */
55 struct vk_rmv_memory_info {
56    uint64_t size;
57    uint64_t physical_base_address;
58 };
59 
60 enum vk_rmv_memory_type {
61    VK_RMV_MEMORY_TYPE_UNKNOWN,
62    VK_RMV_MEMORY_TYPE_DDR2,
63    VK_RMV_MEMORY_TYPE_DDR3,
64    VK_RMV_MEMORY_TYPE_DDR4,
65    VK_RMV_MEMORY_TYPE_GDDR5,
66    VK_RMV_MEMORY_TYPE_GDDR6,
67    VK_RMV_MEMORY_TYPE_HBM,
68    VK_RMV_MEMORY_TYPE_HBM2,
69    VK_RMV_MEMORY_TYPE_HBM3,
70    VK_RMV_MEMORY_TYPE_LPDDR4,
71    VK_RMV_MEMORY_TYPE_LPDDR5,
72    VK_RMV_MEMORY_TYPE_DDR5
73 };
74 
75 /*
76  * Device information for RMV traces.
77  */
78 struct vk_rmv_device_info {
79    struct vk_rmv_memory_info memory_infos[VK_RMV_MEMORY_LOCATION_COUNT];
80 
81    /* The memory type of dedicated VRAM. */
82    enum vk_rmv_memory_type vram_type;
83 
84    char device_name[128];
85 
86    uint32_t pcie_family_id;
87    uint32_t pcie_revision_id;
88    uint32_t pcie_device_id;
89    /* The minimum shader clock, in MHz. */
90    uint32_t minimum_shader_clock;
91    /* The maximum shader clock, in MHz. */
92    uint32_t maximum_shader_clock;
93    uint32_t vram_operations_per_clock;
94    uint32_t vram_bus_width;
95    /* The VRAM bandwidth, in GB/s (1 GB/s = 1000 MB/s). */
96    uint32_t vram_bandwidth;
97    /* The minimum memory clock, in MHz. */
98    uint32_t minimum_memory_clock;
99    /* The maximum memory clock, in MHz. */
100    uint32_t maximum_memory_clock;
101 };
102 
103 struct vk_device;
104 
105 struct vk_memory_trace_data {
106    struct util_dynarray tokens;
107    simple_mtx_t token_mtx;
108 
109    bool is_enabled;
110 
111    struct vk_rmv_device_info device_info;
112 
113    struct hash_table_u64 *handle_table;
114    uint32_t next_resource_id;
115 };
116 
117 struct vk_device;
118 
119 void vk_memory_trace_init(struct vk_device *device, const struct vk_rmv_device_info *device_info);
120 
121 void vk_memory_trace_finish(struct vk_device *device);
122 
123 int vk_dump_rmv_capture(struct vk_memory_trace_data *data);
124 
125 void vk_rmv_emit_token(struct vk_memory_trace_data *data, enum vk_rmv_token_type type,
126                        void *token_data);
127 void vk_rmv_log_buffer_create(struct vk_device *device, bool is_internal, VkBuffer _buffer);
128 void vk_rmv_log_cpu_map(struct vk_device *device, uint64_t va, bool is_unmap);
129 void vk_rmv_log_misc_token(struct vk_device *device, enum vk_rmv_misc_event_type type);
130 
131 /* Retrieves the unique resource id for the resource specified by handle.
132  * Allocates a new id if none exists already.
133  * The memory trace mutex should be locked when entering this function. */
134 uint32_t vk_rmv_get_resource_id_locked(struct vk_device *device, uint64_t handle);
135 /* Destroys a resource id. If the same handle is allocated again, a new resource
136  * id is given to it.
137  * The memory trace mutex should be locked when entering this function. */
138 void vk_rmv_destroy_resource_id_locked(struct vk_device *device, uint64_t handle);
139 
140 #endif
141