2 * Copyright © 2017 Intel 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
24 #include "common/gen_decoder.h"
25 #include "gen_disasm.h"
26 #include "util/macros.h"
27 #include "main/macros.h" /* Needed for ROUND_DOWN_TO */
32 gen_batch_decode_ctx_init(struct gen_batch_decode_ctx
*ctx
,
33 const struct gen_device_info
*devinfo
,
34 FILE *fp
, enum gen_batch_decode_flags flags
,
36 struct gen_batch_decode_bo (*get_bo
)(void *,
39 unsigned (*get_state_size
)(void *, uint64_t,
43 memset(ctx
, 0, sizeof(*ctx
));
46 ctx
->get_state_size
= get_state_size
;
47 ctx
->user_data
= user_data
;
50 ctx
->max_vbo_decoded_lines
= -1; /* No limit! */
51 ctx
->engine
= I915_ENGINE_CLASS_RENDER
;
54 ctx
->spec
= gen_spec_load(devinfo
);
56 ctx
->spec
= gen_spec_load_from_path(devinfo
, xml_path
);
57 ctx
->disasm
= gen_disasm_create(devinfo
);
61 gen_batch_decode_ctx_finish(struct gen_batch_decode_ctx
*ctx
)
63 gen_spec_destroy(ctx
->spec
);
64 gen_disasm_destroy(ctx
->disasm
);
68 #define RED_COLOR CSI "31m"
69 #define BLUE_HEADER CSI "0;44m"
70 #define GREEN_HEADER CSI "1;42m"
71 #define NORMAL CSI "0m"
74 ctx_print_group(struct gen_batch_decode_ctx
*ctx
,
75 struct gen_group
*group
,
76 uint64_t address
, const void *map
)
78 gen_print_group(ctx
->fp
, group
, address
, map
, 0,
79 (ctx
->flags
& GEN_BATCH_DECODE_IN_COLOR
) != 0);
82 static struct gen_batch_decode_bo
83 ctx_get_bo(struct gen_batch_decode_ctx
*ctx
, bool ppgtt
, uint64_t addr
)
85 if (gen_spec_get_gen(ctx
->spec
) >= gen_make_gen(8,0)) {
86 /* On Broadwell and above, we have 48-bit addresses which consume two
87 * dwords. Some packets require that these get stored in a "canonical
88 * form" which means that bit 47 is sign-extended through the upper
89 * bits. In order to correctly handle those aub dumps, we need to mask
90 * off the top 16 bits.
92 addr
&= (~0ull >> 16);
95 struct gen_batch_decode_bo bo
= ctx
->get_bo(ctx
->user_data
, ppgtt
, addr
);
97 if (gen_spec_get_gen(ctx
->spec
) >= gen_make_gen(8,0))
98 bo
.addr
&= (~0ull >> 16);
100 /* We may actually have an offset into the bo */
101 if (bo
.map
!= NULL
) {
102 assert(bo
.addr
<= addr
);
103 uint64_t offset
= addr
- bo
.addr
;
113 update_count(struct gen_batch_decode_ctx
*ctx
,
115 uint64_t base_address
,
116 unsigned element_dwords
,
121 if (ctx
->get_state_size
)
122 size
= ctx
->get_state_size(ctx
->user_data
, address
, base_address
);
125 return size
/ (sizeof(uint32_t) * element_dwords
);
127 /* In the absence of any information, just guess arbitrarily. */
132 ctx_disassemble_program(struct gen_batch_decode_ctx
*ctx
,
133 uint32_t ksp
, const char *type
)
135 uint64_t addr
= ctx
->instruction_base
+ ksp
;
136 struct gen_batch_decode_bo bo
= ctx_get_bo(ctx
, true, addr
);
140 fprintf(ctx
->fp
, "\nReferenced %s:\n", type
);
141 gen_disasm_disassemble(ctx
->disasm
, bo
.map
, 0, ctx
->fp
);
144 /* Heuristic to determine whether a uint32_t is probably actually a float
145 * (http://stackoverflow.com/a/2953466)
149 probably_float(uint32_t bits
)
151 int exp
= ((bits
& 0x7f800000U
) >> 23) - 127;
152 uint32_t mant
= bits
& 0x007fffff;
155 if (exp
== -127 && mant
== 0)
158 /* +- 1 billionth to 1 billion */
159 if (-30 <= exp
&& exp
<= 30)
162 /* some value with only a few binary digits */
163 if ((mant
& 0x0000ffff) == 0)
170 ctx_print_buffer(struct gen_batch_decode_ctx
*ctx
,
171 struct gen_batch_decode_bo bo
,
172 uint32_t read_length
,
176 const uint32_t *dw_end
=
177 bo
.map
+ ROUND_DOWN_TO(MIN2(bo
.size
, read_length
), 4);
179 int column_count
= 0, pitch_col_count
= 0, line_count
= -1;
180 for (const uint32_t *dw
= bo
.map
; dw
< dw_end
; dw
++) {
181 if (pitch_col_count
* 4 == pitch
|| column_count
== 8) {
182 fprintf(ctx
->fp
, "\n");
184 if (pitch_col_count
* 4 == pitch
)
188 if (max_lines
>= 0 && line_count
>= max_lines
)
191 fprintf(ctx
->fp
, column_count
== 0 ? " " : " ");
193 if ((ctx
->flags
& GEN_BATCH_DECODE_FLOATS
) && probably_float(*dw
))
194 fprintf(ctx
->fp
, " %8.2f", *(float *) dw
);
196 fprintf(ctx
->fp
, " 0x%08x", *dw
);
201 fprintf(ctx
->fp
, "\n");
204 static struct gen_group
*
205 gen_ctx_find_instruction(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
207 return gen_spec_find_instruction(ctx
->spec
, ctx
->engine
, p
);
211 handle_state_base_address(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
213 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
215 struct gen_field_iterator iter
;
216 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
218 uint64_t surface_base
= 0, dynamic_base
= 0, instruction_base
= 0;
219 bool surface_modify
= 0, dynamic_modify
= 0, instruction_modify
= 0;
221 while (gen_field_iterator_next(&iter
)) {
222 if (strcmp(iter
.name
, "Surface State Base Address") == 0) {
223 surface_base
= iter
.raw_value
;
224 } else if (strcmp(iter
.name
, "Dynamic State Base Address") == 0) {
225 dynamic_base
= iter
.raw_value
;
226 } else if (strcmp(iter
.name
, "Instruction Base Address") == 0) {
227 instruction_base
= iter
.raw_value
;
228 } else if (strcmp(iter
.name
, "Surface State Base Address Modify Enable") == 0) {
229 surface_modify
= iter
.raw_value
;
230 } else if (strcmp(iter
.name
, "Dynamic State Base Address Modify Enable") == 0) {
231 dynamic_modify
= iter
.raw_value
;
232 } else if (strcmp(iter
.name
, "Instruction Base Address Modify Enable") == 0) {
233 instruction_modify
= iter
.raw_value
;
238 ctx
->dynamic_base
= dynamic_base
;
241 ctx
->surface_base
= surface_base
;
243 if (instruction_modify
)
244 ctx
->instruction_base
= instruction_base
;
248 dump_binding_table(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
, int count
)
250 struct gen_group
*strct
=
251 gen_spec_find_struct(ctx
->spec
, "RENDER_SURFACE_STATE");
253 fprintf(ctx
->fp
, "did not find RENDER_SURFACE_STATE info\n");
258 count
= update_count(ctx
, ctx
->surface_base
+ offset
,
259 ctx
->surface_base
, 1, 8);
262 if (offset
% 32 != 0 || offset
>= UINT16_MAX
) {
263 fprintf(ctx
->fp
, " invalid binding table pointer\n");
267 struct gen_batch_decode_bo bind_bo
=
268 ctx_get_bo(ctx
, true, ctx
->surface_base
+ offset
);
270 if (bind_bo
.map
== NULL
) {
271 fprintf(ctx
->fp
, " binding table unavailable\n");
275 const uint32_t *pointers
= bind_bo
.map
;
276 for (int i
= 0; i
< count
; i
++) {
277 if (pointers
[i
] == 0)
280 uint64_t addr
= ctx
->surface_base
+ pointers
[i
];
281 struct gen_batch_decode_bo bo
= ctx_get_bo(ctx
, true, addr
);
282 uint32_t size
= strct
->dw_length
* 4;
284 if (pointers
[i
] % 32 != 0 ||
285 addr
< bo
.addr
|| addr
+ size
>= bo
.addr
+ bo
.size
) {
286 fprintf(ctx
->fp
, "pointer %u: 0x%08x <not valid>\n", i
, pointers
[i
]);
290 fprintf(ctx
->fp
, "pointer %u: 0x%08x\n", i
, pointers
[i
]);
291 ctx_print_group(ctx
, strct
, addr
, bo
.map
+ (addr
- bo
.addr
));
296 dump_samplers(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
, int count
)
298 struct gen_group
*strct
= gen_spec_find_struct(ctx
->spec
, "SAMPLER_STATE");
299 uint64_t state_addr
= ctx
->dynamic_base
+ offset
;
302 count
= update_count(ctx
, state_addr
, ctx
->dynamic_base
,
303 strct
->dw_length
, 4);
306 struct gen_batch_decode_bo bo
= ctx_get_bo(ctx
, true, state_addr
);
307 const void *state_map
= bo
.map
;
309 if (state_map
== NULL
) {
310 fprintf(ctx
->fp
, " samplers unavailable\n");
314 if (offset
% 32 != 0 || state_addr
- bo
.addr
>= bo
.size
) {
315 fprintf(ctx
->fp
, " invalid sampler state pointer\n");
319 for (int i
= 0; i
< count
; i
++) {
320 fprintf(ctx
->fp
, "sampler state %d\n", i
);
321 ctx_print_group(ctx
, strct
, state_addr
, state_map
);
328 handle_media_interface_descriptor_load(struct gen_batch_decode_ctx
*ctx
,
331 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
332 struct gen_group
*desc
=
333 gen_spec_find_struct(ctx
->spec
, "INTERFACE_DESCRIPTOR_DATA");
335 struct gen_field_iterator iter
;
336 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
337 uint32_t descriptor_offset
= 0;
338 int descriptor_count
= 0;
339 while (gen_field_iterator_next(&iter
)) {
340 if (strcmp(iter
.name
, "Interface Descriptor Data Start Address") == 0) {
341 descriptor_offset
= strtol(iter
.value
, NULL
, 16);
342 } else if (strcmp(iter
.name
, "Interface Descriptor Total Length") == 0) {
344 strtol(iter
.value
, NULL
, 16) / (desc
->dw_length
* 4);
348 uint64_t desc_addr
= ctx
->dynamic_base
+ descriptor_offset
;
349 struct gen_batch_decode_bo bo
= ctx_get_bo(ctx
, true, desc_addr
);
350 const void *desc_map
= bo
.map
;
352 if (desc_map
== NULL
) {
353 fprintf(ctx
->fp
, " interface descriptors unavailable\n");
357 for (int i
= 0; i
< descriptor_count
; i
++) {
358 fprintf(ctx
->fp
, "descriptor %d: %08x\n", i
, descriptor_offset
);
360 ctx_print_group(ctx
, desc
, desc_addr
, desc_map
);
362 gen_field_iterator_init(&iter
, desc
, desc_map
, 0, false);
364 uint32_t sampler_offset
= 0, sampler_count
= 0;
365 uint32_t binding_table_offset
= 0, binding_entry_count
= 0;
366 while (gen_field_iterator_next(&iter
)) {
367 if (strcmp(iter
.name
, "Kernel Start Pointer") == 0) {
368 ksp
= strtoll(iter
.value
, NULL
, 16);
369 } else if (strcmp(iter
.name
, "Sampler State Pointer") == 0) {
370 sampler_offset
= strtol(iter
.value
, NULL
, 16);
371 } else if (strcmp(iter
.name
, "Sampler Count") == 0) {
372 sampler_count
= strtol(iter
.value
, NULL
, 10);
373 } else if (strcmp(iter
.name
, "Binding Table Pointer") == 0) {
374 binding_table_offset
= strtol(iter
.value
, NULL
, 16);
375 } else if (strcmp(iter
.name
, "Binding Table Entry Count") == 0) {
376 binding_entry_count
= strtol(iter
.value
, NULL
, 10);
380 ctx_disassemble_program(ctx
, ksp
, "compute shader");
381 fprintf(ctx
->fp
, "\n");
383 dump_samplers(ctx
, sampler_offset
, sampler_count
);
384 dump_binding_table(ctx
, binding_table_offset
, binding_entry_count
);
386 desc_map
+= desc
->dw_length
;
387 desc_addr
+= desc
->dw_length
* 4;
392 handle_3dstate_vertex_buffers(struct gen_batch_decode_ctx
*ctx
,
395 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
396 struct gen_group
*vbs
= gen_spec_find_struct(ctx
->spec
, "VERTEX_BUFFER_STATE");
398 struct gen_batch_decode_bo vb
= {};
399 uint32_t vb_size
= 0;
404 struct gen_field_iterator iter
;
405 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
406 while (gen_field_iterator_next(&iter
)) {
407 if (iter
.struct_desc
!= vbs
)
410 struct gen_field_iterator vbs_iter
;
411 gen_field_iterator_init(&vbs_iter
, vbs
, &iter
.p
[iter
.start_bit
/ 32], 0, false);
412 while (gen_field_iterator_next(&vbs_iter
)) {
413 if (strcmp(vbs_iter
.name
, "Vertex Buffer Index") == 0) {
414 index
= vbs_iter
.raw_value
;
415 } else if (strcmp(vbs_iter
.name
, "Buffer Pitch") == 0) {
416 pitch
= vbs_iter
.raw_value
;
417 } else if (strcmp(vbs_iter
.name
, "Buffer Starting Address") == 0) {
418 vb
= ctx_get_bo(ctx
, true, vbs_iter
.raw_value
);
419 } else if (strcmp(vbs_iter
.name
, "Buffer Size") == 0) {
420 vb_size
= vbs_iter
.raw_value
;
422 } else if (strcmp(vbs_iter
.name
, "End Address") == 0) {
423 if (vb
.map
&& vbs_iter
.raw_value
>= vb
.addr
)
424 vb_size
= (vbs_iter
.raw_value
+ 1) - vb
.addr
;
433 fprintf(ctx
->fp
, "vertex buffer %d, size %d\n", index
, vb_size
);
435 if (vb
.map
== NULL
) {
436 fprintf(ctx
->fp
, " buffer contents unavailable\n");
440 if (vb
.map
== 0 || vb_size
== 0)
443 ctx_print_buffer(ctx
, vb
, vb_size
, pitch
, ctx
->max_vbo_decoded_lines
);
455 handle_3dstate_index_buffer(struct gen_batch_decode_ctx
*ctx
,
458 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
460 struct gen_batch_decode_bo ib
= {};
461 uint32_t ib_size
= 0;
464 struct gen_field_iterator iter
;
465 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
466 while (gen_field_iterator_next(&iter
)) {
467 if (strcmp(iter
.name
, "Index Format") == 0) {
468 format
= iter
.raw_value
;
469 } else if (strcmp(iter
.name
, "Buffer Starting Address") == 0) {
470 ib
= ctx_get_bo(ctx
, true, iter
.raw_value
);
471 } else if (strcmp(iter
.name
, "Buffer Size") == 0) {
472 ib_size
= iter
.raw_value
;
476 if (ib
.map
== NULL
) {
477 fprintf(ctx
->fp
, " buffer contents unavailable\n");
481 const void *m
= ib
.map
;
482 const void *ib_end
= ib
.map
+ MIN2(ib
.size
, ib_size
);
483 for (int i
= 0; m
< ib_end
&& i
< 10; i
++) {
486 fprintf(ctx
->fp
, "%3d ", *(uint8_t *)m
);
490 fprintf(ctx
->fp
, "%3d ", *(uint16_t *)m
);
494 fprintf(ctx
->fp
, "%3d ", *(uint32_t *)m
);
501 fprintf(ctx
->fp
, "...");
502 fprintf(ctx
->fp
, "\n");
506 decode_single_ksp(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
508 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
511 bool is_simd8
= false; /* vertex shaders on Gen8+ only */
512 bool is_enabled
= true;
514 struct gen_field_iterator iter
;
515 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
516 while (gen_field_iterator_next(&iter
)) {
517 if (strcmp(iter
.name
, "Kernel Start Pointer") == 0) {
518 ksp
= iter
.raw_value
;
519 } else if (strcmp(iter
.name
, "SIMD8 Dispatch Enable") == 0) {
520 is_simd8
= iter
.raw_value
;
521 } else if (strcmp(iter
.name
, "Dispatch Mode") == 0) {
522 is_simd8
= strcmp(iter
.value
, "SIMD8") == 0;
523 } else if (strcmp(iter
.name
, "Dispatch Enable") == 0) {
524 is_simd8
= strcmp(iter
.value
, "SIMD8") == 0;
525 } else if (strcmp(iter
.name
, "Enable") == 0) {
526 is_enabled
= iter
.raw_value
;
531 strcmp(inst
->name
, "VS_STATE") == 0 ? "vertex shader" :
532 strcmp(inst
->name
, "GS_STATE") == 0 ? "geometry shader" :
533 strcmp(inst
->name
, "SF_STATE") == 0 ? "strips and fans shader" :
534 strcmp(inst
->name
, "CLIP_STATE") == 0 ? "clip shader" :
535 strcmp(inst
->name
, "3DSTATE_DS") == 0 ? "tessellation evaluation shader" :
536 strcmp(inst
->name
, "3DSTATE_HS") == 0 ? "tessellation control shader" :
537 strcmp(inst
->name
, "3DSTATE_VS") == 0 ? (is_simd8
? "SIMD8 vertex shader" : "vec4 vertex shader") :
538 strcmp(inst
->name
, "3DSTATE_GS") == 0 ? (is_simd8
? "SIMD8 geometry shader" : "vec4 geometry shader") :
542 ctx_disassemble_program(ctx
, ksp
, type
);
543 fprintf(ctx
->fp
, "\n");
548 decode_ps_kernels(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
550 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
552 uint64_t ksp
[3] = {0, 0, 0};
553 bool enabled
[3] = {false, false, false};
555 struct gen_field_iterator iter
;
556 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
557 while (gen_field_iterator_next(&iter
)) {
558 if (strncmp(iter
.name
, "Kernel Start Pointer ",
559 strlen("Kernel Start Pointer ")) == 0) {
560 int idx
= iter
.name
[strlen("Kernel Start Pointer ")] - '0';
561 ksp
[idx
] = strtol(iter
.value
, NULL
, 16);
562 } else if (strcmp(iter
.name
, "8 Pixel Dispatch Enable") == 0) {
563 enabled
[0] = strcmp(iter
.value
, "true") == 0;
564 } else if (strcmp(iter
.name
, "16 Pixel Dispatch Enable") == 0) {
565 enabled
[1] = strcmp(iter
.value
, "true") == 0;
566 } else if (strcmp(iter
.name
, "32 Pixel Dispatch Enable") == 0) {
567 enabled
[2] = strcmp(iter
.value
, "true") == 0;
571 /* Reorder KSPs to be [8, 16, 32] instead of the hardware order. */
572 if (enabled
[0] + enabled
[1] + enabled
[2] == 1) {
576 } else if (enabled
[2]) {
581 uint64_t tmp
= ksp
[1];
587 ctx_disassemble_program(ctx
, ksp
[0], "SIMD8 fragment shader");
589 ctx_disassemble_program(ctx
, ksp
[1], "SIMD16 fragment shader");
591 ctx_disassemble_program(ctx
, ksp
[2], "SIMD32 fragment shader");
593 if (enabled
[0] || enabled
[1] || enabled
[2])
594 fprintf(ctx
->fp
, "\n");
598 decode_3dstate_constant_all(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
600 struct gen_group
*inst
=
601 gen_spec_find_instruction(ctx
->spec
, ctx
->engine
, p
);
602 struct gen_group
*body
=
603 gen_spec_find_struct(ctx
->spec
, "3DSTATE_CONSTANT_ALL_DATA");
605 uint32_t read_length
[4];
606 struct gen_batch_decode_bo buffer
[4];
607 memset(buffer
, 0, sizeof(buffer
));
609 struct gen_field_iterator outer
;
610 gen_field_iterator_init(&outer
, inst
, p
, 0, false);
612 while (gen_field_iterator_next(&outer
)) {
613 if (outer
.struct_desc
!= body
)
616 struct gen_field_iterator iter
;
617 gen_field_iterator_init(&iter
, body
, &outer
.p
[outer
.start_bit
/ 32],
619 while (gen_field_iterator_next(&iter
)) {
620 if (!strcmp(iter
.name
, "Pointer To Constant Buffer")) {
621 buffer
[idx
] = ctx_get_bo(ctx
, true, iter
.raw_value
);
622 } else if (!strcmp(iter
.name
, "Constant Buffer Read Length")) {
623 read_length
[idx
] = iter
.raw_value
;
629 for (int i
= 0; i
< 4; i
++) {
630 if (read_length
[i
] == 0 || buffer
[i
].map
== NULL
)
633 unsigned size
= read_length
[i
] * 32;
634 fprintf(ctx
->fp
, "constant buffer %d, size %u\n", i
, size
);
636 ctx_print_buffer(ctx
, buffer
[i
], size
, 0, -1);
641 decode_3dstate_constant(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
643 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
644 struct gen_group
*body
=
645 gen_spec_find_struct(ctx
->spec
, "3DSTATE_CONSTANT_BODY");
647 uint32_t read_length
[4] = {0};
648 uint64_t read_addr
[4];
650 struct gen_field_iterator outer
;
651 gen_field_iterator_init(&outer
, inst
, p
, 0, false);
652 while (gen_field_iterator_next(&outer
)) {
653 if (outer
.struct_desc
!= body
)
656 struct gen_field_iterator iter
;
657 gen_field_iterator_init(&iter
, body
, &outer
.p
[outer
.start_bit
/ 32],
660 while (gen_field_iterator_next(&iter
)) {
662 if (sscanf(iter
.name
, "Read Length[%d]", &idx
) == 1) {
663 read_length
[idx
] = iter
.raw_value
;
664 } else if (sscanf(iter
.name
, "Buffer[%d]", &idx
) == 1) {
665 read_addr
[idx
] = iter
.raw_value
;
669 for (int i
= 0; i
< 4; i
++) {
670 if (read_length
[i
] == 0)
673 struct gen_batch_decode_bo buffer
= ctx_get_bo(ctx
, true, read_addr
[i
]);
675 fprintf(ctx
->fp
, "constant buffer %d unavailable\n", i
);
679 unsigned size
= read_length
[i
] * 32;
680 fprintf(ctx
->fp
, "constant buffer %d, size %u\n", i
, size
);
682 ctx_print_buffer(ctx
, buffer
, size
, 0, -1);
688 decode_gen6_3dstate_binding_table_pointers(struct gen_batch_decode_ctx
*ctx
,
691 fprintf(ctx
->fp
, "VS Binding Table:\n");
692 dump_binding_table(ctx
, p
[1], -1);
694 fprintf(ctx
->fp
, "GS Binding Table:\n");
695 dump_binding_table(ctx
, p
[2], -1);
697 fprintf(ctx
->fp
, "PS Binding Table:\n");
698 dump_binding_table(ctx
, p
[3], -1);
702 decode_3dstate_binding_table_pointers(struct gen_batch_decode_ctx
*ctx
,
705 dump_binding_table(ctx
, p
[1], -1);
709 decode_3dstate_sampler_state_pointers(struct gen_batch_decode_ctx
*ctx
,
712 dump_samplers(ctx
, p
[1], -1);
716 decode_3dstate_sampler_state_pointers_gen6(struct gen_batch_decode_ctx
*ctx
,
719 dump_samplers(ctx
, p
[1], -1);
720 dump_samplers(ctx
, p
[2], -1);
721 dump_samplers(ctx
, p
[3], -1);
725 str_ends_with(const char *str
, const char *end
)
727 int offset
= strlen(str
) - strlen(end
);
731 return strcmp(str
+ offset
, end
) == 0;
735 decode_dynamic_state_pointers(struct gen_batch_decode_ctx
*ctx
,
736 const char *struct_type
, const uint32_t *p
,
739 struct gen_group
*inst
= gen_ctx_find_instruction(ctx
, p
);
741 uint32_t state_offset
= 0;
743 struct gen_field_iterator iter
;
744 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
745 while (gen_field_iterator_next(&iter
)) {
746 if (str_ends_with(iter
.name
, "Pointer")) {
747 state_offset
= iter
.raw_value
;
752 uint64_t state_addr
= ctx
->dynamic_base
+ state_offset
;
753 struct gen_batch_decode_bo bo
= ctx_get_bo(ctx
, true, state_addr
);
754 const void *state_map
= bo
.map
;
756 if (state_map
== NULL
) {
757 fprintf(ctx
->fp
, " dynamic %s state unavailable\n", struct_type
);
761 struct gen_group
*state
= gen_spec_find_struct(ctx
->spec
, struct_type
);
762 if (strcmp(struct_type
, "BLEND_STATE") == 0) {
763 /* Blend states are different from the others because they have a header
764 * struct called BLEND_STATE which is followed by a variable number of
765 * BLEND_STATE_ENTRY structs.
767 fprintf(ctx
->fp
, "%s\n", struct_type
);
768 ctx_print_group(ctx
, state
, state_addr
, state_map
);
770 state_addr
+= state
->dw_length
* 4;
771 state_map
+= state
->dw_length
* 4;
773 struct_type
= "BLEND_STATE_ENTRY";
774 state
= gen_spec_find_struct(ctx
->spec
, struct_type
);
777 count
= update_count(ctx
, ctx
->dynamic_base
+ state_offset
,
778 ctx
->dynamic_base
, state
->dw_length
, count
);
780 for (int i
= 0; i
< count
; i
++) {
781 fprintf(ctx
->fp
, "%s %d\n", struct_type
, i
);
782 ctx_print_group(ctx
, state
, state_addr
, state_map
);
784 state_addr
+= state
->dw_length
* 4;
785 state_map
+= state
->dw_length
* 4;
790 decode_3dstate_viewport_state_pointers_cc(struct gen_batch_decode_ctx
*ctx
,
793 decode_dynamic_state_pointers(ctx
, "CC_VIEWPORT", p
, 4);
797 decode_3dstate_viewport_state_pointers_sf_clip(struct gen_batch_decode_ctx
*ctx
,
800 decode_dynamic_state_pointers(ctx
, "SF_CLIP_VIEWPORT", p
, 4);
804 decode_3dstate_blend_state_pointers(struct gen_batch_decode_ctx
*ctx
,
807 decode_dynamic_state_pointers(ctx
, "BLEND_STATE", p
, 1);
811 decode_3dstate_cc_state_pointers(struct gen_batch_decode_ctx
*ctx
,
814 decode_dynamic_state_pointers(ctx
, "COLOR_CALC_STATE", p
, 1);
818 decode_3dstate_scissor_state_pointers(struct gen_batch_decode_ctx
*ctx
,
821 decode_dynamic_state_pointers(ctx
, "SCISSOR_RECT", p
, 1);
825 decode_3dstate_slice_table_state_pointers(struct gen_batch_decode_ctx
*ctx
,
828 decode_dynamic_state_pointers(ctx
, "SLICE_HASH_TABLE", p
, 1);
832 decode_load_register_imm(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
834 struct gen_group
*reg
= gen_spec_find_register(ctx
->spec
, p
[1]);
837 fprintf(ctx
->fp
, "register %s (0x%x): 0x%x\n",
838 reg
->name
, reg
->register_offset
, p
[2]);
839 ctx_print_group(ctx
, reg
, reg
->register_offset
, &p
[2]);
844 decode_vs_state(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
)
846 struct gen_group
*strct
=
847 gen_spec_find_struct(ctx
->spec
, "VS_STATE");
849 fprintf(ctx
->fp
, "did not find VS_STATE info\n");
853 struct gen_batch_decode_bo bind_bo
=
854 ctx_get_bo(ctx
, true, offset
);
856 if (bind_bo
.map
== NULL
) {
857 fprintf(ctx
->fp
, " vs state unavailable\n");
861 ctx_print_group(ctx
, strct
, offset
, bind_bo
.map
);
866 decode_clip_state(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
)
868 struct gen_group
*strct
=
869 gen_spec_find_struct(ctx
->spec
, "CLIP_STATE");
871 fprintf(ctx
->fp
, "did not find CLIP_STATE info\n");
875 struct gen_batch_decode_bo bind_bo
=
876 ctx_get_bo(ctx
, true, offset
);
878 if (bind_bo
.map
== NULL
) {
879 fprintf(ctx
->fp
, " clip state unavailable\n");
883 ctx_print_group(ctx
, strct
, offset
, bind_bo
.map
);
885 struct gen_group
*vp_strct
=
886 gen_spec_find_struct(ctx
->spec
, "CLIP_VIEWPORT");
887 if (vp_strct
== NULL
) {
888 fprintf(ctx
->fp
, "did not find CLIP_VIEWPORT info\n");
891 uint32_t clip_vp_offset
= ((uint32_t *)bind_bo
.map
)[6] & ~0x3;
892 struct gen_batch_decode_bo vp_bo
=
893 ctx_get_bo(ctx
, true, clip_vp_offset
);
894 if (vp_bo
.map
== NULL
) {
895 fprintf(ctx
->fp
, " clip vp state unavailable\n");
898 ctx_print_group(ctx
, vp_strct
, clip_vp_offset
, vp_bo
.map
);
902 decode_sf_state(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
)
904 struct gen_group
*strct
=
905 gen_spec_find_struct(ctx
->spec
, "SF_STATE");
907 fprintf(ctx
->fp
, "did not find SF_STATE info\n");
911 struct gen_batch_decode_bo bind_bo
=
912 ctx_get_bo(ctx
, true, offset
);
914 if (bind_bo
.map
== NULL
) {
915 fprintf(ctx
->fp
, " sf state unavailable\n");
919 ctx_print_group(ctx
, strct
, offset
, bind_bo
.map
);
921 struct gen_group
*vp_strct
=
922 gen_spec_find_struct(ctx
->spec
, "SF_VIEWPORT");
923 if (vp_strct
== NULL
) {
924 fprintf(ctx
->fp
, "did not find SF_VIEWPORT info\n");
928 uint32_t sf_vp_offset
= ((uint32_t *)bind_bo
.map
)[5] & ~0x3;
929 struct gen_batch_decode_bo vp_bo
=
930 ctx_get_bo(ctx
, true, sf_vp_offset
);
931 if (vp_bo
.map
== NULL
) {
932 fprintf(ctx
->fp
, " sf vp state unavailable\n");
935 ctx_print_group(ctx
, vp_strct
, sf_vp_offset
, vp_bo
.map
);
939 decode_wm_state(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
)
941 struct gen_group
*strct
=
942 gen_spec_find_struct(ctx
->spec
, "WM_STATE");
944 fprintf(ctx
->fp
, "did not find WM_STATE info\n");
948 struct gen_batch_decode_bo bind_bo
=
949 ctx_get_bo(ctx
, true, offset
);
951 if (bind_bo
.map
== NULL
) {
952 fprintf(ctx
->fp
, " wm state unavailable\n");
956 ctx_print_group(ctx
, strct
, offset
, bind_bo
.map
);
960 decode_cc_state(struct gen_batch_decode_ctx
*ctx
, uint32_t offset
)
962 struct gen_group
*strct
=
963 gen_spec_find_struct(ctx
->spec
, "COLOR_CALC_STATE");
965 fprintf(ctx
->fp
, "did not find COLOR_CALC_STATE info\n");
969 struct gen_batch_decode_bo bind_bo
=
970 ctx_get_bo(ctx
, true, offset
);
972 if (bind_bo
.map
== NULL
) {
973 fprintf(ctx
->fp
, " cc state unavailable\n");
977 ctx_print_group(ctx
, strct
, offset
, bind_bo
.map
);
979 struct gen_group
*vp_strct
=
980 gen_spec_find_struct(ctx
->spec
, "CC_VIEWPORT");
981 if (vp_strct
== NULL
) {
982 fprintf(ctx
->fp
, "did not find CC_VIEWPORT info\n");
985 uint32_t cc_vp_offset
= ((uint32_t *)bind_bo
.map
)[4] & ~0x3;
986 struct gen_batch_decode_bo vp_bo
=
987 ctx_get_bo(ctx
, true, cc_vp_offset
);
988 if (vp_bo
.map
== NULL
) {
989 fprintf(ctx
->fp
, " cc vp state unavailable\n");
992 ctx_print_group(ctx
, vp_strct
, cc_vp_offset
, vp_bo
.map
);
995 decode_pipelined_pointers(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
)
997 fprintf(ctx
->fp
, "VS State Table:\n");
998 decode_vs_state(ctx
, p
[1]);
999 fprintf(ctx
->fp
, "Clip State Table:\n");
1000 decode_clip_state(ctx
, p
[3] & ~1);
1001 fprintf(ctx
->fp
, "SF State Table:\n");
1002 decode_sf_state(ctx
, p
[4]);
1003 fprintf(ctx
->fp
, "WM State Table:\n");
1004 decode_wm_state(ctx
, p
[5]);
1005 fprintf(ctx
->fp
, "CC State Table:\n");
1006 decode_cc_state(ctx
, p
[6]);
1009 struct custom_decoder
{
1010 const char *cmd_name
;
1011 void (*decode
)(struct gen_batch_decode_ctx
*ctx
, const uint32_t *p
);
1012 } custom_decoders
[] = {
1013 { "STATE_BASE_ADDRESS", handle_state_base_address
},
1014 { "MEDIA_INTERFACE_DESCRIPTOR_LOAD", handle_media_interface_descriptor_load
},
1015 { "3DSTATE_VERTEX_BUFFERS", handle_3dstate_vertex_buffers
},
1016 { "3DSTATE_INDEX_BUFFER", handle_3dstate_index_buffer
},
1017 { "3DSTATE_VS", decode_single_ksp
},
1018 { "3DSTATE_GS", decode_single_ksp
},
1019 { "3DSTATE_DS", decode_single_ksp
},
1020 { "3DSTATE_HS", decode_single_ksp
},
1021 { "3DSTATE_PS", decode_ps_kernels
},
1022 { "3DSTATE_WM", decode_ps_kernels
},
1023 { "3DSTATE_CONSTANT_VS", decode_3dstate_constant
},
1024 { "3DSTATE_CONSTANT_GS", decode_3dstate_constant
},
1025 { "3DSTATE_CONSTANT_PS", decode_3dstate_constant
},
1026 { "3DSTATE_CONSTANT_HS", decode_3dstate_constant
},
1027 { "3DSTATE_CONSTANT_DS", decode_3dstate_constant
},
1028 { "3DSTATE_CONSTANT_ALL", decode_3dstate_constant_all
},
1030 { "3DSTATE_BINDING_TABLE_POINTERS", decode_gen6_3dstate_binding_table_pointers
},
1031 { "3DSTATE_BINDING_TABLE_POINTERS_VS", decode_3dstate_binding_table_pointers
},
1032 { "3DSTATE_BINDING_TABLE_POINTERS_HS", decode_3dstate_binding_table_pointers
},
1033 { "3DSTATE_BINDING_TABLE_POINTERS_DS", decode_3dstate_binding_table_pointers
},
1034 { "3DSTATE_BINDING_TABLE_POINTERS_GS", decode_3dstate_binding_table_pointers
},
1035 { "3DSTATE_BINDING_TABLE_POINTERS_PS", decode_3dstate_binding_table_pointers
},
1037 { "3DSTATE_SAMPLER_STATE_POINTERS_VS", decode_3dstate_sampler_state_pointers
},
1038 { "3DSTATE_SAMPLER_STATE_POINTERS_HS", decode_3dstate_sampler_state_pointers
},
1039 { "3DSTATE_SAMPLER_STATE_POINTERS_DS", decode_3dstate_sampler_state_pointers
},
1040 { "3DSTATE_SAMPLER_STATE_POINTERS_GS", decode_3dstate_sampler_state_pointers
},
1041 { "3DSTATE_SAMPLER_STATE_POINTERS_PS", decode_3dstate_sampler_state_pointers
},
1042 { "3DSTATE_SAMPLER_STATE_POINTERS", decode_3dstate_sampler_state_pointers_gen6
},
1044 { "3DSTATE_VIEWPORT_STATE_POINTERS_CC", decode_3dstate_viewport_state_pointers_cc
},
1045 { "3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP", decode_3dstate_viewport_state_pointers_sf_clip
},
1046 { "3DSTATE_BLEND_STATE_POINTERS", decode_3dstate_blend_state_pointers
},
1047 { "3DSTATE_CC_STATE_POINTERS", decode_3dstate_cc_state_pointers
},
1048 { "3DSTATE_SCISSOR_STATE_POINTERS", decode_3dstate_scissor_state_pointers
},
1049 { "3DSTATE_SLICE_TABLE_STATE_POINTERS", decode_3dstate_slice_table_state_pointers
},
1050 { "MI_LOAD_REGISTER_IMM", decode_load_register_imm
},
1051 { "3DSTATE_PIPELINED_POINTERS", decode_pipelined_pointers
}
1055 gen_print_batch(struct gen_batch_decode_ctx
*ctx
,
1056 const uint32_t *batch
, uint32_t batch_size
,
1057 uint64_t batch_addr
, bool from_ring
)
1059 const uint32_t *p
, *end
= batch
+ batch_size
/ sizeof(uint32_t);
1061 struct gen_group
*inst
;
1062 const char *reset_color
= ctx
->flags
& GEN_BATCH_DECODE_IN_COLOR
? NORMAL
: "";
1064 if (ctx
->n_batch_buffer_start
>= 100) {
1065 fprintf(ctx
->fp
, "%s0x%08"PRIx64
": Max batch buffer jumps exceeded%s\n",
1066 (ctx
->flags
& GEN_BATCH_DECODE_IN_COLOR
) ? RED_COLOR
: "",
1067 (ctx
->flags
& GEN_BATCH_DECODE_OFFSETS
) ? batch_addr
: 0,
1072 ctx
->n_batch_buffer_start
++;
1074 for (p
= batch
; p
< end
; p
+= length
) {
1075 inst
= gen_ctx_find_instruction(ctx
, p
);
1076 length
= gen_group_get_length(inst
, p
);
1077 assert(inst
== NULL
|| length
> 0);
1078 length
= MAX2(1, length
);
1081 if (ctx
->flags
& GEN_BATCH_DECODE_OFFSETS
)
1082 offset
= batch_addr
+ ((char *)p
- (char *)batch
);
1087 fprintf(ctx
->fp
, "%s0x%08"PRIx64
": unknown instruction %08x%s\n",
1088 (ctx
->flags
& GEN_BATCH_DECODE_IN_COLOR
) ? RED_COLOR
: "",
1089 offset
, p
[0], reset_color
);
1094 const char *inst_name
= gen_group_get_name(inst
);
1095 if (ctx
->flags
& GEN_BATCH_DECODE_IN_COLOR
) {
1096 reset_color
= NORMAL
;
1097 if (ctx
->flags
& GEN_BATCH_DECODE_FULL
) {
1098 if (strcmp(inst_name
, "MI_BATCH_BUFFER_START") == 0 ||
1099 strcmp(inst_name
, "MI_BATCH_BUFFER_END") == 0)
1100 color
= GREEN_HEADER
;
1102 color
= BLUE_HEADER
;
1111 fprintf(ctx
->fp
, "%s0x%08"PRIx64
": 0x%08x: %-80s%s\n",
1112 color
, offset
, p
[0], inst_name
, reset_color
);
1114 if (ctx
->flags
& GEN_BATCH_DECODE_FULL
) {
1115 ctx_print_group(ctx
, inst
, offset
, p
);
1117 for (int i
= 0; i
< ARRAY_SIZE(custom_decoders
); i
++) {
1118 if (strcmp(inst_name
, custom_decoders
[i
].cmd_name
) == 0) {
1119 custom_decoders
[i
].decode(ctx
, p
);
1125 if (strcmp(inst_name
, "MI_BATCH_BUFFER_START") == 0) {
1126 uint64_t next_batch_addr
= 0;
1128 bool second_level
= false;
1129 struct gen_field_iterator iter
;
1130 gen_field_iterator_init(&iter
, inst
, p
, 0, false);
1131 while (gen_field_iterator_next(&iter
)) {
1132 if (strcmp(iter
.name
, "Batch Buffer Start Address") == 0) {
1133 next_batch_addr
= iter
.raw_value
;
1134 } else if (strcmp(iter
.name
, "Second Level Batch Buffer") == 0) {
1135 second_level
= iter
.raw_value
;
1136 } else if (strcmp(iter
.name
, "Address Space Indicator") == 0) {
1137 ppgtt
= iter
.raw_value
;
1141 struct gen_batch_decode_bo next_batch
= ctx_get_bo(ctx
, ppgtt
, next_batch_addr
);
1143 if (next_batch
.map
== NULL
) {
1144 fprintf(ctx
->fp
, "Secondary batch at 0x%08"PRIx64
" unavailable\n",
1147 gen_print_batch(ctx
, next_batch
.map
, next_batch
.size
,
1148 next_batch
.addr
, false);
1151 /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" set acts
1152 * like a subroutine call. Commands that come afterwards get
1153 * processed once the 2nd level batch buffer returns with
1154 * MI_BATCH_BUFFER_END.
1157 } else if (!from_ring
) {
1158 /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" unset acts
1159 * like a goto. Nothing after it will ever get processed. In
1160 * order to prevent the recursion from growing, we just reset the
1161 * loop and continue;
1165 } else if (strcmp(inst_name
, "MI_BATCH_BUFFER_END") == 0) {
1170 ctx
->n_batch_buffer_start
--;