/** * Initial pass for fragment program code generation. * This function is used by both the GLSL and non-GLSL paths. */ void brw_wm_pass_fp( struct brw_wm_compile *c ) { struct brw_fragment_program *fp = c->fp; GLuint insn; if (INTEL_DEBUG & DEBUG_WM) { printf("pre-fp:\n"); _mesa_print_program(&fp->program.Base); printf("\n"); } c->pixel_xy = src_undef(); c->delta_xy = src_undef(); c->pixel_w = src_undef(); c->nr_fp_insns = 0; c->fp->tex_units_used = 0x0; /* Emit preamble instructions. This is where special instructions such as * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to * compute shader inputs from varying vars. */ for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; validate_src_regs(c, inst); validate_dst_regs(c, inst); } /* Loop over all instructions doing assorted simplifications and * transformations. */ for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; struct prog_instruction *out; /* Check for INPUT values, emit INTERP instructions where * necessary: */ switch (inst->Opcode) { case OPCODE_SWZ: out = emit_insn(c, inst); out->Opcode = OPCODE_MOV; break; case OPCODE_ABS: out = emit_insn(c, inst); out->Opcode = OPCODE_MOV; out->SrcReg[0].Negate = NEGATE_NONE; out->SrcReg[0].Abs = 1; break; case OPCODE_SUB: out = emit_insn(c, inst); out->Opcode = OPCODE_ADD; out->SrcReg[1].Negate ^= NEGATE_XYZW; break; case OPCODE_SCS: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask &= WRITEMASK_XY; break; case OPCODE_DST: precalc_dst(c, inst); break; case OPCODE_LIT: precalc_lit(c, inst); break; case OPCODE_TEX: precalc_tex(c, inst); break; case OPCODE_TXP: precalc_txp(c, inst); break; case OPCODE_TXB: out = emit_insn(c, inst); out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit]; assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT); break; case OPCODE_XPD: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask &= WRITEMASK_XYZ; break; case OPCODE_KIL: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask = 0; break; case OPCODE_END: emit_render_target_writes(c); break; case OPCODE_PRINT: break; default: if (brw_wm_is_scalar_result(inst->Opcode)) emit_scalar_insn(c, inst); else emit_insn(c, inst); break; } } if (INTEL_DEBUG & DEBUG_WM) { printf("pass_fp:\n"); print_insns( c->prog_instructions, c->nr_fp_insns ); printf("\n"); } }
void brw_wm_pass_fp( struct brw_wm_compile *c ) { struct brw_fragment_program *fp = c->fp; GLuint insn; if (INTEL_DEBUG & DEBUG_WM) { _mesa_printf("\n\n\npre-fp:\n"); _mesa_print_program(&fp->program.Base); _mesa_printf("\n"); } c->pixel_xy = src_undef(); c->delta_xy = src_undef(); c->pixel_w = src_undef(); c->nr_fp_insns = 0; /* Emit preamble instructions: */ for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; struct prog_instruction *out; /* Check for INPUT values, emit INTERP instructions where * necessary: */ validate_src_regs(c, inst); switch (inst->Opcode) { case OPCODE_SWZ: out = emit_insn(c, inst); out->Opcode = OPCODE_MOV; break; case OPCODE_ABS: out = emit_insn(c, inst); out->Opcode = OPCODE_MOV; out->SrcReg[0].NegateBase = 0; out->SrcReg[0].Abs = 1; break; case OPCODE_SUB: out = emit_insn(c, inst); out->Opcode = OPCODE_ADD; out->SrcReg[1].NegateBase ^= 0xf; break; case OPCODE_SCS: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask &= WRITEMASK_XY; break; case OPCODE_DST: precalc_dst(c, inst); break; case OPCODE_LIT: precalc_lit(c, inst); break; case OPCODE_TXP: precalc_txp(c, inst); break; case OPCODE_XPD: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask &= WRITEMASK_XYZ; break; case OPCODE_KIL: out = emit_insn(c, inst); /* This should probably be done in the parser. */ out->DstReg.WriteMask = 0; break; case OPCODE_END: case OPCODE_PRINT: break; default: emit_insn(c, inst); break; } } emit_fog(c); emit_fb_write(c); if (INTEL_DEBUG & DEBUG_WM) { _mesa_printf("\n\n\npass_fp:\n"); print_insns( c->prog_instructions, c->nr_fp_insns ); _mesa_printf("\n"); } }