From db5105b4b35e064f3934154b45de15422a1bdb0a Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 29 Jun 2015 10:21:08 -0400 Subject: [PATCH] freedreno/ir3: add ir3_shader_disasm() Split out most of dump_info() from ir3_cmdline compiler into a function that can be used both by cmdline compiler and also for the disasm debug option. This way, for FD_MESA_DEBUG=disasm we also get to see intput/ output registers, etc. Signed-off-by: Rob Clark --- .../drivers/freedreno/ir3/ir3_cmdline.c | 116 +--------------- .../drivers/freedreno/ir3/ir3_shader.c | 127 +++++++++++++++++- .../drivers/freedreno/ir3/ir3_shader.h | 1 + 3 files changed, 124 insertions(+), 120 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index ad9d2719d59..2b89fb442b4 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -43,127 +43,15 @@ #include "instr-a3xx.h" #include "ir3.h" -static void dump_reg(const char *name, uint32_t r) -{ - if (r != regid(63,0)) - debug_printf("; %s: r%d.%c\n", name, r >> 2, "xyzw"[r & 0x3]); -} - -static void dump_semantic(struct ir3_shader_variant *so, - unsigned sem, const char *name) -{ - uint32_t regid; - regid = ir3_find_output_regid(so, ir3_semantic_name(sem, 0)); - dump_reg(name, regid); -} - static void dump_info(struct ir3_shader_variant *so, const char *str) { uint32_t *bin; const char *type = (so->type == SHADER_VERTEX) ? "VERT" : "FRAG"; - - // for debug, dump some before/after info: // TODO make gpu_id configurable on cmdline bin = ir3_shader_assemble(so, 320); - if (fd_mesa_debug & FD_DBG_DISASM) { - struct ir3 *ir = so->ir; - struct ir3_register *reg; - uint8_t regid; - unsigned i; - - debug_printf("; %s: %s\n", type, str); - - for (i = 0; i < ir->ninputs; i++) { - if (!ir->inputs[i]) { - debug_printf("; in%d unused\n", i); - continue; - } - reg = ir->inputs[i]->regs[0]; - regid = reg->num; - debug_printf("@in(%sr%d.%c)\tin%d\n", - (reg->flags & IR3_REG_HALF) ? "h" : "", - (regid >> 2), "xyzw"[regid & 0x3], i); - } - - for (i = 0; i < ir->noutputs; i++) { - if (!ir->outputs[i]) { - debug_printf("; out%d unused\n", i); - continue; - } - /* kill shows up as a virtual output.. skip it! */ - if (is_kill(ir->outputs[i])) - continue; - reg = ir->outputs[i]->regs[0]; - regid = reg->num; - debug_printf("@out(%sr%d.%c)\tout%d\n", - (reg->flags & IR3_REG_HALF) ? "h" : "", - (regid >> 2), "xyzw"[regid & 0x3], i); - } - - for (i = 0; i < so->immediates_count; i++) { - debug_printf("@const(c%d.x)\t", so->first_immediate + i); - debug_printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - so->immediates[i].val[0], - so->immediates[i].val[1], - so->immediates[i].val[2], - so->immediates[i].val[3]); - } - - disasm_a3xx(bin, so->info.sizedwords, 0, so->type); - - debug_printf("; %s: outputs:", type); - for (i = 0; i < so->outputs_count; i++) { - uint8_t regid = so->outputs[i].regid; - ir3_semantic sem = so->outputs[i].semantic; - debug_printf(" r%d.%c (%u:%u)", - (regid >> 2), "xyzw"[regid & 0x3], - sem2name(sem), sem2idx(sem)); - } - debug_printf("\n"); - debug_printf("; %s: inputs:", type); - for (i = 0; i < so->inputs_count; i++) { - uint8_t regid = so->inputs[i].regid; - ir3_semantic sem = so->inputs[i].semantic; - debug_printf(" r%d.%c (%u:%u,cm=%x,il=%u,b=%u)", - (regid >> 2), "xyzw"[regid & 0x3], - sem2name(sem), sem2idx(sem), - so->inputs[i].compmask, - so->inputs[i].inloc, - so->inputs[i].bary); - } - debug_printf("\n"); - } - - /* print generic shader info: */ - debug_printf("; %s: %u instructions, %d half, %d full\n", type, - so->info.instrs_count, - so->info.max_half_reg + 1, - so->info.max_reg + 1); - - /* print shader type specific info: */ - switch (so->type) { - case SHADER_VERTEX: - dump_semantic(so, TGSI_SEMANTIC_POSITION, "pos"); - dump_semantic(so, TGSI_SEMANTIC_PSIZE, "psize"); - break; - case SHADER_FRAGMENT: - dump_reg("pos (bary)", so->pos_regid); - dump_semantic(so, TGSI_SEMANTIC_POSITION, "posz"); - dump_semantic(so, TGSI_SEMANTIC_COLOR, "color"); - /* these two are hard-coded since we don't know how to - * program them to anything but all 0's... - */ - if (so->frag_coord) - debug_printf("; fragcoord: r0.x\n"); - if (so->frag_face) - debug_printf("; fragface: hr0.x\n"); - break; - case SHADER_COMPUTE: - break; - } + debug_printf("; %s: %s\n", type, str); + ir3_shader_disasm(so, bin); free(bin); - - debug_printf("\n"); } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index c22b7f8d169..bfcc2ca8a53 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -140,6 +140,13 @@ assemble_variant(struct ir3_shader_variant *v) memcpy(fd_bo_map(v->bo), bin, sz); + if (fd_mesa_debug & FD_DBG_DISASM) { + struct ir3_shader_key key = v->key; + DBG("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type, + key.binning_pass, key.color_two_side, key.half_precision); + ir3_shader_disasm(v, bin); + } + free(bin); /* no need to keep the ir around beyond this point: */ @@ -179,12 +186,6 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key) goto fail; } - if (fd_mesa_debug & FD_DBG_DISASM) { - DBG("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type, - key.binning_pass, key.color_two_side, key.half_precision); - disasm_a3xx(fd_bo_map(v->bo), v->info.sizedwords, 0, v->type); - } - return v; fail: @@ -262,3 +263,117 @@ ir3_shader_create(struct pipe_context *pctx, const struct tgsi_token *tokens, shader->tokens = tgsi_dup_tokens(tokens); return shader; } + +static void dump_reg(const char *name, uint32_t r) +{ + if (r != regid(63,0)) + debug_printf("; %s: r%d.%c\n", name, r >> 2, "xyzw"[r & 0x3]); +} + +static void dump_semantic(struct ir3_shader_variant *so, + unsigned sem, const char *name) +{ + uint32_t regid; + regid = ir3_find_output_regid(so, ir3_semantic_name(sem, 0)); + dump_reg(name, regid); +} + +void +ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin) +{ + struct ir3 *ir = so->ir; + struct ir3_register *reg; + const char *type = (so->type == SHADER_VERTEX) ? "VERT" : "FRAG"; + uint8_t regid; + unsigned i; + + for (i = 0; i < ir->ninputs; i++) { + if (!ir->inputs[i]) { + debug_printf("; in%d unused\n", i); + continue; + } + reg = ir->inputs[i]->regs[0]; + regid = reg->num; + debug_printf("@in(%sr%d.%c)\tin%d\n", + (reg->flags & IR3_REG_HALF) ? "h" : "", + (regid >> 2), "xyzw"[regid & 0x3], i); + } + + for (i = 0; i < ir->noutputs; i++) { + if (!ir->outputs[i]) { + debug_printf("; out%d unused\n", i); + continue; + } + /* kill shows up as a virtual output.. skip it! */ + if (is_kill(ir->outputs[i])) + continue; + reg = ir->outputs[i]->regs[0]; + regid = reg->num; + debug_printf("@out(%sr%d.%c)\tout%d\n", + (reg->flags & IR3_REG_HALF) ? "h" : "", + (regid >> 2), "xyzw"[regid & 0x3], i); + } + + for (i = 0; i < so->immediates_count; i++) { + debug_printf("@const(c%d.x)\t", so->first_immediate + i); + debug_printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + so->immediates[i].val[0], + so->immediates[i].val[1], + so->immediates[i].val[2], + so->immediates[i].val[3]); + } + + disasm_a3xx(bin, so->info.sizedwords, 0, so->type); + + debug_printf("; %s: outputs:", type); + for (i = 0; i < so->outputs_count; i++) { + uint8_t regid = so->outputs[i].regid; + ir3_semantic sem = so->outputs[i].semantic; + debug_printf(" r%d.%c (%u:%u)", + (regid >> 2), "xyzw"[regid & 0x3], + sem2name(sem), sem2idx(sem)); + } + debug_printf("\n"); + debug_printf("; %s: inputs:", type); + for (i = 0; i < so->inputs_count; i++) { + uint8_t regid = so->inputs[i].regid; + ir3_semantic sem = so->inputs[i].semantic; + debug_printf(" r%d.%c (%u:%u,cm=%x,il=%u,b=%u)", + (regid >> 2), "xyzw"[regid & 0x3], + sem2name(sem), sem2idx(sem), + so->inputs[i].compmask, + so->inputs[i].inloc, + so->inputs[i].bary); + } + debug_printf("\n"); + + /* print generic shader info: */ + debug_printf("; %s: %u instructions, %d half, %d full\n", type, + so->info.instrs_count, + so->info.max_half_reg + 1, + so->info.max_reg + 1); + + /* print shader type specific info: */ + switch (so->type) { + case SHADER_VERTEX: + dump_semantic(so, TGSI_SEMANTIC_POSITION, "pos"); + dump_semantic(so, TGSI_SEMANTIC_PSIZE, "psize"); + break; + case SHADER_FRAGMENT: + dump_reg("pos (bary)", so->pos_regid); + dump_semantic(so, TGSI_SEMANTIC_POSITION, "posz"); + dump_semantic(so, TGSI_SEMANTIC_COLOR, "color"); + /* these two are hard-coded since we don't know how to + * program them to anything but all 0's... + */ + if (so->frag_coord) + debug_printf("; fragcoord: r0.x\n"); + if (so->frag_face) + debug_printf("; fragface: hr0.x\n"); + break; + case SHADER_COMPUTE: + break; + } + + debug_printf("\n"); +} diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h index 9f1b0769180..3cf3167e1cc 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h @@ -212,6 +212,7 @@ struct ir3_shader * ir3_shader_create(struct pipe_context *pctx, void ir3_shader_destroy(struct ir3_shader *shader); struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key); +void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin); /* * Helper/util: -- 2.30.2