t_vb_arbprogram.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,571 行 · 第 1/3 页
C
1,571 行
if (mask&0x2) _mesa_printf("y"); if (mask&0x4) _mesa_printf("z"); if (mask&0x8) _mesa_printf("w");}static void print_reg( GLuint file, GLuint reg ){ static const char *reg_file[] = { "REG", "LOCAL_PARAM", "ENV_PARAM", "STATE_VAR", }; if (file == 0) { if (reg == REG_RES) _mesa_printf("RES"); else if (reg >= REG_ARG0 && reg <= REG_ARG1) _mesa_printf("ARG%d", reg - REG_ARG0); else if (reg >= REG_TMP0 && reg <= REG_TMP11) _mesa_printf("TMP%d", reg - REG_TMP0); else if (reg >= REG_IN0 && reg <= REG_IN31) _mesa_printf("IN%d", reg - REG_IN0); else if (reg >= REG_OUT0 && reg <= REG_OUT14) _mesa_printf("OUT%d", reg - REG_OUT0); else if (reg == REG_ADDR) _mesa_printf("ADDR"); else if (reg == REG_ID) _mesa_printf("ID"); else _mesa_printf("REG%d", reg); } else _mesa_printf("%s:%d", reg_file[file], reg);}static void print_RSW( union instruction op ){ GLuint swz = op.rsw.swz; GLuint neg = op.rsw.neg; GLuint i; _mesa_printf("RSW "); print_reg(0, op.rsw.dst); _mesa_printf(", "); print_reg(op.rsw.file0, op.rsw.idx0); _mesa_printf("."); for (i = 0; i < 4; i++, swz >>= 2) { const char *cswz = "xyzw"; if (neg & (1<<i)) _mesa_printf("-"); _mesa_printf("%c", cswz[swz&0x3]); } _mesa_printf("\n");}static void print_ALU( union instruction op ){ _mesa_printf("%s ", _mesa_opcode_string((enum prog_opcode) op.alu.opcode)); print_reg(0, op.alu.dst); _mesa_printf(", "); print_reg(op.alu.file0, op.alu.idx0); if (_mesa_num_inst_src_regs((enum prog_opcode) op.alu.opcode) > 1) { _mesa_printf(", "); print_reg(op.alu.file1, op.alu.idx1); } _mesa_printf("\n");}static void print_MSK( union instruction op ){ _mesa_printf("MSK "); print_reg(0, op.msk.dst); print_mask(op.msk.mask); _mesa_printf(", "); print_reg(op.msk.file, op.msk.idx); _mesa_printf("\n");}static void print_NOP( union instruction op ){}void_tnl_disassem_vba_insn( union instruction op ){ switch (op.alu.opcode) { case OPCODE_ABS: case OPCODE_ADD: case OPCODE_DP3: case OPCODE_DP4: case OPCODE_DPH: case OPCODE_DST: case OPCODE_EX2: case OPCODE_EXP: case OPCODE_FLR: case OPCODE_FRC: case OPCODE_LG2: case OPCODE_LIT: case OPCODE_LOG: case OPCODE_MAX: case OPCODE_MIN: case OPCODE_MOV: case OPCODE_MUL: case OPCODE_POW: case OPCODE_PRINT: case OPCODE_RCP: case OPCODE_RSQ: case OPCODE_SGE: case OPCODE_SLT: case OPCODE_SUB: case OPCODE_XPD: print_ALU(op); break; case OPCODE_ARA: case OPCODE_ARL: case OPCODE_ARL_NV: case OPCODE_ARR: case OPCODE_BRA: case OPCODE_CAL: case OPCODE_END: case OPCODE_MAD: case OPCODE_POPA: case OPCODE_PUSHA: case OPCODE_RCC: case OPCODE_RET: case OPCODE_SSG: case OPCODE_SWZ: print_NOP(op); break; case RSW: print_RSW(op); break; case MSK: print_MSK(op); break; case REL: print_ALU(op); break; default: _mesa_problem(NULL, "Bad opcode in _tnl_disassem_vba_insn()"); }}static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union instruction) = { do_ABS, do_ADD, do_NOP,/*ARA*/ do_NOP,/*ARL*/ do_NOP,/*ARL_NV*/ do_NOP,/*ARR*/ do_NOP,/*BRA*/ do_NOP,/*CAL*/ do_NOP,/*CMP*/ do_NOP,/*COS*/ do_NOP,/*DDX*/ do_NOP,/*DDY*/ do_DP3, do_DP4, do_DPH, do_DST, do_NOP, do_EX2, do_EXP, do_FLR, do_FRC, do_NOP,/*KIL*/ do_NOP,/*KIL_NV*/ do_LG2, do_LIT, do_LOG, do_NOP,/*LRP*/ do_NOP,/*MAD*/ do_MAX, do_MIN, do_MOV, do_MUL, do_NOP,/*PK2H*/ do_NOP,/*PK2US*/ do_NOP,/*PK4B*/ do_NOP,/*PK4UB*/ do_POW, do_NOP,/*POPA*/ do_PRT, do_NOP,/*PUSHA*/ do_NOP,/*RCC*/ do_RCP,/*RCP*/ do_NOP,/*RET*/ do_NOP,/*RFL*/ do_RSQ, do_NOP,/*SCS*/ do_NOP,/*SEQ*/ do_NOP,/*SFL*/ do_SGE, do_NOP,/*SGT*/ do_NOP,/*SIN*/ do_NOP,/*SLE*/ do_SLT, do_NOP,/*SNE*/ do_NOP,/*SSG*/ do_NOP,/*STR*/ do_SUB, do_RSW,/*SWZ*/ do_NOP,/*TEX*/ do_NOP,/*TXB*/ do_NOP,/*TXD*/ do_NOP,/*TXL*/ do_NOP,/*TXP*/ do_NOP,/*TXP_NV*/ do_NOP,/*UP2H*/ do_NOP,/*UP2US*/ do_NOP,/*UP4B*/ do_NOP,/*UP4UB*/ do_NOP,/*X2D*/ do_XPD, do_RSW, do_MSK, do_REL,};static union instruction *cvp_next_instruction( struct compilation *cp ){ union instruction *op = cp->csr++; _mesa_bzero(op, sizeof(*op)); return op;}static struct reg cvp_make_reg( GLuint file, GLuint idx ){ struct reg reg; reg.file = file; reg.idx = idx; return reg;}static struct reg cvp_emit_rel( struct compilation *cp, struct reg reg, struct reg tmpreg ){ union instruction *op = cvp_next_instruction(cp); op->alu.opcode = REL; op->alu.file0 = reg.file; op->alu.idx0 = reg.idx; op->alu.dst = tmpreg.idx; return tmpreg;}static struct reg cvp_load_reg( struct compilation *cp, GLuint file, GLuint index, GLuint rel, GLuint tmpidx ){ struct reg tmpreg = cvp_make_reg(FILE_REG, tmpidx); struct reg reg; switch (file) { case PROGRAM_TEMPORARY: return cvp_make_reg(FILE_REG, REG_TMP0 + index); case PROGRAM_INPUT: return cvp_make_reg(FILE_REG, REG_IN0 + index); case PROGRAM_OUTPUT: return cvp_make_reg(FILE_REG, REG_OUT0 + index); /* These two aren't populated by the parser? */ case PROGRAM_LOCAL_PARAM: reg = cvp_make_reg(FILE_LOCAL_PARAM, index); if (rel) return cvp_emit_rel(cp, reg, tmpreg); else return reg; case PROGRAM_ENV_PARAM: reg = cvp_make_reg(FILE_ENV_PARAM, index); if (rel) return cvp_emit_rel(cp, reg, tmpreg); else return reg; case PROGRAM_STATE_VAR: reg = cvp_make_reg(FILE_STATE_PARAM, index); if (rel) return cvp_emit_rel(cp, reg, tmpreg); else return reg; /* Invalid values: */ case PROGRAM_WRITE_ONLY: case PROGRAM_ADDRESS: default: _mesa_problem(NULL, "Invalid register file %d in cvp_load_reg()"); assert(0); return tmpreg; /* can't happen */ }}static struct reg cvp_emit_arg( struct compilation *cp, const struct prog_src_register *src, GLuint arg ){ struct reg reg = cvp_load_reg( cp, src->File, src->Index, src->RelAddr, arg ); union instruction rsw, noop; /* Emit any necessary swizzling. */ _mesa_bzero(&rsw, sizeof(rsw)); rsw.rsw.neg = src->NegateBase ? WRITEMASK_XYZW : 0; /* we're expecting 2-bit swizzles below... */#if 1 /* XXX THESE ASSERTIONS CURRENTLY FAIL DURING GLEAN TESTS! */ ASSERT(GET_SWZ(src->Swizzle, 0) < 4); ASSERT(GET_SWZ(src->Swizzle, 1) < 4); ASSERT(GET_SWZ(src->Swizzle, 2) < 4); ASSERT(GET_SWZ(src->Swizzle, 3) < 4);#endif rsw.rsw.swz = ((GET_SWZ(src->Swizzle, 0) << 0) | (GET_SWZ(src->Swizzle, 1) << 2) | (GET_SWZ(src->Swizzle, 2) << 4) | (GET_SWZ(src->Swizzle, 3) << 6)); _mesa_bzero(&noop, sizeof(noop)); noop.rsw.neg = 0; noop.rsw.swz = RSW_NOOP; if (_mesa_memcmp(&rsw, &noop, sizeof(rsw)) !=0) { union instruction *op = cvp_next_instruction(cp); struct reg rsw_reg = cvp_make_reg(FILE_REG, REG_ARG0 + arg); *op = rsw; op->rsw.opcode = RSW; op->rsw.file0 = reg.file; op->rsw.idx0 = reg.idx; op->rsw.dst = rsw_reg.idx; return rsw_reg; } else return reg;}static GLuint cvp_choose_result( struct compilation *cp, const struct prog_dst_register *dst, union instruction *fixup ){ GLuint mask = dst->WriteMask; GLuint idx; switch (dst->File) { case PROGRAM_TEMPORARY: idx = REG_TMP0 + dst->Index; break; case PROGRAM_OUTPUT: idx = REG_OUT0 + dst->Index; break; default: assert(0); return REG_RES; /* can't happen */ } /* Optimization: When writing (with a writemask) to an undefined * value for the first time, the writemask may be ignored. */ if (mask != WRITEMASK_XYZW && (cp->reg_active & (1 << idx))) { fixup->msk.opcode = MSK; fixup->msk.dst = idx; fixup->msk.file = FILE_REG; fixup->msk.idx = REG_RES; fixup->msk.mask = mask; cp->reg_active |= 1 << idx; return REG_RES; } else { _mesa_bzero(fixup, sizeof(*fixup)); cp->reg_active |= 1 << idx; return idx; }}static struct reg cvp_emit_rsw( struct compilation *cp, GLuint dst, struct reg src, GLuint neg, GLuint swz, GLboolean force){ struct reg retval; if (swz != RSW_NOOP || neg != 0) { union instruction *op = cvp_next_instruction(cp); op->rsw.opcode = RSW; op->rsw.dst = dst; op->rsw.file0 = src.file; op->rsw.idx0 = src.idx; op->rsw.neg = neg; op->rsw.swz = swz; retval.file = FILE_REG; retval.idx = dst; return retval; } else if (force) { /* Oops. Degenerate case: */ union instruction *op = cvp_next_instruction(cp); op->alu.opcode = OPCODE_MOV; op->alu.dst = dst; op->alu.file0 = src.file; op->alu.idx0 = src.idx; retval.file = FILE_REG; retval.idx = dst; return retval; } else { return src; }}static void cvp_emit_inst( struct compilation *cp, const struct prog_instruction *inst ){ union instruction *op; union instruction fixup; struct reg reg[3]; GLuint result, nr_args, i; /* Need to handle SWZ, ARL specially. */ switch (inst->Opcode) { /* Split into mul and add: */ case OPCODE_MAD: result = cvp_choose_result( cp, &inst->DstReg, &fixup ); for (i = 0; i < 3; i++) reg[i] = cvp_emit_arg( cp, &inst->SrcReg[i], REG_ARG0+i ); op = cvp_next_instruction(cp); op->alu.opcode = OPCODE_MUL; op->alu.file0 = reg[0].file; op->alu.idx0 = reg[0].idx; op->alu.file1 = reg[1].file; op->alu.idx1 = reg[1].idx; op->alu.dst = REG_ARG0; op = cvp_next_instruction(cp); op->alu.opcode = OPCODE_ADD; op->alu.file0 = FILE_REG; op->alu.idx0 = REG_ARG0; op->alu.file1 = reg[2].file; op->alu.idx1 = reg[2].idx; op->alu.dst = result; if (result == REG_RES) { op = cvp_next_instruction(cp); *op = fixup; } break; case OPCODE_ARL: reg[0] = cvp_emit_arg( cp, &inst->SrcReg[0], REG_ARG0 ); op = cvp_next_instruction(cp); op->alu.opcode = OPCODE_FLR; op->alu.dst = REG_ADDR; op->alu.file0 = reg[0].file; op->alu.idx0 = reg[0].idx; break; case OPCODE_SWZ: { GLuint swz0 = 0, swz1 = 0; GLuint neg0 = 0, neg1 = 0; GLuint mask = 0; /* Translate 3-bit-per-element swizzle into two 2-bit swizzles, * one from the source register the other from a constant * {0,0,0,1}. */ for (i = 0; i < 4; i++) { GLuint swzelt = GET_SWZ(inst->SrcReg[0].Swizzle, i); if (swzelt >= SWIZZLE_ZERO) { neg0 |= inst->SrcReg[0].NegateBase & (1<<i); if (swzelt == SWIZZLE_ONE) swz0 |= SWIZZLE_W << (i*2); else if (i < SWIZZLE_W) swz0 |= i << (i*2); } else { mask |= 1<<i; neg1 |= inst->SrcReg[0].NegateBase & (1<<i); swz1 |= swzelt << (i*2); } } result = cvp_choose_result( cp, &inst->DstReg, &fixup ); reg[0].file = FILE_REG; reg[0].idx = REG_ID; reg[1] = cvp_emit_arg( cp, &inst->SrcReg[0], REG_ARG0 ); if (mask == WRITEMASK_XYZW) { cvp_emit_rsw(cp, result, reg[0], neg0, swz0, GL_TRUE); } else if (mask == 0) { cvp_emit_rsw(cp, result, reg[1], neg1, swz1, GL_TRUE); } else { cvp_emit_rsw(cp, result, reg[0], neg0, swz0, GL_TRUE); reg[1] = cvp_emit_rsw(cp, REG_ARG0, reg[1], neg1, swz1, GL_FALSE); op = cvp_next_instruction(cp); op->msk.opcode = MSK; op->msk.dst = result; op->msk.file = reg[1].file; op->msk.idx = reg[1].idx; op->msk.mask = mask; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?