- if (!shader || !shader->binary.disasm_string)
- return;
-
- uint64_t start_addr = shader->bo->gpu_address;
- uint64_t end_addr = start_addr + shader->bo->b.b.width0;
- unsigned i;
-
- /* See if any wave executes the shader. */
- for (i = 0; i < num_waves; i++) {
- if (start_addr <= waves[i].pc && waves[i].pc <= end_addr)
- break;
- }
- if (i == num_waves)
- return; /* the shader is not being executed */
-
- /* Remember the first found wave. The waves are sorted according to PC. */
- waves = &waves[i];
- num_waves -= i;
-
- /* Get the list of instructions.
- * Buffer size / 4 is the upper bound of the instruction count.
- */
- unsigned num_inst = 0;
- struct si_shader_inst *instructions =
- calloc(shader->bo->b.b.width0 / 4, sizeof(struct si_shader_inst));
-
- if (shader->prolog) {
- si_add_split_disasm(shader->prolog->binary.disasm_string,
- start_addr, &num_inst, instructions);
- }
- if (shader->previous_stage) {
- si_add_split_disasm(shader->previous_stage->binary.disasm_string,
- start_addr, &num_inst, instructions);
- }
- if (shader->prolog2) {
- si_add_split_disasm(shader->prolog2->binary.disasm_string,
- start_addr, &num_inst, instructions);
- }
- si_add_split_disasm(shader->binary.disasm_string,
- start_addr, &num_inst, instructions);
- if (shader->epilog) {
- si_add_split_disasm(shader->epilog->binary.disasm_string,
- start_addr, &num_inst, instructions);
- }
-
- fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET "\n",
- si_get_shader_name(shader, shader->selector->type));
-
- /* Print instructions with annotations. */
- for (i = 0; i < num_inst; i++) {
- struct si_shader_inst *inst = &instructions[i];
-
- fprintf(f, "%s\n", inst->text);
-
- /* Print which waves execute the instruction right now. */
- while (num_waves && start_addr + inst->offset == waves->pc) {
- fprintf(f,
- " " COLOR_GREEN "^ SE%u SH%u CU%u "
- "SIMD%u WAVE%u EXEC=%016"PRIx64 " ",
- waves->se, waves->sh, waves->cu, waves->simd,
- waves->wave, waves->exec);
-
- if (inst->size == 4) {
- fprintf(f, "INST32=%08X" COLOR_RESET "\n",
- waves->inst_dw0);
- } else {
- fprintf(f, "INST64=%08X %08X" COLOR_RESET "\n",
- waves->inst_dw0, waves->inst_dw1);
- }
-
- waves->matched = true;
- waves = &waves[1];
- num_waves--;
- }
- }
-
- fprintf(f, "\n\n");
- free(instructions);
+ if (!shader)
+ return;
+
+ struct si_screen *screen = shader->selector->screen;
+ gl_shader_stage stage = shader->selector->info.stage;
+ uint64_t start_addr = shader->bo->gpu_address;
+ uint64_t end_addr = start_addr + shader->bo->b.b.width0;
+ unsigned i;
+
+ /* See if any wave executes the shader. */
+ for (i = 0; i < num_waves; i++) {
+ if (start_addr <= waves[i].pc && waves[i].pc <= end_addr)
+ break;
+ }
+ if (i == num_waves)
+ return; /* the shader is not being executed */
+
+ /* Remember the first found wave. The waves are sorted according to PC. */
+ waves = &waves[i];
+ num_waves -= i;
+
+ /* Get the list of instructions.
+ * Buffer size / 4 is the upper bound of the instruction count.
+ */
+ unsigned num_inst = 0;
+ uint64_t inst_addr = start_addr;
+ unsigned wave_size = si_get_shader_wave_size(shader);
+ struct ac_rtld_binary rtld_binaries[5] = {};
+ struct si_shader_inst *instructions =
+ calloc(shader->bo->b.b.width0 / 4, sizeof(struct si_shader_inst));
+
+ if (shader->prolog) {
+ si_add_split_disasm(screen, &rtld_binaries[0], &shader->prolog->binary, &inst_addr, &num_inst,
+ instructions, stage, wave_size);
+ }
+ if (shader->previous_stage) {
+ si_add_split_disasm(screen, &rtld_binaries[1], &shader->previous_stage->binary, &inst_addr,
+ &num_inst, instructions, stage, wave_size);
+ }
+ if (shader->prolog2) {
+ si_add_split_disasm(screen, &rtld_binaries[2], &shader->prolog2->binary, &inst_addr,
+ &num_inst, instructions, stage, wave_size);
+ }
+ si_add_split_disasm(screen, &rtld_binaries[3], &shader->binary, &inst_addr, &num_inst,
+ instructions, stage, wave_size);
+ if (shader->epilog) {
+ si_add_split_disasm(screen, &rtld_binaries[4], &shader->epilog->binary, &inst_addr, &num_inst,
+ instructions, stage, wave_size);
+ }
+
+ fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET "\n",
+ si_get_shader_name(shader));
+
+ /* Print instructions with annotations. */
+ for (i = 0; i < num_inst; i++) {
+ struct si_shader_inst *inst = &instructions[i];
+
+ fprintf(f, "%.*s [PC=0x%" PRIx64 ", size=%u]\n", inst->textlen, inst->text, inst->addr,
+ inst->size);
+
+ /* Print which waves execute the instruction right now. */
+ while (num_waves && inst->addr == waves->pc) {
+ fprintf(f,
+ " " COLOR_GREEN "^ SE%u SH%u CU%u "
+ "SIMD%u WAVE%u EXEC=%016" PRIx64 " ",
+ waves->se, waves->sh, waves->cu, waves->simd, waves->wave, waves->exec);
+
+ if (inst->size == 4) {
+ fprintf(f, "INST32=%08X" COLOR_RESET "\n", waves->inst_dw0);
+ } else {
+ fprintf(f, "INST64=%08X %08X" COLOR_RESET "\n", waves->inst_dw0, waves->inst_dw1);
+ }
+
+ waves->matched = true;
+ waves = &waves[1];
+ num_waves--;
+ }
+ }
+
+ fprintf(f, "\n\n");
+ free(instructions);
+ for (unsigned i = 0; i < ARRAY_SIZE(rtld_binaries); ++i)
+ ac_rtld_close(&rtld_binaries[i]);