static const char* opcode_string(GLuint opcode) { if (opcode == OPCODE_REPL_ALPHA) return "SOP"; else return _mesa_opcode_string(opcode); }
/** * Print a single NVIDIA vertex program instruction. */ void _mesa_print_nv_vertex_instruction(const struct prog_instruction *inst) { GLuint i, n; switch (inst->Opcode) { case OPCODE_MOV: case OPCODE_LIT: case OPCODE_RCP: case OPCODE_RSQ: case OPCODE_EXP: case OPCODE_LOG: case OPCODE_RCC: case OPCODE_ABS: case OPCODE_MUL: case OPCODE_ADD: case OPCODE_DP3: case OPCODE_DP4: case OPCODE_DST: case OPCODE_MIN: case OPCODE_MAX: case OPCODE_SLT: case OPCODE_SGE: case OPCODE_DPH: case OPCODE_SUB: case OPCODE_MAD: _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode)); PrintDstReg(&inst->DstReg); _mesa_printf(", "); n = _mesa_num_inst_src_regs(inst->Opcode); for (i = 0; i < n; i++) { PrintSrcReg(&inst->SrcReg[i]); if (i + 1 < n) _mesa_printf(", "); } _mesa_printf(";\n"); break; case OPCODE_ARL: _mesa_printf("ARL A0.x, "); PrintSrcReg(&inst->SrcReg[0]); _mesa_printf(";\n"); break; case OPCODE_PRINT: _mesa_printf("PRINT '%s'", inst->Data); if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { _mesa_printf(", "); PrintSrcReg(&inst->SrcReg[0]); _mesa_printf(";\n"); } else { _mesa_printf("\n"); } break; case OPCODE_END: _mesa_printf("END\n"); break; default: _mesa_printf("BAD INSTRUCTION\n"); } }
/** * Print a single vertex/fragment program instruction. */ GLint _mesa_fprint_instruction_opt(FILE *f, const struct prog_instruction *inst, GLint indent, gl_prog_print_mode mode, const struct gl_program *prog) { GLint i; if (inst->Opcode == OPCODE_ELSE || inst->Opcode == OPCODE_ENDIF || inst->Opcode == OPCODE_ENDLOOP || inst->Opcode == OPCODE_ENDSUB) { indent -= 3; } for (i = 0; i < indent; i++) { fprintf(f, " "); } switch (inst->Opcode) { case OPCODE_SWZ: fprintf(f, "SWZ"); if (inst->Saturate) fprintf(f, "_SAT"); fprintf(f, " "); fprint_dst_reg(f, &inst->DstReg, mode, prog); fprintf(f, ", %s[%d], %s", _mesa_register_file_name((gl_register_file) inst->SrcReg[0].File), inst->SrcReg[0].Index, _mesa_swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].Negate, GL_TRUE)); fprint_comment(f, inst); break; case OPCODE_TEX: case OPCODE_TXP: case OPCODE_TXL: case OPCODE_TXB: case OPCODE_TXD: fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); if (inst->Saturate) fprintf(f, "_SAT"); fprintf(f, " "); fprint_dst_reg(f, &inst->DstReg, mode, prog); fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); if (inst->Opcode == OPCODE_TXD) { fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[1], mode, prog); fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[2], mode, prog); } fprintf(f, ", texture[%d], ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { case TEXTURE_1D_INDEX: fprintf(f, "1D"); break; case TEXTURE_2D_INDEX: fprintf(f, "2D"); break; case TEXTURE_3D_INDEX: fprintf(f, "3D"); break; case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break; case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break; case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break; case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break; default: ; } if (inst->TexShadow) fprintf(f, " SHADOW"); fprint_comment(f, inst); break; case OPCODE_KIL: fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); fprintf(f, " "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); fprint_comment(f, inst); break; case OPCODE_ARL: fprintf(f, "ARL "); fprint_dst_reg(f, &inst->DstReg, mode, prog); fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); fprint_comment(f, inst); break; case OPCODE_IF: fprintf(f, "IF "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); fprintf(f, "; "); fprintf(f, " # (if false, goto %d)", inst->BranchTarget); fprint_comment(f, inst); return indent + 3; case OPCODE_ELSE: fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: fprintf(f, "ENDIF;\n"); break; case OPCODE_BGNLOOP: fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: case OPCODE_CONT: fprintf(f, "%s; # (goto %d)", _mesa_opcode_string(inst->Opcode), inst->BranchTarget); fprint_comment(f, inst); break; case OPCODE_BGNSUB: fprintf(f, "BGNSUB"); fprint_comment(f, inst); return indent + 3; case OPCODE_ENDSUB: if (mode == PROG_PRINT_DEBUG) { fprintf(f, "ENDSUB"); fprint_comment(f, inst); } break; case OPCODE_CAL: fprintf(f, "CAL %u", inst->BranchTarget); fprint_comment(f, inst); break; case OPCODE_RET: fprintf(f, "RET"); fprint_comment(f, inst); break; case OPCODE_END: fprintf(f, "END\n"); break; case OPCODE_NOP: if (mode == PROG_PRINT_DEBUG) { fprintf(f, "NOP"); fprint_comment(f, inst); } else if (inst->Comment) { /* ARB/NV extensions don't have NOP instruction */ fprintf(f, "# %s\n", inst->Comment); } break; /* XXX may need other special-case instructions */ default: if (inst->Opcode < MAX_OPCODE) { /* typical alu instruction */ _mesa_fprint_alu_instruction(f, inst, _mesa_opcode_string(inst->Opcode), _mesa_num_inst_src_regs(inst->Opcode), mode, prog); } else { _mesa_fprint_alu_instruction(f, inst, _mesa_opcode_string(inst->Opcode), 3/*_mesa_num_inst_src_regs(inst->Opcode)*/, mode, prog); } break; } return indent; }
/** * Print a single vertex/fragment program instruction. */ static GLint _mesa_fprint_instruction_opt(FILE *f, const struct prog_instruction *inst, GLint indent, gl_prog_print_mode mode, const struct gl_program *prog) { GLint i; if (inst->Opcode == OPCODE_ELSE || inst->Opcode == OPCODE_ENDIF || inst->Opcode == OPCODE_ENDLOOP || inst->Opcode == OPCODE_ENDSUB) { indent -= 3; } for (i = 0; i < indent; i++) { _mesa_fprintf(f, " "); } switch (inst->Opcode) { case OPCODE_PRINT: _mesa_fprintf(f, "PRINT '%s'", inst->Data); if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { _mesa_fprintf(f, ", "); _mesa_fprintf(f, "%s[%d]%s", file_string((gl_register_file) inst->SrcReg[0].File, mode), inst->SrcReg[0].Index, _mesa_swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].Negate, GL_FALSE)); } if (inst->Comment) _mesa_fprintf(f, " # %s", inst->Comment); fprint_comment(f, inst); break; case OPCODE_SWZ: _mesa_fprintf(f, "SWZ"); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_fprintf(f, "_SAT"); _mesa_fprintf(f, " "); fprint_dst_reg(f, &inst->DstReg, mode, prog); _mesa_fprintf(f, ", %s[%d], %s", file_string((gl_register_file) inst->SrcReg[0].File, mode), inst->SrcReg[0].Index, _mesa_swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].Negate, GL_TRUE)); fprint_comment(f, inst); break; case OPCODE_TEX: case OPCODE_TXP: case OPCODE_TXL: case OPCODE_TXB: _mesa_fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_fprintf(f, "_SAT"); _mesa_fprintf(f, " "); fprint_dst_reg(f, &inst->DstReg, mode, prog); _mesa_fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); _mesa_fprintf(f, ", texture[%d], ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { case TEXTURE_1D_INDEX: _mesa_fprintf(f, "1D"); break; case TEXTURE_2D_INDEX: _mesa_fprintf(f, "2D"); break; case TEXTURE_3D_INDEX: _mesa_fprintf(f, "3D"); break; case TEXTURE_CUBE_INDEX: _mesa_fprintf(f, "CUBE"); break; case TEXTURE_RECT_INDEX: _mesa_fprintf(f, "RECT"); break; default: ; } if (inst->TexShadow) _mesa_fprintf(f, " SHADOW"); fprint_comment(f, inst); break; case OPCODE_KIL: _mesa_fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); _mesa_fprintf(f, " "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); fprint_comment(f, inst); break; case OPCODE_KIL_NV: _mesa_fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); _mesa_fprintf(f, " "); _mesa_fprintf(f, "%s.%s", _mesa_condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, GL_FALSE, GL_FALSE)); fprint_comment(f, inst); break; case OPCODE_ARL: _mesa_fprintf(f, "ARL "); fprint_dst_reg(f, &inst->DstReg, mode, prog); _mesa_fprintf(f, ", "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); fprint_comment(f, inst); break; case OPCODE_BRA: _mesa_fprintf(f, "BRA %d (%s%s)", inst->BranchTarget, _mesa_condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); fprint_comment(f, inst); break; case OPCODE_IF: if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { /* Use ordinary register */ _mesa_fprintf(f, "IF "); fprint_src_reg(f, &inst->SrcReg[0], mode, prog); _mesa_fprintf(f, "; "); } else { /* Use cond codes */ _mesa_fprintf(f, "IF (%s%s);", _mesa_condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); } _mesa_fprintf(f, " # (if false, goto %d)", inst->BranchTarget); fprint_comment(f, inst); return indent + 3; case OPCODE_ELSE: _mesa_fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: _mesa_fprintf(f, "ENDIF;\n"); break; case OPCODE_BGNLOOP: _mesa_fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: _mesa_fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: case OPCODE_CONT: _mesa_fprintf(f, "%s (%s%s); # (goto %d)", _mesa_opcode_string(inst->Opcode), _mesa_condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); fprint_comment(f, inst); break; case OPCODE_BGNSUB: if (mode == PROG_PRINT_NV) { _mesa_fprintf(f, "%s:\n", inst->Comment); /* comment is label */ return indent; } else { _mesa_fprintf(f, "BGNSUB"); fprint_comment(f, inst); return indent + 3; } case OPCODE_ENDSUB: if (mode == PROG_PRINT_DEBUG) { _mesa_fprintf(f, "ENDSUB"); fprint_comment(f, inst); } break; case OPCODE_CAL: if (mode == PROG_PRINT_NV) { _mesa_fprintf(f, "CAL %s; # (goto %d)\n", inst->Comment, inst->BranchTarget); } else { _mesa_fprintf(f, "CAL %u", inst->BranchTarget); fprint_comment(f, inst); } break; case OPCODE_RET: _mesa_fprintf(f, "RET (%s%s)", _mesa_condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); fprint_comment(f, inst); break; case OPCODE_END: _mesa_fprintf(f, "END\n"); break; case OPCODE_NOP: if (mode == PROG_PRINT_DEBUG) { _mesa_fprintf(f, "NOP"); fprint_comment(f, inst); } else if (inst->Comment) { /* ARB/NV extensions don't have NOP instruction */ _mesa_fprintf(f, "# %s\n", inst->Comment); } break; /* XXX may need other special-case instructions */ default: if (inst->Opcode < MAX_OPCODE) { /* typical alu instruction */ fprint_alu_instruction(f, inst, _mesa_opcode_string(inst->Opcode), _mesa_num_inst_src_regs(inst->Opcode), mode, prog); } else { _mesa_fprintf(f, "Other opcode %d\n", inst->Opcode); } break; } return indent; }
/* Emit the fragment program instructions here. */ void brw_wm_emit( struct brw_wm_compile *c ) { struct brw_compile *p = &c->func; struct intel_context *intel = &p->brw->intel; GLuint insn; brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); if (intel->gen >= 6) brw_set_acc_write_control(p, 1); /* Check if any of the payload regs need to be spilled: */ spill_values(c, c->payload.depth, 4); spill_values(c, c->creg, c->nr_creg); spill_values(c, c->payload.input_interp, FRAG_ATTRIB_MAX); for (insn = 0; insn < c->nr_insns; insn++) { struct brw_wm_instruction *inst = &c->instruction[insn]; struct brw_reg args[3][4], dst[4]; GLuint i, dst_flags; /* Get argument regs: */ for (i = 0; i < 3; i++) get_argument_regs(c, inst->src[i], args[i]); /* Get dest regs: */ for (i = 0; i < 4; i++) if (inst->dst[i]) dst[i] = inst->dst[i]->hw_reg; else dst[i] = brw_null_reg(); /* Flags */ dst_flags = inst->writemask; if (inst->saturate) dst_flags |= SATURATE; switch (inst->opcode) { /* Generated instructions for calculating triangle interpolants: */ case WM_PIXELXY: emit_pixel_xy(c, dst, dst_flags); break; case WM_DELTAXY: emit_delta_xy(p, dst, dst_flags, args[0]); break; case WM_WPOSXY: emit_wpos_xy(c, dst, dst_flags, args[0]); break; case WM_PIXELW: emit_pixel_w(c, dst, dst_flags, args[0], args[1]); break; case WM_LINTERP: emit_linterp(p, dst, dst_flags, args[0], args[1]); break; case WM_PINTERP: emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]); break; case WM_CINTERP: emit_cinterp(p, dst, dst_flags, args[0]); break; case WM_FB_WRITE: emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot); break; case WM_FRONTFACING: emit_frontfacing(p, dst, dst_flags); break; /* Straightforward arithmetic: */ case OPCODE_ADD: emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]); break; case OPCODE_FRC: emit_alu1(p, brw_FRC, dst, dst_flags, args[0]); break; case OPCODE_FLR: emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]); break; case OPCODE_DDX: emit_ddxy(p, dst, dst_flags, true, args[0]); break; case OPCODE_DDY: emit_ddxy(p, dst, dst_flags, false, args[0]); break; case OPCODE_DP2: emit_dp2(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DP3: emit_dp3(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DP4: emit_dp4(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DPH: emit_dph(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_TRUNC: for (i = 0; i < 4; i++) { if (dst_flags & (1<<i)) { brw_RNDZ(p, dst[i], args[0][i]); } } break; case OPCODE_LRP: emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MAD: emit_mad(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MOV: case OPCODE_SWZ: emit_alu1(p, brw_MOV, dst, dst_flags, args[0]); break; case OPCODE_MUL: emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]); break; case OPCODE_XPD: emit_xpd(p, dst, dst_flags, args[0], args[1]); break; /* Higher math functions: */ case OPCODE_RCP: emit_math1(c, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]); break; case OPCODE_RSQ: emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]); break; case OPCODE_SIN: emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]); break; case OPCODE_COS: emit_math1(c, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]); break; case OPCODE_EX2: emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]); break; case OPCODE_LG2: emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]); break; case OPCODE_SCS: /* There is an scs math function, but it would need some * fixup for 16-element execution. */ if (dst_flags & WRITEMASK_X) emit_math1(c, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|WRITEMASK_X, args[0]); if (dst_flags & WRITEMASK_Y) emit_math1(c, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|WRITEMASK_X, args[0]); break; case OPCODE_POW: emit_math2(c, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]); break; /* Comparisons: */ case OPCODE_CMP: emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MAX: emit_max(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_MIN: emit_min(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SLT: emit_slt(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SLE: emit_sle(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SGT: emit_sgt(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SGE: emit_sge(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SEQ: emit_seq(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SNE: emit_sne(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SSG: emit_sign(p, dst, dst_flags, args[0]); break; case OPCODE_LIT: emit_lit(c, dst, dst_flags, args[0]); break; /* Texturing operations: */ case OPCODE_TEX: emit_tex(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg, inst->tex_idx, inst->tex_unit, inst->tex_shadow); break; case OPCODE_TXB: emit_txb(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg, inst->tex_idx, inst->tex_unit); break; case OPCODE_KIL: emit_kil(c, args[0]); break; default: printf("Unsupported opcode %i (%s) in fragment shader\n", inst->opcode, inst->opcode < MAX_OPCODE ? _mesa_opcode_string(inst->opcode) : "unknown"); } for (i = 0; i < 4; i++) if (inst->dst[i] && inst->dst[i]->spill_slot) emit_spill(c, inst->dst[i]->hw_reg, inst->dst[i]->spill_slot); } /* Only properly tested on ILK */ if (p->brw->intel.gen == 5) { brw_remove_duplicate_mrf_moves(p); if (c->dispatch_width == 16) brw_remove_grf_to_mrf_moves(p); } if (unlikely(INTEL_DEBUG & DEBUG_WM)) { int i; printf("wm-native:\n"); for (i = 0; i < p->nr_insn; i++) brw_disasm(stdout, &p->store[i], p->brw->intel.gen); printf("\n"); } }
void brw_wm_print_insn( struct brw_wm_compile *c, struct brw_wm_instruction *inst ) { GLuint i, arg; GLuint nr_args = brw_wm_nr_args(inst->opcode); printf("["); for (i = 0; i < 4; i++) { if (inst->dst[i]) { brw_wm_print_value(c, inst->dst[i]); if (inst->dst[i]->spill_slot) printf("/SPILL(%x)",inst->dst[i]->spill_slot); } else printf("#"); if (i < 3) printf(","); } printf("]"); if (inst->writemask != WRITEMASK_XYZW) printf(".%s%s%s%s", GET_BIT(inst->writemask, 0) ? "x" : "", GET_BIT(inst->writemask, 1) ? "y" : "", GET_BIT(inst->writemask, 2) ? "z" : "", GET_BIT(inst->writemask, 3) ? "w" : ""); switch (inst->opcode) { case WM_PIXELXY: printf(" = PIXELXY"); break; case WM_DELTAXY: printf(" = DELTAXY"); break; case WM_PIXELW: printf(" = PIXELW"); break; case WM_WPOSXY: printf(" = WPOSXY"); break; case WM_PINTERP: printf(" = PINTERP"); break; case WM_LINTERP: printf(" = LINTERP"); break; case WM_CINTERP: printf(" = CINTERP"); break; case WM_FB_WRITE: printf(" = FB_WRITE"); break; case WM_FRONTFACING: printf(" = FRONTFACING"); break; default: printf(" = %s", _mesa_opcode_string(inst->opcode)); break; } if (inst->saturate) printf("_SAT"); for (arg = 0; arg < nr_args; arg++) { printf(" ["); for (i = 0; i < 4; i++) { if (inst->src[arg][i]) { brw_wm_print_ref(c, inst->src[arg][i]); } else printf("%%"); if (i < 3) printf(","); else printf("]"); } } printf("\n"); }