2 * Copyright © 2020 Valve Corporation
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:
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
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
26 #include "radv_private.h"
28 #include "util/u_process.h"
30 #include "drm-uapi/amdgpu_drm.h"
32 #define SQTT_FILE_MAGIC_NUMBER 0x50303042
33 #define SQTT_FILE_VERSION_MAJOR 1
34 #define SQTT_FILE_VERSION_MINOR 4
36 #define SQTT_GPU_NAME_MAX_SIZE 256
37 #define SQTT_MAX_NUM_SE 32
38 #define SQTT_SA_PER_SE 2
41 SQTT_VERSION_NONE
= 0x0,
42 SQTT_VERSION_1_0
= 0x1,
43 SQTT_VERSION_1_1
= 0x2,
44 SQTT_VERSION_2_0
= 0x3, /* GFX6 */
45 SQTT_VERSION_2_1
= 0x4, /* GFX7 */
46 SQTT_VERSION_2_2
= 0x5, /* GFX8 */
47 SQTT_VERSION_2_3
= 0x6, /* GFX9 */
48 SQTT_VERSION_2_4
= 0x7 /* GFX10 */
54 enum sqtt_file_chunk_type
{
55 SQTT_FILE_CHUNK_TYPE_ASIC_INFO
,
56 SQTT_FILE_CHUNK_TYPE_SQTT_DESC
,
57 SQTT_FILE_CHUNK_TYPE_SQTT_DATA
,
58 SQTT_FILE_CHUNK_TYPE_API_INFO
,
59 SQTT_FILE_CHUNK_TYPE_ISA_DATABASE
,
60 SQTT_FILE_CHUNK_TYPE_QUEUE_EVENT_TIMINGS
,
61 SQTT_FILE_CHUNK_TYPE_CLOCK_CALIBRATION
,
62 SQTT_FILE_CHUNK_TYPE_CPU_INFO
,
63 SQTT_FILE_CHUNK_TYPE_SPM_DB
,
64 SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_DATABASE
,
65 SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_LOADER_EVENTS
,
66 SQTT_FILE_CHUNK_TYPE_PSO_CORRELATION
,
67 SQTT_FILE_CHUNK_TYPE_INSTRUMENTATION_TABLE
,
68 SQTT_FILE_CHUNK_TYPE_COUNT
71 struct sqtt_file_chunk_id
{
72 enum sqtt_file_chunk_type type
: 8;
74 int32_t reserved
: 16;
77 struct sqtt_file_chunk_header
{
78 struct sqtt_file_chunk_id chunk_id
;
79 uint16_t minor_version
;
80 uint16_t major_version
;
81 int32_t size_in_bytes
;
88 struct sqtt_file_header_flags
{
91 int32_t is_semaphore_queue_timing_etw
: 1;
92 int32_t no_queue_semaphore_timestamps
: 1;
93 int32_t reserved
: 30;
100 struct sqtt_file_header
{
101 uint32_t magic_number
;
102 uint32_t version_major
;
103 uint32_t version_minor
;
104 struct sqtt_file_header_flags flags
;
105 int32_t chunk_offset
;
109 int32_t day_in_month
;
114 int32_t is_daylight_savings
;
117 static_assert(sizeof(struct sqtt_file_header
) == 56,
118 "sqtt_file_header doesn't match RGP spec");
121 radv_sqtt_fill_header(struct sqtt_file_header
*header
)
123 struct tm
*timep
, result
;
126 header
->magic_number
= SQTT_FILE_MAGIC_NUMBER
;
127 header
->version_major
= SQTT_FILE_VERSION_MAJOR
;
128 header
->version_minor
= SQTT_FILE_VERSION_MINOR
;
129 header
->flags
.value
= 0;
130 header
->flags
.is_semaphore_queue_timing_etw
= 1;
131 header
->flags
.no_queue_semaphore_timestamps
= 0;
132 header
->chunk_offset
= sizeof(*header
);
135 timep
= localtime_r(&raw_time
, &result
);
137 header
->second
= timep
->tm_sec
;
138 header
->minute
= timep
->tm_min
;
139 header
->hour
= timep
->tm_hour
;
140 header
->day_in_month
= timep
->tm_mday
;
141 header
->month
= timep
->tm_mon
;
142 header
->year
= timep
->tm_year
;
143 header
->day_in_week
= timep
->tm_wday
;
144 header
->day_in_year
= timep
->tm_yday
;
145 header
->is_daylight_savings
= timep
->tm_isdst
;
151 struct sqtt_file_chunk_cpu_info
{
152 struct sqtt_file_chunk_header header
;
153 uint32_t vendor_id
[4];
154 uint32_t processor_brand
[12];
155 uint32_t reserved
[2];
156 uint64_t cpu_timestamp_freq
;
157 uint32_t clock_speed
;
158 uint32_t num_logical_cores
;
159 uint32_t num_physical_cores
;
160 uint32_t system_ram_size
;
163 static_assert(sizeof(struct sqtt_file_chunk_cpu_info
) == 112,
164 "sqtt_file_chunk_cpu_info doesn't match RGP spec");
167 radv_sqtt_fill_cpu_info(struct sqtt_file_chunk_cpu_info
*chunk
)
169 uint64_t system_ram_size
= 0;
171 chunk
->header
.chunk_id
.type
= SQTT_FILE_CHUNK_TYPE_CPU_INFO
;
172 chunk
->header
.chunk_id
.index
= 0;
173 chunk
->header
.major_version
= 0;
174 chunk
->header
.minor_version
= 0;
175 chunk
->header
.size_in_bytes
= sizeof(*chunk
);
177 chunk
->cpu_timestamp_freq
= 1000000000; /* tick set to 1ns */
179 /* TODO: fill with real info. */
181 strncpy((char *)chunk
->vendor_id
, "Unknown", sizeof(chunk
->vendor_id
));
182 strncpy((char *)chunk
->processor_brand
, "Unknown", sizeof(chunk
->processor_brand
));
183 chunk
->clock_speed
= 0;
184 chunk
->num_logical_cores
= 0;
185 chunk
->num_physical_cores
= 0;
187 chunk
->system_ram_size
= 0;
188 if (os_get_total_physical_memory(&system_ram_size
))
189 chunk
->system_ram_size
= system_ram_size
/ (1024 * 1024);
195 enum sqtt_file_chunk_asic_info_flags
197 SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING
= (1 << 0),
198 SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED
= (1 << 1)
202 SQTT_GPU_TYPE_UNKNOWN
= 0x0,
203 SQTT_GPU_TYPE_INTEGRATED
= 0x1,
204 SQTT_GPU_TYPE_DISCRETE
= 0x2,
205 SQTT_GPU_TYPE_VIRTUAL
= 0x3
208 enum sqtt_gfxip_level
{
209 SQTT_GFXIP_LEVEL_NONE
= 0x0,
210 SQTT_GFXIP_LEVEL_GFXIP_6
= 0x1,
211 SQTT_GFXIP_LEVEL_GFXIP_7
= 0x2,
212 SQTT_GFXIP_LEVEL_GFXIP_8
= 0x3,
213 SQTT_GFXIP_LEVEL_GFXIP_8_1
= 0x4,
214 SQTT_GFXIP_LEVEL_GFXIP_9
= 0x5,
215 SQTT_GFXIP_LEVEL_GFXIP_10_1
= 0x7,
218 enum sqtt_memory_type
{
219 SQTT_MEMORY_TYPE_UNKNOWN
= 0x0,
220 SQTT_MEMORY_TYPE_DDR
= 0x1,
221 SQTT_MEMORY_TYPE_DDR2
= 0x2,
222 SQTT_MEMORY_TYPE_DDR3
= 0x3,
223 SQTT_MEMORY_TYPE_DDR4
= 0x4,
224 SQTT_MEMORY_TYPE_GDDR3
= 0x10,
225 SQTT_MEMORY_TYPE_GDDR4
= 0x11,
226 SQTT_MEMORY_TYPE_GDDR5
= 0x12,
227 SQTT_MEMORY_TYPE_GDDR6
= 0x13,
228 SQTT_MEMORY_TYPE_HBM
= 0x20,
229 SQTT_MEMORY_TYPE_HBM2
= 0x21,
230 SQTT_MEMORY_TYPE_HBM3
= 0x22,
233 struct sqtt_file_chunk_asic_info
{
234 struct sqtt_file_chunk_header header
;
236 uint64_t trace_shader_core_clock
;
237 uint64_t trace_memory_clock
;
239 int32_t device_revision_id
;
240 int32_t vgprs_per_simd
;
241 int32_t sgprs_per_simd
;
242 int32_t shader_engines
;
243 int32_t compute_unit_per_shader_engine
;
244 int32_t simd_per_compute_unit
;
245 int32_t wavefronts_per_simd
;
246 int32_t minimum_vgpr_alloc
;
247 int32_t vgpr_alloc_granularity
;
248 int32_t minimum_sgpr_alloc
;
249 int32_t sgpr_alloc_granularity
;
250 int32_t hardware_contexts
;
251 enum sqtt_gpu_type gpu_type
;
252 enum sqtt_gfxip_level gfxip_level
;
255 int32_t gds_per_shader_engine
;
257 int32_t ce_ram_size_graphics
;
258 int32_t ce_ram_size_compute
;
259 int32_t max_number_of_dedicated_cus
;
261 int32_t vram_bus_width
;
262 int32_t l2_cache_size
;
263 int32_t l1_cache_size
;
265 char gpu_name
[SQTT_GPU_NAME_MAX_SIZE
];
267 float texture_per_clock
;
268 float prims_per_clock
;
269 float pixels_per_clock
;
270 uint64_t gpu_timestamp_frequency
;
271 uint64_t max_shader_core_clock
;
272 uint64_t max_memory_clock
;
273 uint32_t memory_ops_per_clock
;
274 enum sqtt_memory_type memory_chip_type
;
275 uint32_t lds_granularity
;
276 uint16_t cu_mask
[SQTT_MAX_NUM_SE
][SQTT_SA_PER_SE
];
281 static_assert(sizeof(struct sqtt_file_chunk_asic_info
) == 720,
282 "sqtt_file_chunk_asic_info doesn't match RGP spec");
284 static enum sqtt_gfxip_level
285 radv_chip_class_to_sqtt_gfxip_level(enum chip_class chip_class
)
287 switch (chip_class
) {
289 return SQTT_GFXIP_LEVEL_GFXIP_6
;
291 return SQTT_GFXIP_LEVEL_GFXIP_7
;
293 return SQTT_GFXIP_LEVEL_GFXIP_8
;
295 return SQTT_GFXIP_LEVEL_GFXIP_9
;
297 return SQTT_GFXIP_LEVEL_GFXIP_10_1
;
299 unreachable("Invalid chip class");
303 static enum sqtt_memory_type
304 radv_vram_type_to_sqtt_memory_type(uint32_t vram_type
)
307 case AMDGPU_VRAM_TYPE_UNKNOWN
:
308 return SQTT_MEMORY_TYPE_UNKNOWN
;
309 case AMDGPU_VRAM_TYPE_DDR2
:
310 return SQTT_MEMORY_TYPE_DDR2
;
311 case AMDGPU_VRAM_TYPE_DDR3
:
312 return SQTT_MEMORY_TYPE_DDR3
;
313 case AMDGPU_VRAM_TYPE_DDR4
:
314 return SQTT_MEMORY_TYPE_DDR4
;
315 case AMDGPU_VRAM_TYPE_GDDR5
:
316 return SQTT_MEMORY_TYPE_GDDR5
;
317 case AMDGPU_VRAM_TYPE_HBM
:
318 return SQTT_MEMORY_TYPE_HBM
;
319 case AMDGPU_VRAM_TYPE_GDDR6
:
320 return SQTT_MEMORY_TYPE_GDDR6
;
321 case AMDGPU_VRAM_TYPE_GDDR1
:
322 case AMDGPU_VRAM_TYPE_GDDR3
:
323 case AMDGPU_VRAM_TYPE_GDDR4
:
325 unreachable("Invalid vram type");
330 radv_fill_sqtt_asic_info(struct radv_device
*device
,
331 struct sqtt_file_chunk_asic_info
*chunk
)
333 struct radeon_info
*rad_info
= &device
->physical_device
->rad_info
;
335 chunk
->header
.chunk_id
.type
= SQTT_FILE_CHUNK_TYPE_ASIC_INFO
;
336 chunk
->header
.chunk_id
.index
= 0;
337 chunk
->header
.major_version
= 0;
338 chunk
->header
.minor_version
= 4;
339 chunk
->header
.size_in_bytes
= sizeof(*chunk
);
343 /* All chips older than GFX9 are affected by the "SPI not
344 * differentiating pkr_id for newwave commands" bug.
346 if (rad_info
->chip_class
< GFX9
)
347 chunk
->flags
|= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING
;
349 /* Only FIJI and GFX9+ support PS1 events. */
350 if (rad_info
->family
== CHIP_FIJI
|| rad_info
->chip_class
>= GFX9
)
351 chunk
->flags
|= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED
;
353 chunk
->trace_shader_core_clock
= rad_info
->max_shader_clock
* 1000000;
354 chunk
->trace_memory_clock
= rad_info
->max_memory_clock
* 1000000;
356 chunk
->device_id
= rad_info
->pci_id
;
357 chunk
->device_revision_id
= rad_info
->pci_rev_id
;
358 chunk
->vgprs_per_simd
= rad_info
->num_physical_wave64_vgprs_per_simd
;
359 chunk
->sgprs_per_simd
= rad_info
->num_physical_sgprs_per_simd
;
360 chunk
->shader_engines
= rad_info
->max_se
;
361 chunk
->compute_unit_per_shader_engine
= rad_info
->min_good_cu_per_sa
;
362 chunk
->simd_per_compute_unit
= rad_info
->num_simd_per_compute_unit
;
363 chunk
->wavefronts_per_simd
= rad_info
->max_wave64_per_simd
;
365 chunk
->minimum_vgpr_alloc
= rad_info
->min_wave64_vgpr_alloc
;
366 chunk
->vgpr_alloc_granularity
= rad_info
->wave64_vgpr_alloc_granularity
;
367 chunk
->minimum_sgpr_alloc
= rad_info
->min_sgpr_alloc
;
368 chunk
->sgpr_alloc_granularity
= rad_info
->sgpr_alloc_granularity
;
370 chunk
->hardware_contexts
= 8;
371 chunk
->gpu_type
= rad_info
->has_dedicated_vram
? SQTT_GPU_TYPE_DISCRETE
: SQTT_GPU_TYPE_INTEGRATED
;
372 chunk
->gfxip_level
= radv_chip_class_to_sqtt_gfxip_level(rad_info
->chip_class
);
373 chunk
->gpu_index
= 0;
375 chunk
->max_number_of_dedicated_cus
= 0;
376 chunk
->ce_ram_size
= rad_info
->ce_ram_size
;
377 chunk
->ce_ram_size_graphics
= 0;
378 chunk
->ce_ram_size_compute
= 0;
380 chunk
->vram_bus_width
= rad_info
->vram_bit_width
;
381 chunk
->vram_size
= rad_info
->vram_size
;
382 chunk
->l2_cache_size
= rad_info
->l2_cache_size
;
383 chunk
->l1_cache_size
= rad_info
->l1_cache_size
;
384 chunk
->lds_size
= rad_info
->lds_size_per_workgroup
;
386 strncpy(chunk
->gpu_name
, device
->physical_device
->name
, SQTT_GPU_NAME_MAX_SIZE
);
388 chunk
->alu_per_clock
= 0.0;
389 chunk
->texture_per_clock
= 0.0;
390 chunk
->prims_per_clock
= 0.0;
391 chunk
->pixels_per_clock
= 0.0;
393 chunk
->gpu_timestamp_frequency
= rad_info
->clock_crystal_freq
* 1000;
394 chunk
->max_shader_core_clock
= rad_info
->max_shader_clock
* 1000000;
395 chunk
->max_memory_clock
= rad_info
->max_memory_clock
* 1000000;
396 chunk
->memory_ops_per_clock
= 0;
397 chunk
->memory_chip_type
= radv_vram_type_to_sqtt_memory_type(rad_info
->vram_type
);
398 chunk
->lds_granularity
= rad_info
->lds_granularity
;
400 for (unsigned se
= 0; se
< 4; se
++) {
401 for (unsigned sa
= 0; sa
< 2; sa
++) {
402 chunk
->cu_mask
[se
][sa
] = rad_info
->cu_mask
[se
][sa
];
411 SQTT_API_TYPE_DIRECTX_12
,
412 SQTT_API_TYPE_VULKAN
,
413 SQTT_API_TYPE_GENERIC
,
417 enum sqtt_instruction_trace_mode
419 SQTT_INSTRUCTION_TRACE_DISABLED
= 0x0,
420 SQTT_INSTRUCTION_TRACE_FULL_FRAME
= 0x1,
421 SQTT_INSTRUCTION_TRACE_API_PSO
= 0x2,
424 enum sqtt_profiling_mode
{
425 SQTT_PROFILING_MODE_PRESENT
= 0x0,
426 SQTT_PROFILING_MODE_USER_MARKERS
= 0x1,
427 SQTT_PROFILING_MODE_INDEX
= 0x2,
428 SQTT_PROFILING_MODE_TAG
= 0x3,
431 union sqtt_profiling_mode_data
{
435 } user_marker_profiling_data
;
440 } index_profiling_data
;
447 } tag_profiling_data
;
450 union sqtt_instruction_trace_data
{
452 uint64_t api_pso_filter
;
461 struct sqtt_file_chunk_api_info
{
462 struct sqtt_file_chunk_header header
;
463 enum sqtt_api_type api_type
;
464 uint16_t major_version
;
465 uint16_t minor_version
;
466 enum sqtt_profiling_mode profiling_mode
;
468 union sqtt_profiling_mode_data profiling_mode_data
;
469 enum sqtt_instruction_trace_mode instruction_trace_mode
;
471 union sqtt_instruction_trace_data instruction_trace_data
;
474 static_assert(sizeof(struct sqtt_file_chunk_api_info
) == 1064,
475 "sqtt_file_chunk_api_info doesn't match RGP spec");
478 radv_sqtt_fill_api_info(struct sqtt_file_chunk_api_info
*chunk
)
480 chunk
->header
.chunk_id
.type
= SQTT_FILE_CHUNK_TYPE_API_INFO
;
481 chunk
->header
.chunk_id
.index
= 0;
482 chunk
->header
.major_version
= 0;
483 chunk
->header
.minor_version
= 1;
484 chunk
->header
.size_in_bytes
= sizeof(*chunk
);
486 chunk
->api_type
= SQTT_API_TYPE_VULKAN
;
487 chunk
->major_version
= 0;
488 chunk
->minor_version
= 0;
489 chunk
->profiling_mode
= SQTT_PROFILING_MODE_PRESENT
;
490 chunk
->instruction_trace_mode
= SQTT_INSTRUCTION_TRACE_DISABLED
;
496 struct sqtt_file_chunk_sqtt_desc
{
497 struct sqtt_file_chunk_header header
;
498 int32_t shader_engine_index
;
499 enum sqtt_version sqtt_version
;
502 int32_t instrumentation_version
;
505 int16_t instrumentation_spec_version
;
506 int16_t instrumentation_api_version
;
507 int32_t compute_unit_index
;
512 static_assert(sizeof(struct sqtt_file_chunk_sqtt_desc
) == 32,
513 "sqtt_file_chunk_sqtt_desc doesn't match RGP spec");
515 static enum sqtt_version
516 radv_chip_class_to_sqtt_version(enum chip_class chip_class
)
518 switch (chip_class
) {
520 return SQTT_VERSION_2_0
;
522 return SQTT_VERSION_2_1
;
524 return SQTT_VERSION_2_2
;
526 return SQTT_VERSION_2_3
;
528 return SQTT_VERSION_2_4
;
530 unreachable("Invalid chip class");
535 radv_sqtt_fill_sqtt_desc(struct radv_device
*device
,
536 struct sqtt_file_chunk_sqtt_desc
*chunk
,
538 int32_t shader_engine_index
,
539 int32_t compute_unit_index
)
541 chunk
->header
.chunk_id
.type
= SQTT_FILE_CHUNK_TYPE_SQTT_DESC
;
542 chunk
->header
.chunk_id
.index
= chunk_index
;
543 chunk
->header
.major_version
= 0;
544 chunk
->header
.minor_version
= 2;
545 chunk
->header
.size_in_bytes
= sizeof(*chunk
);
547 chunk
->sqtt_version
= radv_chip_class_to_sqtt_version(device
->physical_device
->rad_info
.chip_class
);
548 chunk
->shader_engine_index
= shader_engine_index
;
549 chunk
->v1
.instrumentation_spec_version
= 1;
550 chunk
->v1
.instrumentation_api_version
= 0;
551 chunk
->v1
.compute_unit_index
= compute_unit_index
;
557 struct sqtt_file_chunk_sqtt_data
{
558 struct sqtt_file_chunk_header header
;
559 int32_t offset
; /* in bytes */
560 int32_t size
; /* in bytes */
563 static_assert(sizeof(struct sqtt_file_chunk_sqtt_data
) == 24,
564 "sqtt_file_chunk_sqtt_data doesn't match RGP spec");
567 radv_sqtt_fill_sqtt_data(struct sqtt_file_chunk_sqtt_data
*chunk
,
568 int32_t chunk_index
, int32_t offset
, int32_t size
)
570 chunk
->header
.chunk_id
.type
= SQTT_FILE_CHUNK_TYPE_SQTT_DATA
;
571 chunk
->header
.chunk_id
.index
= chunk_index
;
572 chunk
->header
.major_version
= 0;
573 chunk
->header
.minor_version
= 0;
574 chunk
->header
.size_in_bytes
= sizeof(*chunk
) + size
;
576 chunk
->offset
= sizeof(*chunk
) + offset
;
581 radv_sqtt_dump_data(struct radv_device
*device
,
582 const struct radv_thread_trace
*thread_trace
,
585 struct sqtt_file_chunk_asic_info asic_info
= {};
586 struct sqtt_file_chunk_cpu_info cpu_info
= {};
587 struct sqtt_file_chunk_api_info api_info
= {};
588 struct sqtt_file_header header
= {};
589 size_t file_offset
= 0;
591 /* SQTT header file. */
592 radv_sqtt_fill_header(&header
);
593 file_offset
+= sizeof(header
);
594 fwrite(&header
, sizeof(header
), 1, output
);
596 /* SQTT cpu chunk. */
597 radv_sqtt_fill_cpu_info(&cpu_info
);
598 file_offset
+= sizeof(cpu_info
);
599 fwrite(&cpu_info
, sizeof(cpu_info
), 1, output
);
601 /* SQTT asic chunk. */
602 radv_fill_sqtt_asic_info(device
, &asic_info
);
603 file_offset
+= sizeof(asic_info
);
604 fwrite(&asic_info
, sizeof(asic_info
), 1, output
);
606 /* SQTT api chunk. */
607 radv_sqtt_fill_api_info(&api_info
);
608 file_offset
+= sizeof(api_info
);
609 fwrite(&api_info
, sizeof(api_info
), 1, output
);
612 for (unsigned i
= 0; i
< thread_trace
->num_traces
; i
++) {
613 const struct radv_thread_trace_se
*se
= &thread_trace
->traces
[i
];
614 const struct radv_thread_trace_info
*info
= &se
->info
;
615 struct sqtt_file_chunk_sqtt_desc desc
= {};
616 struct sqtt_file_chunk_sqtt_data data
= {};
617 uint64_t size
= info
->cur_offset
* 32; /* unit of 32 bytes */
619 /* SQTT desc chunk. */
620 radv_sqtt_fill_sqtt_desc(device
, &desc
, i
,
623 file_offset
+= sizeof(desc
);
624 fwrite(&desc
, sizeof(desc
), 1, output
);
626 /* SQTT data chunk. */
627 radv_sqtt_fill_sqtt_data(&data
, i
, file_offset
, size
);
628 file_offset
+= sizeof(data
);
629 fwrite(&data
, sizeof(data
), 1, output
);
631 /* Copy thread trace data generated by the hardware. */
633 fwrite(se
->data_ptr
, size
, 1, output
);
639 radv_dump_thread_trace(struct radv_device
*device
,
640 const struct radv_thread_trace
*thread_trace
)
648 now
= *localtime(&t
);
650 snprintf(filename
, sizeof(filename
), "/tmp/%s_%04d.%02d.%02d_%02d.%02d.rgp",
651 util_get_process_name(), 1900 + now
.tm_year
, now
.tm_mon
+ 1,
652 now
.tm_mday
, now
.tm_hour
, now
.tm_min
);
654 f
= fopen(filename
, "w+");
658 radv_sqtt_dump_data(device
, thread_trace
, f
);
660 fprintf(stderr
, "Thread trace capture saved to '%s'\n", filename
);