~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/amd/common/ac_rgp.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2020 Advanced Micro Devices, Inc.
3
 
 * Copyright © 2020 Valve Corporation
4
 
 *
5
 
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 
 * copy of this software and associated documentation files (the "Software"),
7
 
 * to deal in the Software without restriction, including without limitation
8
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 
 * and/or sell copies of the Software, and to permit persons to whom the
10
 
 * Software is furnished to do so, subject to the following conditions:
11
 
 *
12
 
 * The above copyright notice and this permission notice (including the next
13
 
 * paragraph) shall be included in all copies or substantial portions of the
14
 
 * Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 
 * IN THE SOFTWARE.
23
 
 */
24
 
#include "ac_rgp.h"
25
 
 
26
 
#include "util/macros.h"
27
 
#include "util/os_misc.h"
28
 
#include "util/os_time.h"
29
 
#include "util/u_process.h"
30
 
#include "util/u_math.h"
31
 
 
32
 
#include "ac_spm.h"
33
 
#include "ac_sqtt.h"
34
 
#include "ac_gpu_info.h"
35
 
#ifdef _WIN32
36
 
#define AMDGPU_VRAM_TYPE_UNKNOWN 0
37
 
#define AMDGPU_VRAM_TYPE_GDDR1 1
38
 
#define AMDGPU_VRAM_TYPE_DDR2  2
39
 
#define AMDGPU_VRAM_TYPE_GDDR3 3
40
 
#define AMDGPU_VRAM_TYPE_GDDR4 4
41
 
#define AMDGPU_VRAM_TYPE_GDDR5 5
42
 
#define AMDGPU_VRAM_TYPE_HBM   6
43
 
#define AMDGPU_VRAM_TYPE_DDR3  7
44
 
#define AMDGPU_VRAM_TYPE_DDR4  8
45
 
#define AMDGPU_VRAM_TYPE_GDDR6 9
46
 
#define AMDGPU_VRAM_TYPE_DDR5  10
47
 
#else
48
 
#include "drm-uapi/amdgpu_drm.h"
49
 
#endif
50
 
 
51
 
#include <stdbool.h>
52
 
#include <string.h>
53
 
 
54
 
#define SQTT_FILE_MAGIC_NUMBER  0x50303042
55
 
#define SQTT_FILE_VERSION_MAJOR 1
56
 
#define SQTT_FILE_VERSION_MINOR 5
57
 
 
58
 
#define SQTT_GPU_NAME_MAX_SIZE 256
59
 
#define SQTT_MAX_NUM_SE        32
60
 
#define SQTT_SA_PER_SE         2
61
 
 
62
 
enum sqtt_version
63
 
{
64
 
   SQTT_VERSION_NONE = 0x0,
65
 
   SQTT_VERSION_2_2 = 0x5, /* GFX8 */
66
 
   SQTT_VERSION_2_3 = 0x6, /* GFX9 */
67
 
   SQTT_VERSION_2_4 = 0x7  /* GFX10+ */
68
 
};
69
 
 
70
 
/**
71
 
 * SQTT chunks.
72
 
 */
73
 
enum sqtt_file_chunk_type
74
 
{
75
 
   SQTT_FILE_CHUNK_TYPE_ASIC_INFO,
76
 
   SQTT_FILE_CHUNK_TYPE_SQTT_DESC,
77
 
   SQTT_FILE_CHUNK_TYPE_SQTT_DATA,
78
 
   SQTT_FILE_CHUNK_TYPE_API_INFO,
79
 
   SQTT_FILE_CHUNK_TYPE_RESERVED,
80
 
   SQTT_FILE_CHUNK_TYPE_QUEUE_EVENT_TIMINGS,
81
 
   SQTT_FILE_CHUNK_TYPE_CLOCK_CALIBRATION,
82
 
   SQTT_FILE_CHUNK_TYPE_CPU_INFO,
83
 
   SQTT_FILE_CHUNK_TYPE_SPM_DB,
84
 
   SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_DATABASE,
85
 
   SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_LOADER_EVENTS,
86
 
   SQTT_FILE_CHUNK_TYPE_PSO_CORRELATION,
87
 
   SQTT_FILE_CHUNK_TYPE_INSTRUMENTATION_TABLE,
88
 
   SQTT_FILE_CHUNK_TYPE_COUNT
89
 
};
90
 
 
91
 
struct sqtt_file_chunk_id {
92
 
   enum sqtt_file_chunk_type type : 8;
93
 
   int32_t index : 8;
94
 
   int32_t reserved : 16;
95
 
};
96
 
 
97
 
struct sqtt_file_chunk_header {
98
 
   struct sqtt_file_chunk_id chunk_id;
99
 
   uint16_t minor_version;
100
 
   uint16_t major_version;
101
 
   int32_t size_in_bytes;
102
 
   int32_t padding;
103
 
};
104
 
 
105
 
/**
106
 
 * SQTT file header.
107
 
 */
108
 
struct sqtt_file_header_flags {
109
 
   union {
110
 
      struct {
111
 
         int32_t is_semaphore_queue_timing_etw : 1;
112
 
         int32_t no_queue_semaphore_timestamps : 1;
113
 
         int32_t reserved : 30;
114
 
      };
115
 
 
116
 
      uint32_t value;
117
 
   };
118
 
};
119
 
 
120
 
struct sqtt_file_header {
121
 
   uint32_t magic_number;
122
 
   uint32_t version_major;
123
 
   uint32_t version_minor;
124
 
   struct sqtt_file_header_flags flags;
125
 
   int32_t chunk_offset;
126
 
   int32_t second;
127
 
   int32_t minute;
128
 
   int32_t hour;
129
 
   int32_t day_in_month;
130
 
   int32_t month;
131
 
   int32_t year;
132
 
   int32_t day_in_week;
133
 
   int32_t day_in_year;
134
 
   int32_t is_daylight_savings;
135
 
};
136
 
 
137
 
static_assert(sizeof(struct sqtt_file_header) == 56, "sqtt_file_header doesn't match RGP spec");
138
 
 
139
 
static void ac_sqtt_fill_header(struct sqtt_file_header *header)
140
 
{
141
 
   struct tm *timep, result;
142
 
   time_t raw_time;
143
 
 
144
 
   header->magic_number = SQTT_FILE_MAGIC_NUMBER;
145
 
   header->version_major = SQTT_FILE_VERSION_MAJOR;
146
 
   header->version_minor = SQTT_FILE_VERSION_MINOR;
147
 
   header->flags.value = 0;
148
 
   header->flags.is_semaphore_queue_timing_etw = 1;
149
 
   header->flags.no_queue_semaphore_timestamps = 0;
150
 
   header->chunk_offset = sizeof(*header);
151
 
 
152
 
   time(&raw_time);
153
 
   timep = os_localtime(&raw_time, &result);
154
 
 
155
 
   header->second = timep->tm_sec;
156
 
   header->minute = timep->tm_min;
157
 
   header->hour = timep->tm_hour;
158
 
   header->day_in_month = timep->tm_mday;
159
 
   header->month = timep->tm_mon;
160
 
   header->year = timep->tm_year;
161
 
   header->day_in_week = timep->tm_wday;
162
 
   header->day_in_year = timep->tm_yday;
163
 
   header->is_daylight_savings = timep->tm_isdst;
164
 
}
165
 
 
166
 
/**
167
 
 * SQTT CPU info.
168
 
 */
169
 
struct sqtt_file_chunk_cpu_info {
170
 
   struct sqtt_file_chunk_header header;
171
 
   uint32_t vendor_id[4];
172
 
   uint32_t processor_brand[12];
173
 
   uint32_t reserved[2];
174
 
   uint64_t cpu_timestamp_freq;
175
 
   uint32_t clock_speed;
176
 
   uint32_t num_logical_cores;
177
 
   uint32_t num_physical_cores;
178
 
   uint32_t system_ram_size;
179
 
};
180
 
 
181
 
static_assert(sizeof(struct sqtt_file_chunk_cpu_info) == 112,
182
 
              "sqtt_file_chunk_cpu_info doesn't match RGP spec");
183
 
 
184
 
static void ac_sqtt_fill_cpu_info(struct sqtt_file_chunk_cpu_info *chunk)
185
 
{
186
 
   uint32_t cpu_clock_speed_total = 0;
187
 
   uint64_t system_ram_size = 0;
188
 
   char line[1024];
189
 
   FILE *f;
190
 
 
191
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CPU_INFO;
192
 
   chunk->header.chunk_id.index = 0;
193
 
   chunk->header.major_version = 0;
194
 
   chunk->header.minor_version = 0;
195
 
   chunk->header.size_in_bytes = sizeof(*chunk);
196
 
 
197
 
   chunk->cpu_timestamp_freq = 1000000000; /* tick set to 1ns */
198
 
 
199
 
   strncpy((char *)chunk->vendor_id, "Unknown", sizeof(chunk->vendor_id));
200
 
   strncpy((char *)chunk->processor_brand, "Unknown", sizeof(chunk->processor_brand));
201
 
   chunk->clock_speed = 0;
202
 
   chunk->num_logical_cores = 0;
203
 
   chunk->num_physical_cores = 0;
204
 
   chunk->system_ram_size = 0;
205
 
   if (os_get_total_physical_memory(&system_ram_size))
206
 
      chunk->system_ram_size = system_ram_size / (1024 * 1024);
207
 
 
208
 
   /* Parse cpuinfo to get more detailled information. */
209
 
   f = fopen("/proc/cpuinfo", "r");
210
 
   if (!f)
211
 
      return;
212
 
 
213
 
   while (fgets(line, sizeof(line), f)) {
214
 
      char *str;
215
 
 
216
 
      /* Parse vendor name. */
217
 
      str = strstr(line, "vendor_id");
218
 
      if (str) {
219
 
         char *ptr = (char *)chunk->vendor_id;
220
 
         char *v = strtok(str, ":");
221
 
         v = strtok(NULL, ":");
222
 
         strncpy(ptr, v + 1, sizeof(chunk->vendor_id) - 1);
223
 
         ptr[sizeof(chunk->vendor_id) - 1] = '\0';
224
 
      }
225
 
 
226
 
      /* Parse processor name. */
227
 
      str = strstr(line, "model name");
228
 
      if (str) {
229
 
         char *ptr = (char *)chunk->processor_brand;
230
 
         char *v = strtok(str, ":");
231
 
         v = strtok(NULL, ":");
232
 
         strncpy(ptr, v + 1, sizeof(chunk->processor_brand) - 1);
233
 
         ptr[sizeof(chunk->processor_brand) - 1] = '\0';
234
 
      }
235
 
 
236
 
      /* Parse the current CPU clock speed for each cores. */
237
 
      str = strstr(line, "cpu MHz");
238
 
      if (str) {
239
 
         uint32_t v = 0;
240
 
         if (sscanf(str, "cpu MHz : %d", &v) == 1)
241
 
            cpu_clock_speed_total += v;
242
 
      }
243
 
 
244
 
      /* Parse the number of logical cores. */
245
 
      str = strstr(line, "siblings");
246
 
      if (str) {
247
 
         uint32_t v = 0;
248
 
         if (sscanf(str, "siblings : %d", &v) == 1)
249
 
            chunk->num_logical_cores = v;
250
 
      }
251
 
 
252
 
      /* Parse the number of physical cores. */
253
 
      str = strstr(line, "cpu cores");
254
 
      if (str) {
255
 
         uint32_t v = 0;
256
 
         if (sscanf(str, "cpu cores : %d", &v) == 1)
257
 
            chunk->num_physical_cores = v;
258
 
      }
259
 
   }
260
 
 
261
 
   if (chunk->num_logical_cores)
262
 
      chunk->clock_speed = cpu_clock_speed_total / chunk->num_logical_cores;
263
 
 
264
 
   fclose(f);
265
 
}
266
 
 
267
 
/**
268
 
 * SQTT ASIC info.
269
 
 */
270
 
enum sqtt_file_chunk_asic_info_flags
271
 
{
272
 
   SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING = (1 << 0),
273
 
   SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED = (1 << 1)
274
 
};
275
 
 
276
 
enum sqtt_gpu_type
277
 
{
278
 
   SQTT_GPU_TYPE_UNKNOWN = 0x0,
279
 
   SQTT_GPU_TYPE_INTEGRATED = 0x1,
280
 
   SQTT_GPU_TYPE_DISCRETE = 0x2,
281
 
   SQTT_GPU_TYPE_VIRTUAL = 0x3
282
 
};
283
 
 
284
 
enum sqtt_gfxip_level
285
 
{
286
 
   SQTT_GFXIP_LEVEL_NONE = 0x0,
287
 
   SQTT_GFXIP_LEVEL_GFXIP_6 = 0x1,
288
 
   SQTT_GFXIP_LEVEL_GFXIP_7 = 0x2,
289
 
   SQTT_GFXIP_LEVEL_GFXIP_8 = 0x3,
290
 
   SQTT_GFXIP_LEVEL_GFXIP_8_1 = 0x4,
291
 
   SQTT_GFXIP_LEVEL_GFXIP_9 = 0x5,
292
 
   SQTT_GFXIP_LEVEL_GFXIP_10_1 = 0x7,
293
 
   SQTT_GFXIP_LEVEL_GFXIP_10_3 = 0x9,
294
 
};
295
 
 
296
 
enum sqtt_memory_type
297
 
{
298
 
   SQTT_MEMORY_TYPE_UNKNOWN = 0x0,
299
 
   SQTT_MEMORY_TYPE_DDR = 0x1,
300
 
   SQTT_MEMORY_TYPE_DDR2 = 0x2,
301
 
   SQTT_MEMORY_TYPE_DDR3 = 0x3,
302
 
   SQTT_MEMORY_TYPE_DDR4 = 0x4,
303
 
   SQTT_MEMORY_TYPE_GDDR3 = 0x10,
304
 
   SQTT_MEMORY_TYPE_GDDR4 = 0x11,
305
 
   SQTT_MEMORY_TYPE_GDDR5 = 0x12,
306
 
   SQTT_MEMORY_TYPE_GDDR6 = 0x13,
307
 
   SQTT_MEMORY_TYPE_HBM = 0x20,
308
 
   SQTT_MEMORY_TYPE_HBM2 = 0x21,
309
 
   SQTT_MEMORY_TYPE_HBM3 = 0x22,
310
 
   SQTT_MEMORY_TYPE_LPDDR4 = 0x30,
311
 
   SQTT_MEMORY_TYPE_LPDDR5 = 0x31,
312
 
};
313
 
 
314
 
struct sqtt_file_chunk_asic_info {
315
 
   struct sqtt_file_chunk_header header;
316
 
   uint64_t flags;
317
 
   uint64_t trace_shader_core_clock;
318
 
   uint64_t trace_memory_clock;
319
 
   int32_t device_id;
320
 
   int32_t device_revision_id;
321
 
   int32_t vgprs_per_simd;
322
 
   int32_t sgprs_per_simd;
323
 
   int32_t shader_engines;
324
 
   int32_t compute_unit_per_shader_engine;
325
 
   int32_t simd_per_compute_unit;
326
 
   int32_t wavefronts_per_simd;
327
 
   int32_t minimum_vgpr_alloc;
328
 
   int32_t vgpr_alloc_granularity;
329
 
   int32_t minimum_sgpr_alloc;
330
 
   int32_t sgpr_alloc_granularity;
331
 
   int32_t hardware_contexts;
332
 
   enum sqtt_gpu_type gpu_type;
333
 
   enum sqtt_gfxip_level gfxip_level;
334
 
   int32_t gpu_index;
335
 
   int32_t gds_size;
336
 
   int32_t gds_per_shader_engine;
337
 
   int32_t ce_ram_size;
338
 
   int32_t ce_ram_size_graphics;
339
 
   int32_t ce_ram_size_compute;
340
 
   int32_t max_number_of_dedicated_cus;
341
 
   int64_t vram_size;
342
 
   int32_t vram_bus_width;
343
 
   int32_t l2_cache_size;
344
 
   int32_t l1_cache_size;
345
 
   int32_t lds_size;
346
 
   char gpu_name[SQTT_GPU_NAME_MAX_SIZE];
347
 
   float alu_per_clock;
348
 
   float texture_per_clock;
349
 
   float prims_per_clock;
350
 
   float pixels_per_clock;
351
 
   uint64_t gpu_timestamp_frequency;
352
 
   uint64_t max_shader_core_clock;
353
 
   uint64_t max_memory_clock;
354
 
   uint32_t memory_ops_per_clock;
355
 
   enum sqtt_memory_type memory_chip_type;
356
 
   uint32_t lds_granularity;
357
 
   uint16_t cu_mask[SQTT_MAX_NUM_SE][SQTT_SA_PER_SE];
358
 
   char reserved1[128];
359
 
   char padding[4];
360
 
};
361
 
 
362
 
static_assert(sizeof(struct sqtt_file_chunk_asic_info) == 720,
363
 
              "sqtt_file_chunk_asic_info doesn't match RGP spec");
364
 
 
365
 
static enum sqtt_gfxip_level ac_chip_class_to_sqtt_gfxip_level(enum chip_class chip_class)
366
 
{
367
 
   switch (chip_class) {
368
 
   case GFX8:
369
 
      return SQTT_GFXIP_LEVEL_GFXIP_8;
370
 
   case GFX9:
371
 
      return SQTT_GFXIP_LEVEL_GFXIP_9;
372
 
   case GFX10:
373
 
      return SQTT_GFXIP_LEVEL_GFXIP_10_1;
374
 
   case GFX10_3:
375
 
      return SQTT_GFXIP_LEVEL_GFXIP_10_3;
376
 
   default:
377
 
      unreachable("Invalid chip class");
378
 
   }
379
 
}
380
 
 
381
 
static enum sqtt_memory_type ac_vram_type_to_sqtt_memory_type(uint32_t vram_type)
382
 
{
383
 
   switch (vram_type) {
384
 
   case AMDGPU_VRAM_TYPE_UNKNOWN:
385
 
      return SQTT_MEMORY_TYPE_UNKNOWN;
386
 
   case AMDGPU_VRAM_TYPE_DDR2:
387
 
      return SQTT_MEMORY_TYPE_DDR2;
388
 
   case AMDGPU_VRAM_TYPE_DDR3:
389
 
      return SQTT_MEMORY_TYPE_DDR3;
390
 
   case AMDGPU_VRAM_TYPE_DDR4:
391
 
      return SQTT_MEMORY_TYPE_DDR4;
392
 
   case AMDGPU_VRAM_TYPE_GDDR5:
393
 
      return SQTT_MEMORY_TYPE_GDDR5;
394
 
   case AMDGPU_VRAM_TYPE_HBM:
395
 
      return SQTT_MEMORY_TYPE_HBM;
396
 
   case AMDGPU_VRAM_TYPE_GDDR6:
397
 
      return SQTT_MEMORY_TYPE_GDDR6;
398
 
   case AMDGPU_VRAM_TYPE_DDR5:
399
 
      return SQTT_MEMORY_TYPE_LPDDR5;
400
 
   case AMDGPU_VRAM_TYPE_GDDR1:
401
 
   case AMDGPU_VRAM_TYPE_GDDR3:
402
 
   case AMDGPU_VRAM_TYPE_GDDR4:
403
 
   default:
404
 
      unreachable("Invalid vram type");
405
 
   }
406
 
}
407
 
 
408
 
static uint32_t ac_memory_ops_per_clock(uint32_t vram_type)
409
 
{
410
 
   switch (vram_type) {
411
 
   case AMDGPU_VRAM_TYPE_UNKNOWN:
412
 
      return 0;
413
 
   case AMDGPU_VRAM_TYPE_DDR2:
414
 
   case AMDGPU_VRAM_TYPE_DDR3:
415
 
   case AMDGPU_VRAM_TYPE_DDR4:
416
 
   case AMDGPU_VRAM_TYPE_HBM:
417
 
      return 2;
418
 
   case AMDGPU_VRAM_TYPE_DDR5:
419
 
   case AMDGPU_VRAM_TYPE_GDDR5:
420
 
      return 4;
421
 
   case AMDGPU_VRAM_TYPE_GDDR6:
422
 
      return 16;
423
 
   case AMDGPU_VRAM_TYPE_GDDR1:
424
 
   case AMDGPU_VRAM_TYPE_GDDR3:
425
 
   case AMDGPU_VRAM_TYPE_GDDR4:
426
 
   default:
427
 
      unreachable("Invalid vram type");
428
 
   }
429
 
}
430
 
 
431
 
static void ac_sqtt_fill_asic_info(struct radeon_info *rad_info,
432
 
                                   struct sqtt_file_chunk_asic_info *chunk)
433
 
{
434
 
   bool has_wave32 = rad_info->chip_class >= GFX10;
435
 
 
436
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_ASIC_INFO;
437
 
   chunk->header.chunk_id.index = 0;
438
 
   chunk->header.major_version = 0;
439
 
   chunk->header.minor_version = 4;
440
 
   chunk->header.size_in_bytes = sizeof(*chunk);
441
 
 
442
 
   chunk->flags = 0;
443
 
 
444
 
   /* All chips older than GFX9 are affected by the "SPI not
445
 
    * differentiating pkr_id for newwave commands" bug.
446
 
    */
447
 
   if (rad_info->chip_class < GFX9)
448
 
      chunk->flags |= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING;
449
 
 
450
 
   /* Only GFX9+ support PS1 events. */
451
 
   if (rad_info->chip_class >= GFX9)
452
 
      chunk->flags |= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED;
453
 
 
454
 
   chunk->trace_shader_core_clock = rad_info->max_shader_clock * 1000000;
455
 
   chunk->trace_memory_clock = rad_info->max_memory_clock * 1000000;
456
 
 
457
 
   /* RGP gets very confused if these clocks are 0. The numbers here are for profile_peak on
458
 
    * VGH since that is the chips where we've seen the need for this workaround. */
459
 
   if (!chunk->trace_shader_core_clock)
460
 
      chunk->trace_shader_core_clock = 1300000000;
461
 
   if (!chunk->trace_memory_clock)
462
 
      chunk->trace_memory_clock = 687000000;
463
 
 
464
 
   chunk->device_id = rad_info->pci_id;
465
 
   chunk->device_revision_id = rad_info->pci_rev_id;
466
 
   chunk->vgprs_per_simd = rad_info->num_physical_wave64_vgprs_per_simd * (has_wave32 ? 2 : 1);
467
 
   chunk->sgprs_per_simd = rad_info->num_physical_sgprs_per_simd;
468
 
   chunk->shader_engines = rad_info->max_se;
469
 
   chunk->compute_unit_per_shader_engine = rad_info->min_good_cu_per_sa * rad_info->max_sa_per_se;
470
 
   chunk->simd_per_compute_unit = rad_info->num_simd_per_compute_unit;
471
 
   chunk->wavefronts_per_simd = rad_info->max_wave64_per_simd;
472
 
 
473
 
   chunk->minimum_vgpr_alloc = rad_info->min_wave64_vgpr_alloc;
474
 
   chunk->vgpr_alloc_granularity = rad_info->wave64_vgpr_alloc_granularity * (has_wave32 ? 2 : 1);
475
 
   chunk->minimum_sgpr_alloc = rad_info->min_sgpr_alloc;
476
 
   chunk->sgpr_alloc_granularity = rad_info->sgpr_alloc_granularity;
477
 
 
478
 
   chunk->hardware_contexts = 8;
479
 
   chunk->gpu_type =
480
 
      rad_info->has_dedicated_vram ? SQTT_GPU_TYPE_DISCRETE : SQTT_GPU_TYPE_INTEGRATED;
481
 
   chunk->gfxip_level = ac_chip_class_to_sqtt_gfxip_level(rad_info->chip_class);
482
 
   chunk->gpu_index = 0;
483
 
 
484
 
   chunk->max_number_of_dedicated_cus = 0;
485
 
   chunk->ce_ram_size = rad_info->ce_ram_size;
486
 
   chunk->ce_ram_size_graphics = 0;
487
 
   chunk->ce_ram_size_compute = 0;
488
 
 
489
 
   chunk->vram_bus_width = rad_info->vram_bit_width;
490
 
   chunk->vram_size = rad_info->vram_size;
491
 
   chunk->l2_cache_size = rad_info->l2_cache_size;
492
 
   chunk->l1_cache_size = rad_info->l1_cache_size;
493
 
   chunk->lds_size = rad_info->lds_size_per_workgroup;
494
 
   if (rad_info->chip_class >= GFX10) {
495
 
      /* RGP expects the LDS size in CU mode. */
496
 
      chunk->lds_size /= 2;
497
 
   }
498
 
 
499
 
   strncpy(chunk->gpu_name, rad_info->name, SQTT_GPU_NAME_MAX_SIZE - 1);
500
 
 
501
 
   chunk->alu_per_clock = 0.0;
502
 
   chunk->texture_per_clock = 0.0;
503
 
   chunk->prims_per_clock = rad_info->max_se;
504
 
   if (rad_info->chip_class == GFX10)
505
 
      chunk->prims_per_clock *= 2;
506
 
   chunk->pixels_per_clock = 0.0;
507
 
 
508
 
   chunk->gpu_timestamp_frequency = rad_info->clock_crystal_freq * 1000;
509
 
   chunk->max_shader_core_clock = rad_info->max_shader_clock * 1000000;
510
 
   chunk->max_memory_clock = rad_info->max_memory_clock * 1000000;
511
 
   chunk->memory_ops_per_clock = ac_memory_ops_per_clock(rad_info->vram_type);
512
 
   chunk->memory_chip_type = ac_vram_type_to_sqtt_memory_type(rad_info->vram_type);
513
 
   chunk->lds_granularity = rad_info->lds_encode_granularity;
514
 
 
515
 
   for (unsigned se = 0; se < AMD_MAX_SE; se++) {
516
 
      for (unsigned sa = 0; sa < AMD_MAX_SA_PER_SE; sa++) {
517
 
         chunk->cu_mask[se][sa] = rad_info->cu_mask[se][sa];
518
 
      }
519
 
   }
520
 
}
521
 
 
522
 
/**
523
 
 * SQTT API info.
524
 
 */
525
 
enum sqtt_api_type
526
 
{
527
 
   SQTT_API_TYPE_DIRECTX_12,
528
 
   SQTT_API_TYPE_VULKAN,
529
 
   SQTT_API_TYPE_GENERIC,
530
 
   SQTT_API_TYPE_OPENCL
531
 
};
532
 
 
533
 
enum sqtt_instruction_trace_mode
534
 
{
535
 
   SQTT_INSTRUCTION_TRACE_DISABLED = 0x0,
536
 
   SQTT_INSTRUCTION_TRACE_FULL_FRAME = 0x1,
537
 
   SQTT_INSTRUCTION_TRACE_API_PSO = 0x2,
538
 
};
539
 
 
540
 
enum sqtt_profiling_mode
541
 
{
542
 
   SQTT_PROFILING_MODE_PRESENT = 0x0,
543
 
   SQTT_PROFILING_MODE_USER_MARKERS = 0x1,
544
 
   SQTT_PROFILING_MODE_INDEX = 0x2,
545
 
   SQTT_PROFILING_MODE_TAG = 0x3,
546
 
};
547
 
 
548
 
union sqtt_profiling_mode_data {
549
 
   struct {
550
 
      char start[256];
551
 
      char end[256];
552
 
   } user_marker_profiling_data;
553
 
 
554
 
   struct {
555
 
      uint32_t start;
556
 
      uint32_t end;
557
 
   } index_profiling_data;
558
 
 
559
 
   struct {
560
 
      uint32_t begin_hi;
561
 
      uint32_t begin_lo;
562
 
      uint32_t end_hi;
563
 
      uint32_t end_lo;
564
 
   } tag_profiling_data;
565
 
};
566
 
 
567
 
union sqtt_instruction_trace_data {
568
 
   struct {
569
 
      uint64_t api_pso_filter;
570
 
   } api_pso_data;
571
 
 
572
 
   struct {
573
 
      char start[256];
574
 
      char end[256];
575
 
   } user_marker_data;
576
 
};
577
 
 
578
 
struct sqtt_file_chunk_api_info {
579
 
   struct sqtt_file_chunk_header header;
580
 
   enum sqtt_api_type api_type;
581
 
   uint16_t major_version;
582
 
   uint16_t minor_version;
583
 
   enum sqtt_profiling_mode profiling_mode;
584
 
   uint32_t reserved;
585
 
   union sqtt_profiling_mode_data profiling_mode_data;
586
 
   enum sqtt_instruction_trace_mode instruction_trace_mode;
587
 
   uint32_t reserved2;
588
 
   union sqtt_instruction_trace_data instruction_trace_data;
589
 
};
590
 
 
591
 
static_assert(sizeof(struct sqtt_file_chunk_api_info) == 1064,
592
 
              "sqtt_file_chunk_api_info doesn't match RGP spec");
593
 
 
594
 
static void ac_sqtt_fill_api_info(struct sqtt_file_chunk_api_info *chunk)
595
 
{
596
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_API_INFO;
597
 
   chunk->header.chunk_id.index = 0;
598
 
   chunk->header.major_version = 0;
599
 
   chunk->header.minor_version = 1;
600
 
   chunk->header.size_in_bytes = sizeof(*chunk);
601
 
 
602
 
   chunk->api_type = SQTT_API_TYPE_VULKAN;
603
 
   chunk->major_version = 0;
604
 
   chunk->minor_version = 0;
605
 
   chunk->profiling_mode = SQTT_PROFILING_MODE_PRESENT;
606
 
   chunk->instruction_trace_mode = SQTT_INSTRUCTION_TRACE_DISABLED;
607
 
}
608
 
 
609
 
struct sqtt_code_object_database_record {
610
 
   uint32_t size;
611
 
};
612
 
 
613
 
struct sqtt_file_chunk_code_object_database {
614
 
   struct sqtt_file_chunk_header header;
615
 
   uint32_t offset;
616
 
   uint32_t flags;
617
 
   uint32_t size;
618
 
   uint32_t record_count;
619
 
};
620
 
 
621
 
static void
622
 
ac_sqtt_fill_code_object(struct rgp_code_object *rgp_code_object,
623
 
                         struct sqtt_file_chunk_code_object_database *chunk,
624
 
                         size_t file_offset, uint32_t chunk_size)
625
 
{
626
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_DATABASE;
627
 
   chunk->header.chunk_id.index = 0;
628
 
   chunk->header.major_version = 0;
629
 
   chunk->header.minor_version = 0;
630
 
   chunk->header.size_in_bytes = chunk_size;
631
 
   chunk->offset = file_offset;
632
 
   chunk->flags = 0;
633
 
   chunk->size = chunk_size;
634
 
   chunk->record_count = rgp_code_object->record_count;
635
 
}
636
 
 
637
 
struct sqtt_code_object_loader_events_record {
638
 
   uint32_t loader_event_type;
639
 
   uint32_t reserved;
640
 
   uint64_t base_address;
641
 
   uint64_t code_object_hash[2];
642
 
   uint64_t time_stamp;
643
 
};
644
 
 
645
 
struct sqtt_file_chunk_code_object_loader_events {
646
 
   struct sqtt_file_chunk_header header;
647
 
   uint32_t offset;
648
 
   uint32_t flags;
649
 
   uint32_t record_size;
650
 
   uint32_t record_count;
651
 
};
652
 
 
653
 
static void
654
 
ac_sqtt_fill_loader_events(struct rgp_loader_events *rgp_loader_events,
655
 
                           struct sqtt_file_chunk_code_object_loader_events *chunk,
656
 
                           size_t file_offset)
657
 
{
658
 
   chunk->header.chunk_id.type =
659
 
                               SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_LOADER_EVENTS;
660
 
   chunk->header.chunk_id.index = 0;
661
 
   chunk->header.major_version = 1;
662
 
   chunk->header.minor_version = 0;
663
 
   chunk->header.size_in_bytes = (rgp_loader_events->record_count *
664
 
                                 sizeof(struct sqtt_code_object_loader_events_record)) +
665
 
                                 sizeof(*chunk);
666
 
   chunk->offset = file_offset;
667
 
   chunk->flags = 0;
668
 
   chunk->record_size = sizeof(struct sqtt_code_object_loader_events_record);
669
 
   chunk->record_count = rgp_loader_events->record_count;
670
 
}
671
 
struct sqtt_pso_correlation_record {
672
 
   uint64_t api_pso_hash;
673
 
   uint64_t pipeline_hash[2];
674
 
   char api_level_obj_name[64];
675
 
};
676
 
 
677
 
struct sqtt_file_chunk_pso_correlation {
678
 
   struct sqtt_file_chunk_header header;
679
 
   uint32_t offset;
680
 
   uint32_t flags;
681
 
   uint32_t record_size;
682
 
   uint32_t record_count;
683
 
};
684
 
 
685
 
static void
686
 
ac_sqtt_fill_pso_correlation(struct rgp_pso_correlation *rgp_pso_correlation,
687
 
                             struct sqtt_file_chunk_pso_correlation *chunk,
688
 
                             size_t file_offset)
689
 
{
690
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_PSO_CORRELATION;
691
 
   chunk->header.chunk_id.index = 0;
692
 
   chunk->header.major_version = 0;
693
 
   chunk->header.minor_version = 0;
694
 
   chunk->header.size_in_bytes = (rgp_pso_correlation->record_count *
695
 
                                 sizeof(struct sqtt_pso_correlation_record)) +
696
 
                                 sizeof(*chunk);
697
 
   chunk->offset = file_offset;
698
 
   chunk->flags = 0;
699
 
   chunk->record_size = sizeof(struct sqtt_pso_correlation_record);
700
 
   chunk->record_count = rgp_pso_correlation->record_count;
701
 
}
702
 
 
703
 
/**
704
 
 * SQTT desc info.
705
 
 */
706
 
struct sqtt_file_chunk_sqtt_desc {
707
 
   struct sqtt_file_chunk_header header;
708
 
   int32_t shader_engine_index;
709
 
   enum sqtt_version sqtt_version;
710
 
   union {
711
 
      struct {
712
 
         int32_t instrumentation_version;
713
 
      } v0;
714
 
      struct {
715
 
         int16_t instrumentation_spec_version;
716
 
         int16_t instrumentation_api_version;
717
 
         int32_t compute_unit_index;
718
 
      } v1;
719
 
   };
720
 
};
721
 
 
722
 
static_assert(sizeof(struct sqtt_file_chunk_sqtt_desc) == 32,
723
 
              "sqtt_file_chunk_sqtt_desc doesn't match RGP spec");
724
 
 
725
 
static enum sqtt_version ac_chip_class_to_sqtt_version(enum chip_class chip_class)
726
 
{
727
 
   switch (chip_class) {
728
 
   case GFX8:
729
 
      return SQTT_VERSION_2_2;
730
 
   case GFX9:
731
 
      return SQTT_VERSION_2_3;
732
 
   case GFX10:
733
 
      return SQTT_VERSION_2_4;
734
 
   case GFX10_3:
735
 
      return SQTT_VERSION_2_4;
736
 
   default:
737
 
      unreachable("Invalid chip class");
738
 
   }
739
 
}
740
 
 
741
 
static void ac_sqtt_fill_sqtt_desc(struct radeon_info *info,
742
 
                                   struct sqtt_file_chunk_sqtt_desc *chunk, int32_t chunk_index,
743
 
                                   int32_t shader_engine_index, int32_t compute_unit_index)
744
 
{
745
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SQTT_DESC;
746
 
   chunk->header.chunk_id.index = chunk_index;
747
 
   chunk->header.major_version = 0;
748
 
   chunk->header.minor_version = 2;
749
 
   chunk->header.size_in_bytes = sizeof(*chunk);
750
 
 
751
 
   chunk->sqtt_version =
752
 
      ac_chip_class_to_sqtt_version(info->chip_class);
753
 
   chunk->shader_engine_index = shader_engine_index;
754
 
   chunk->v1.instrumentation_spec_version = 1;
755
 
   chunk->v1.instrumentation_api_version = 0;
756
 
   chunk->v1.compute_unit_index = compute_unit_index;
757
 
}
758
 
 
759
 
/**
760
 
 * SQTT data info.
761
 
 */
762
 
struct sqtt_file_chunk_sqtt_data {
763
 
   struct sqtt_file_chunk_header header;
764
 
   int32_t offset; /* in bytes */
765
 
   int32_t size;   /* in bytes */
766
 
};
767
 
 
768
 
static_assert(sizeof(struct sqtt_file_chunk_sqtt_data) == 24,
769
 
              "sqtt_file_chunk_sqtt_data doesn't match RGP spec");
770
 
 
771
 
static void ac_sqtt_fill_sqtt_data(struct sqtt_file_chunk_sqtt_data *chunk, int32_t chunk_index,
772
 
                                   int32_t offset, int32_t size)
773
 
{
774
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SQTT_DATA;
775
 
   chunk->header.chunk_id.index = chunk_index;
776
 
   chunk->header.major_version = 0;
777
 
   chunk->header.minor_version = 0;
778
 
   chunk->header.size_in_bytes = sizeof(*chunk) + size;
779
 
 
780
 
   chunk->offset = sizeof(*chunk) + offset;
781
 
   chunk->size = size;
782
 
}
783
 
 
784
 
/**
785
 
 * SQTT queue event timings info.
786
 
 */
787
 
struct sqtt_file_chunk_queue_event_timings {
788
 
   struct sqtt_file_chunk_header header;
789
 
   uint32_t queue_info_table_record_count;
790
 
   uint32_t queue_info_table_size;
791
 
   uint32_t queue_event_table_record_count;
792
 
   uint32_t queue_event_table_size;
793
 
};
794
 
 
795
 
static_assert(sizeof(struct sqtt_file_chunk_queue_event_timings) == 32,
796
 
              "sqtt_file_chunk_queue_event_timings doesn't match RGP spec");
797
 
 
798
 
struct sqtt_queue_info_record {
799
 
   uint64_t queue_id;
800
 
   uint64_t queue_context;
801
 
   struct sqtt_queue_hardware_info hardware_info;
802
 
   uint32_t reserved;
803
 
};
804
 
 
805
 
static_assert(sizeof(struct sqtt_queue_info_record) == 24,
806
 
              "sqtt_queue_info_record doesn't match RGP spec");
807
 
 
808
 
struct sqtt_queue_event_record {
809
 
   enum sqtt_queue_event_type event_type;
810
 
   uint32_t sqtt_cb_id;
811
 
   uint64_t frame_index;
812
 
   uint32_t queue_info_index;
813
 
   uint32_t submit_sub_index;
814
 
   uint64_t api_id;
815
 
   uint64_t cpu_timestamp;
816
 
   uint64_t gpu_timestamps[2];
817
 
};
818
 
 
819
 
static_assert(sizeof(struct sqtt_queue_event_record) == 56,
820
 
              "sqtt_queue_event_record doesn't match RGP spec");
821
 
 
822
 
static void
823
 
ac_sqtt_fill_queue_event_timings(struct rgp_queue_info *rgp_queue_info,
824
 
                                 struct rgp_queue_event *rgp_queue_event,
825
 
                                 struct sqtt_file_chunk_queue_event_timings *chunk)
826
 
{
827
 
   unsigned queue_info_size =
828
 
      rgp_queue_info->record_count * sizeof(struct sqtt_queue_info_record);
829
 
   unsigned queue_event_size =
830
 
      rgp_queue_event->record_count * sizeof(struct sqtt_queue_event_record);
831
 
 
832
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_QUEUE_EVENT_TIMINGS;
833
 
   chunk->header.chunk_id.index = 0;
834
 
   chunk->header.major_version = 1;
835
 
   chunk->header.minor_version = 1;
836
 
   chunk->header.size_in_bytes = queue_info_size + queue_event_size +
837
 
                                 sizeof(*chunk);
838
 
 
839
 
   chunk->queue_info_table_record_count = rgp_queue_info->record_count;
840
 
   chunk->queue_info_table_size = queue_info_size;
841
 
   chunk->queue_event_table_record_count = rgp_queue_event->record_count;
842
 
   chunk->queue_event_table_size = queue_event_size;
843
 
}
844
 
 
845
 
/**
846
 
 * SQTT clock calibration info.
847
 
 */
848
 
struct sqtt_file_chunk_clock_calibration {
849
 
   struct sqtt_file_chunk_header header;
850
 
   uint64_t cpu_timestamp;
851
 
   uint64_t gpu_timestamp;
852
 
   uint64_t reserved;
853
 
};
854
 
 
855
 
static_assert(sizeof(struct sqtt_file_chunk_clock_calibration) == 40,
856
 
              "sqtt_file_chunk_clock_calibration doesn't match RGP spec");
857
 
 
858
 
static void
859
 
ac_sqtt_fill_clock_calibration(struct sqtt_file_chunk_clock_calibration *chunk,
860
 
                               int32_t chunk_index)
861
 
{
862
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CLOCK_CALIBRATION;
863
 
   chunk->header.chunk_id.index = chunk_index;
864
 
   chunk->header.major_version = 0;
865
 
   chunk->header.minor_version = 0;
866
 
   chunk->header.size_in_bytes = sizeof(*chunk);
867
 
}
868
 
 
869
 
/* Below values are from from llvm project
870
 
 * llvm/include/llvm/BinaryFormat/ELF.h
871
 
 */
872
 
enum elf_gfxip_level
873
 
{
874
 
   EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
875
 
   EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
876
 
   EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
877
 
   EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
878
 
};
879
 
 
880
 
static enum elf_gfxip_level ac_chip_class_to_elf_gfxip_level(enum chip_class chip_class)
881
 
{
882
 
   switch (chip_class) {
883
 
   case GFX8:
884
 
      return EF_AMDGPU_MACH_AMDGCN_GFX801;
885
 
   case GFX9:
886
 
      return EF_AMDGPU_MACH_AMDGCN_GFX900;
887
 
   case GFX10:
888
 
      return EF_AMDGPU_MACH_AMDGCN_GFX1010;
889
 
   case GFX10_3:
890
 
      return EF_AMDGPU_MACH_AMDGCN_GFX1030;
891
 
   default:
892
 
      unreachable("Invalid chip class");
893
 
   }
894
 
}
895
 
 
896
 
/**
897
 
 * SQTT SPM DB info.
898
 
 */
899
 
struct sqtt_spm_counter_info {
900
 
   enum ac_pc_gpu_block block;
901
 
   uint32_t instance;
902
 
   uint32_t data_offset; /* offset of counter from the beginning of the chunk */
903
 
   uint32_t event_index; /* index of counter within the block */
904
 
};
905
 
 
906
 
struct sqtt_file_chunk_spm_db {
907
 
   struct sqtt_file_chunk_header header;
908
 
   uint32_t flags;
909
 
   uint32_t num_timestamps;
910
 
   uint32_t num_spm_counter_info;
911
 
   uint32_t sample_interval;
912
 
};
913
 
 
914
 
static_assert(sizeof(struct sqtt_file_chunk_spm_db) == 32,
915
 
              "sqtt_file_chunk_spm_db doesn't match RGP spec");
916
 
 
917
 
static void ac_sqtt_fill_spm_db(const struct ac_spm_trace_data *spm_trace,
918
 
                                struct sqtt_file_chunk_spm_db *chunk,
919
 
                                uint32_t num_samples,
920
 
                                uint32_t chunk_size)
921
 
{
922
 
   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SPM_DB;
923
 
   chunk->header.chunk_id.index = 0;
924
 
   chunk->header.major_version = 1;
925
 
   chunk->header.minor_version = 3;
926
 
   chunk->header.size_in_bytes = chunk_size;
927
 
 
928
 
   chunk->flags = 0;
929
 
   chunk->num_timestamps = num_samples;
930
 
   chunk->num_spm_counter_info = spm_trace->num_counters;
931
 
   chunk->sample_interval = spm_trace->sample_interval;
932
 
}
933
 
 
934
 
static void ac_sqtt_dump_spm(const struct ac_spm_trace_data *spm_trace,
935
 
                             size_t file_offset,
936
 
                             FILE *output)
937
 
{
938
 
   uint32_t sample_size_in_bytes = ac_spm_get_sample_size(spm_trace);
939
 
   uint32_t num_samples = ac_spm_get_num_samples(spm_trace);
940
 
   uint8_t *spm_data_ptr = (uint8_t *)spm_trace->ptr;
941
 
   struct sqtt_file_chunk_spm_db spm_db;
942
 
   size_t file_spm_db_offset = file_offset;
943
 
 
944
 
   fseek(output, sizeof(struct sqtt_file_chunk_spm_db), SEEK_CUR);
945
 
   file_offset += sizeof(struct sqtt_file_chunk_spm_db);
946
 
 
947
 
   /* Skip the reserved 32 bytes of data at beginning. */
948
 
   spm_data_ptr += 32;
949
 
 
950
 
   /* SPM timestamps. */
951
 
   uint32_t sample_size_in_qwords = sample_size_in_bytes / sizeof(uint64_t);
952
 
   uint64_t *timestamp_ptr = (uint64_t *)spm_data_ptr;
953
 
 
954
 
   for (uint32_t s = 0; s < num_samples; s++) {
955
 
      uint64_t index = s * sample_size_in_qwords;
956
 
      uint64_t timestamp = timestamp_ptr[index];
957
 
 
958
 
      file_offset += sizeof(timestamp);
959
 
      fwrite(&timestamp, sizeof(timestamp), 1, output);
960
 
   }
961
 
 
962
 
   /* SPM counter info. */
963
 
   uint64_t counter_values_size = num_samples * sizeof(uint16_t);
964
 
   uint64_t counter_values_offset = num_samples * sizeof(uint64_t) +
965
 
                                    spm_trace->num_counters * sizeof(struct sqtt_spm_counter_info);
966
 
 
967
 
   for (uint32_t c = 0; c < spm_trace->num_counters; c++) {
968
 
      struct sqtt_spm_counter_info cntr_info = {
969
 
         .block = spm_trace->counters[c].gpu_block,
970
 
         .instance = spm_trace->counters[c].instance,
971
 
         .data_offset = counter_values_offset,
972
 
         .event_index = spm_trace->counters[c].event_id,
973
 
      };
974
 
 
975
 
      file_offset += sizeof(cntr_info);
976
 
      fwrite(&cntr_info, sizeof(cntr_info), 1, output);
977
 
 
978
 
      counter_values_offset += counter_values_size;
979
 
   }
980
 
 
981
 
   /* SPM counter values. */
982
 
   uint32_t sample_size_in_hwords = sample_size_in_bytes / sizeof(uint16_t);
983
 
   uint16_t *counter_values_ptr = (uint16_t *)spm_data_ptr;
984
 
 
985
 
   for (uint32_t c = 0; c < spm_trace->num_counters; c++) {
986
 
      uint64_t offset = spm_trace->counters[c].offset;
987
 
 
988
 
      for (uint32_t s = 0; s < num_samples; s++) {
989
 
         uint64_t index = offset + (s * sample_size_in_hwords);
990
 
         uint16_t value = counter_values_ptr[index];
991
 
 
992
 
         file_offset += sizeof(value);
993
 
         fwrite(&value, sizeof(value), 1, output);
994
 
      }
995
 
   }
996
 
 
997
 
   /* SQTT SPM DB chunk. */
998
 
   ac_sqtt_fill_spm_db(spm_trace, &spm_db, num_samples,
999
 
                       file_offset - file_spm_db_offset);
1000
 
   fseek(output, file_spm_db_offset, SEEK_SET);
1001
 
   fwrite(&spm_db, sizeof(struct sqtt_file_chunk_spm_db), 1, output);
1002
 
   fseek(output, file_offset, SEEK_SET);
1003
 
}
1004
 
 
1005
 
static void ac_sqtt_dump_data(struct radeon_info *rad_info,
1006
 
                              struct ac_thread_trace *thread_trace,
1007
 
                              const struct ac_spm_trace_data *spm_trace,
1008
 
                              FILE *output)
1009
 
{
1010
 
   struct ac_thread_trace_data *thread_trace_data = thread_trace->data;
1011
 
   struct sqtt_file_chunk_asic_info asic_info = {0};
1012
 
   struct sqtt_file_chunk_cpu_info cpu_info = {0};
1013
 
   struct sqtt_file_chunk_api_info api_info = {0};
1014
 
   struct sqtt_file_header header = {0};
1015
 
   size_t file_offset = 0;
1016
 
   struct rgp_code_object *rgp_code_object =
1017
 
                                          &thread_trace_data->rgp_code_object;
1018
 
   struct rgp_loader_events *rgp_loader_events =
1019
 
                                        &thread_trace_data->rgp_loader_events;
1020
 
   struct rgp_pso_correlation *rgp_pso_correlation =
1021
 
                                      &thread_trace_data->rgp_pso_correlation;
1022
 
   struct rgp_queue_info *rgp_queue_info = &thread_trace_data->rgp_queue_info;
1023
 
   struct rgp_queue_event *rgp_queue_event = &thread_trace_data->rgp_queue_event;
1024
 
   struct rgp_clock_calibration *rgp_clock_calibration = &thread_trace_data->rgp_clock_calibration;
1025
 
 
1026
 
   /* SQTT header file. */
1027
 
   ac_sqtt_fill_header(&header);
1028
 
   file_offset += sizeof(header);
1029
 
   fwrite(&header, sizeof(header), 1, output);
1030
 
 
1031
 
   /* SQTT cpu chunk. */
1032
 
   ac_sqtt_fill_cpu_info(&cpu_info);
1033
 
   file_offset += sizeof(cpu_info);
1034
 
   fwrite(&cpu_info, sizeof(cpu_info), 1, output);
1035
 
 
1036
 
   /* SQTT asic chunk. */
1037
 
   ac_sqtt_fill_asic_info(rad_info, &asic_info);
1038
 
   file_offset += sizeof(asic_info);
1039
 
   fwrite(&asic_info, sizeof(asic_info), 1, output);
1040
 
 
1041
 
   /* SQTT api chunk. */
1042
 
   ac_sqtt_fill_api_info(&api_info);
1043
 
   file_offset += sizeof(api_info);
1044
 
   fwrite(&api_info, sizeof(api_info), 1, output);
1045
 
 
1046
 
    /* SQTT code object database chunk. */
1047
 
   if (rgp_code_object->record_count) {
1048
 
      size_t file_code_object_offset = file_offset;
1049
 
      struct sqtt_file_chunk_code_object_database code_object;
1050
 
      struct sqtt_code_object_database_record code_object_record;
1051
 
      uint32_t elf_size_calc = 0;
1052
 
      uint32_t flags = ac_chip_class_to_elf_gfxip_level(rad_info->chip_class);
1053
 
 
1054
 
      fseek(output, sizeof(struct sqtt_file_chunk_code_object_database), SEEK_CUR);
1055
 
      file_offset += sizeof(struct sqtt_file_chunk_code_object_database);
1056
 
      list_for_each_entry_safe(struct rgp_code_object_record, record,
1057
 
                               &rgp_code_object->record, list) {
1058
 
         fseek(output, sizeof(struct sqtt_code_object_database_record), SEEK_CUR);
1059
 
         ac_rgp_file_write_elf_object(output, file_offset +
1060
 
                                      sizeof(struct sqtt_code_object_database_record),
1061
 
                                      record, &elf_size_calc, flags);
1062
 
         /* Align to 4 bytes per the RGP file spec. */
1063
 
         code_object_record.size = ALIGN(elf_size_calc, 4);
1064
 
         fseek(output, file_offset, SEEK_SET);
1065
 
         fwrite(&code_object_record, sizeof(struct sqtt_code_object_database_record),
1066
 
                1, output);
1067
 
         file_offset += (sizeof(struct sqtt_code_object_database_record) +
1068
 
                         code_object_record.size);
1069
 
         fseek(output, file_offset, SEEK_SET);
1070
 
      }
1071
 
      ac_sqtt_fill_code_object(rgp_code_object, &code_object,
1072
 
                               file_code_object_offset,
1073
 
                               file_offset - file_code_object_offset);
1074
 
      fseek(output, file_code_object_offset, SEEK_SET);
1075
 
      fwrite(&code_object, sizeof(struct sqtt_file_chunk_code_object_database), 1, output);
1076
 
      fseek(output, file_offset, SEEK_SET);
1077
 
   }
1078
 
 
1079
 
   /* SQTT code object loader events chunk. */
1080
 
   if (rgp_loader_events->record_count) {
1081
 
      struct sqtt_file_chunk_code_object_loader_events loader_events;
1082
 
 
1083
 
      ac_sqtt_fill_loader_events(rgp_loader_events, &loader_events,
1084
 
                                 file_offset);
1085
 
      fwrite(&loader_events, sizeof(struct sqtt_file_chunk_code_object_loader_events),
1086
 
             1, output);
1087
 
      file_offset += sizeof(struct sqtt_file_chunk_code_object_loader_events);
1088
 
      list_for_each_entry_safe(struct rgp_loader_events_record, record,
1089
 
                               &rgp_loader_events->record, list) {
1090
 
         fwrite(record, sizeof(struct sqtt_code_object_loader_events_record), 1, output);
1091
 
      }
1092
 
      file_offset += (rgp_loader_events->record_count *
1093
 
                      sizeof(struct sqtt_code_object_loader_events_record));
1094
 
   }
1095
 
 
1096
 
   /* SQTT pso correlation chunk. */
1097
 
   if (rgp_pso_correlation->record_count) {
1098
 
      struct sqtt_file_chunk_pso_correlation pso_correlation;
1099
 
 
1100
 
      ac_sqtt_fill_pso_correlation(rgp_pso_correlation,
1101
 
                                   &pso_correlation, file_offset);
1102
 
      fwrite(&pso_correlation, sizeof(struct sqtt_file_chunk_pso_correlation), 1,
1103
 
             output);
1104
 
      file_offset += sizeof(struct sqtt_file_chunk_pso_correlation);
1105
 
      list_for_each_entry_safe(struct rgp_pso_correlation_record, record,
1106
 
                               &rgp_pso_correlation->record, list) {
1107
 
         fwrite(record, sizeof(struct sqtt_pso_correlation_record),
1108
 
                1, output);
1109
 
      }
1110
 
      file_offset += (rgp_pso_correlation->record_count *
1111
 
                      sizeof(struct sqtt_pso_correlation_record));
1112
 
   }
1113
 
 
1114
 
   /* SQTT queue event timings. */
1115
 
   if (rgp_queue_info->record_count || rgp_queue_event->record_count) {
1116
 
      struct sqtt_file_chunk_queue_event_timings queue_event_timings;
1117
 
 
1118
 
      ac_sqtt_fill_queue_event_timings(rgp_queue_info, rgp_queue_event,
1119
 
                                       &queue_event_timings);
1120
 
      fwrite(&queue_event_timings, sizeof(struct sqtt_file_chunk_queue_event_timings), 1,
1121
 
             output);
1122
 
      file_offset += sizeof(struct sqtt_file_chunk_queue_event_timings);
1123
 
 
1124
 
      /* Queue info. */
1125
 
      list_for_each_entry_safe(struct rgp_queue_info_record, record,
1126
 
                               &rgp_queue_info->record, list) {
1127
 
         fwrite(record, sizeof(struct sqtt_queue_info_record), 1, output);
1128
 
      }
1129
 
      file_offset += (rgp_queue_info->record_count *
1130
 
                      sizeof(struct sqtt_queue_info_record));
1131
 
 
1132
 
      /* Queue event. */
1133
 
      list_for_each_entry_safe(struct rgp_queue_event_record, record,
1134
 
                               &rgp_queue_event->record, list) {
1135
 
         fwrite(record, sizeof(struct sqtt_queue_event_record), 1, output);
1136
 
      }
1137
 
      file_offset += (rgp_queue_event->record_count *
1138
 
                      sizeof(struct sqtt_queue_event_record));
1139
 
   }
1140
 
 
1141
 
   /* SQTT clock calibration. */
1142
 
   if (rgp_clock_calibration->record_count) {
1143
 
      uint32_t num_records = 0;
1144
 
 
1145
 
      list_for_each_entry_safe(struct rgp_clock_calibration_record, record,
1146
 
                               &rgp_clock_calibration->record, list) {
1147
 
         struct sqtt_file_chunk_clock_calibration clock_calibration;
1148
 
         memset(&clock_calibration, 0, sizeof(clock_calibration));
1149
 
 
1150
 
         ac_sqtt_fill_clock_calibration(&clock_calibration, num_records);
1151
 
 
1152
 
         clock_calibration.cpu_timestamp = record->cpu_timestamp;
1153
 
         clock_calibration.gpu_timestamp = record->gpu_timestamp;
1154
 
 
1155
 
         fwrite(&clock_calibration, sizeof(struct sqtt_file_chunk_clock_calibration), 1,
1156
 
             output);
1157
 
         file_offset += sizeof(struct sqtt_file_chunk_clock_calibration);
1158
 
 
1159
 
         num_records++;
1160
 
      }
1161
 
   }
1162
 
 
1163
 
   if (thread_trace) {
1164
 
      for (unsigned i = 0; i < thread_trace->num_traces; i++) {
1165
 
         const struct ac_thread_trace_se *se = &thread_trace->traces[i];
1166
 
         const struct ac_thread_trace_info *info = &se->info;
1167
 
         struct sqtt_file_chunk_sqtt_desc desc = {0};
1168
 
         struct sqtt_file_chunk_sqtt_data data = {0};
1169
 
         uint64_t size = info->cur_offset * 32; /* unit of 32 bytes */
1170
 
 
1171
 
         /* SQTT desc chunk. */
1172
 
         ac_sqtt_fill_sqtt_desc(rad_info, &desc, i, se->shader_engine, se->compute_unit);
1173
 
         file_offset += sizeof(desc);
1174
 
         fwrite(&desc, sizeof(desc), 1, output);
1175
 
 
1176
 
         /* SQTT data chunk. */
1177
 
         ac_sqtt_fill_sqtt_data(&data, i, file_offset, size);
1178
 
         file_offset += sizeof(data);
1179
 
         fwrite(&data, sizeof(data), 1, output);
1180
 
 
1181
 
         /* Copy thread trace data generated by the hardware. */
1182
 
         file_offset += size;
1183
 
         fwrite(se->data_ptr, size, 1, output);
1184
 
      }
1185
 
   }
1186
 
 
1187
 
   if (spm_trace) {
1188
 
      ac_sqtt_dump_spm(spm_trace, file_offset, output);
1189
 
   }
1190
 
}
1191
 
 
1192
 
int ac_dump_rgp_capture(struct radeon_info *info,
1193
 
                        struct ac_thread_trace *thread_trace,
1194
 
                        const struct ac_spm_trace_data *spm_trace)
1195
 
{
1196
 
   char filename[2048];
1197
 
   struct tm now;
1198
 
   time_t t;
1199
 
   FILE *f;
1200
 
 
1201
 
   t = time(NULL);
1202
 
   now = *localtime(&t);
1203
 
 
1204
 
   snprintf(filename, sizeof(filename), "/tmp/%s_%04d.%02d.%02d_%02d.%02d.%02d.rgp",
1205
 
            util_get_process_name(), 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour,
1206
 
            now.tm_min, now.tm_sec);
1207
 
 
1208
 
   f = fopen(filename, "w+");
1209
 
   if (!f)
1210
 
      return -1;
1211
 
 
1212
 
   ac_sqtt_dump_data(info, thread_trace, spm_trace, f);
1213
 
 
1214
 
   fprintf(stderr, "RGP capture saved to '%s'\n", filename);
1215
 
 
1216
 
   fclose(f);
1217
 
   return 0;
1218
 
}