static struct fd3_shader_stateobj * create_shader(struct pipe_context *pctx, const struct pipe_shader_state *cso, enum shader_t type) { struct fd3_shader_stateobj *so = CALLOC_STRUCT(fd3_shader_stateobj); int ret; if (!so) return NULL; so->type = type; if (fd_mesa_debug & FD_DBG_DISASM) { DBG("dump tgsi: type=%d", so->type); tgsi_dump(cso->tokens, 0); } if (type == SHADER_FRAGMENT) { /* we seem to get wrong colors (maybe swap/endianess or hw issue?) * with full precision color reg. And blob driver only seems to * use half precision register for color output (that I can find * so far), even with highp precision. So for force half precision * for frag shader: */ so->half_precision = true; } ret = fd3_compile_shader(so, cso->tokens); if (ret) { debug_error("compile failed!"); goto fail; } assemble_shader(pctx, so); if (!so->bo) { debug_error("assemble failed!"); goto fail; } if (type == SHADER_VERTEX) fixup_vp_regfootprint(so); if (fd_mesa_debug & FD_DBG_DISASM) { DBG("disassemble: type=%d", so->type); disasm_a3xx(fd_bo_map(so->bo), so->info.sizedwords, 0, so->type); } return so; fail: delete_shader(so); return NULL; }
static void reg_disasm_gpuaddr(const char *name, uint32_t dword, int level) { void *buf; dword &= 0xfffffff0; if (summary) return; buf = hostptr(dword); if (buf) { uint32_t sizedwords = hostlen(dword) / 4; dump_hex(buf, 64, level+1); disasm_a3xx(buf, sizedwords, level+2, SHADER_FRAGMENT); } }
static void dump_shaders_a3xx(struct state *state) { int i, j; /* dump vertex shaders: */ for (i = 0; i < 2; i++) { int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; uint8_t *vs_hdr; struct constant *constants[32]; uint8_t *instrs = NULL; vs_hdr = next_sect(state, &hdr_size); /* seems like there are two cases, either: * 1) 152 byte header, * 2) zero or more 32 byte compiler const sections * 3) followed by shader instructions * or, if there are no compiler consts, this can be * all smashed in one large section */ if (hdr_size > 152) { instrs = &vs_hdr[152]; instrs_size = hdr_size - 152; hdr_size = 152; compact = 1; } else { while (1) { void *ptr = next_sect(state, §_size); if (sect_size != 32) { /* end of constants: */ instrs = ptr; instrs_size = sect_size; break; } constants[nconsts++] = ptr; } } printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## VS%d HEADER: (size %d)\n", i, hdr_size); dump_hex((void *)vs_hdr, hdr_size); for (j = 0; j < nconsts; j++) { printf("######## VS%d CONST: (size=%d)\n", i, sizeof(constants[i])); dump_constant(constants[j]); dump_hex((char *)constants[j], sizeof(constants[j])); } } printf("######## VS%d SHADER: (size=%d)\n", i, instrs_size); if (full_dump) { dump_hex(instrs, instrs_size); level = 1; } else { dump_short_summary(state, nconsts, constants); } if (!compact) { instrs += 32; instrs_size -= 32; } disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, SHADER_VERTEX); dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "vo3"); free(vs_hdr); } /* dump fragment shaders: */ for (i = 0; i < 1; i++) { int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; uint8_t *fs_hdr; struct constant *constants[32]; uint8_t *instrs = NULL; fs_hdr = next_sect(state, &hdr_size); /* two cases, similar to vertex shader, but magic # is 200.. */ if (hdr_size > 200) { instrs = &fs_hdr[200]; instrs_size = hdr_size - 200; hdr_size = 200; compact = 1; } else { while (1) { void *ptr = next_sect(state, §_size); if (sect_size != 32) { /* end of constants: */ instrs = ptr; instrs_size = sect_size; break; } constants[nconsts++] = ptr; } } printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## FS%d HEADER: (size %d)\n", i, hdr_size); dump_hex((void *)fs_hdr, hdr_size); for (j = 0; j < nconsts; j++) { printf("######## FS%d CONST: (size=%d)\n", i, sizeof(constants[i])); dump_constant(constants[j]); dump_hex((char *)constants[j], sizeof(constants[j])); } } printf("######## FS%d SHADER: (size=%d)\n", i, instrs_size); if (full_dump) { dump_hex(instrs, instrs_size); level = 1; } else { dump_short_summary(state, nconsts, constants); } if (!compact) { instrs += 32; instrs_size -= 32; } disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, SHADER_FRAGMENT); dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "fo3"); free(fs_hdr); } }
static void dump_info(struct ir3_shader_variant *so, const char *str) { struct ir3_info info; uint32_t *bin; const char *type = (so->type == SHADER_VERTEX) ? "VERT" : "FRAG"; // for debug, dump some before/after info: bin = ir3_assemble(so->ir, &info); if (fd_mesa_debug & FD_DBG_DISASM) { struct ir3_block *block = so->ir->block; unsigned i; debug_printf("; %s: %s\n", type, str); for (i = 0; i < block->ninputs; i++) { uint8_t regid; if (!block->inputs[i]) continue; regid = block->inputs[i]->regs[0]->num; debug_printf("@in(r%d.%c)\tin%d\n", (regid >> 2), "xyzw"[regid & 0x3], i); } for (i = 0; i < block->noutputs; i++) { uint8_t regid; if (!block->outputs[i]) continue; /* kill shows up as a virtual output.. skip it! */ if (is_kill(block->outputs[i])) continue; regid = block->outputs[i]->regs[0]->num; debug_printf("@out(r%d.%c)\tout%d\n", (regid >> 2), "xyzw"[regid & 0x3], i); } disasm_a3xx(bin, 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"); } debug_printf("; %s: %u instructions, %d half, %d full\n\n", type, info.instrs_count, info.max_half_reg + 1, info.max_reg + 1); free(bin); }