mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
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 <robclark@freedesktop.org>
This commit is contained in:
parent
3244195f48
commit
db5105b4b3
3 changed files with 124 additions and 120 deletions
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue