void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) { rewrite_depth_out(c); if (c->is_r500) { struct radeon_program_transformation transformations[] = { { &r500_transform_TEX, c }, { &r500_transform_IF, 0 }, { &radeonTransformALU, 0 }, { &radeonTransformDeriv, 0 }, { &radeonTransformTrigScale, 0 } }; radeonLocalTransform(&c->Base, 5, transformations); c->Base.SwizzleCaps = &r500_swizzle_caps; } else { struct radeon_program_transformation transformations[] = { { &r300_transform_TEX, c }, { &radeonTransformALU, 0 }, { &radeonTransformTrigSimple, 0 } }; radeonLocalTransform(&c->Base, 3, transformations); c->Base.SwizzleCaps = &r300_swizzle_caps; } if (c->Base.Debug) { fprintf(stderr, "Fragment Program: After native rewrite:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use, c); if (c->Base.Error) return; if (c->Base.Debug) { fprintf(stderr, "Fragment Program: After deadcode:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } rc_dataflow_swizzles(&c->Base); if (c->Base.Error) return; if (c->Base.Debug) { fprintf(stderr, "Compiler: after dataflow passes:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } rc_pair_translate(c); if (c->Base.Error) return; if (c->Base.Debug) { fprintf(stderr, "Compiler: after pair translate:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } rc_pair_schedule(c); if (c->Base.Error) return; if (c->Base.Debug) { fprintf(stderr, "Compiler: after pair scheduling:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } if (c->is_r500) rc_pair_regalloc(c, 128); else rc_pair_regalloc(c, R300_PFS_NUM_TEMP_REGS); if (c->Base.Error) return; if (c->Base.Debug) { fprintf(stderr, "Compiler: after pair register allocation:\n"); rc_print_program(&c->Base.Program); fflush(stderr); } if (c->is_r500) { r500BuildFragmentProgramHwCode(c); } else { r300BuildFragmentProgramHwCode(c); } rc_constants_copy(&c->code->constants, &c->Base.Program.Constants); if (c->Base.Debug) { if (c->is_r500) { r500FragmentProgramDump(c->code); } else { r300FragmentProgramDump(c->code); } } }
/** * Handle one instruction. */ static void process_instruction(struct nqssadce_state* s) { struct prog_instruction *inst = s->Program->Instructions + s->IP; if (inst->Opcode == OPCODE_END) return; if (inst->Opcode != OPCODE_KIL) { if (s->Descr->RewriteDepthOut) { if (inst->DstReg.File == PROGRAM_OUTPUT && inst->DstReg.Index == FRAG_RESULT_DEPR) rewrite_depth_out(inst); } struct register_state *regstate = get_reg_state(s, inst->DstReg.File, inst->DstReg.Index); if (!regstate) { _mesa_problem(s->Ctx, "NqssaDce: bad destination register (%i[%i])\n", inst->DstReg.File, inst->DstReg.Index); return; } inst->DstReg.WriteMask &= regstate->Sourced; regstate->Sourced &= ~inst->DstReg.WriteMask; if (inst->DstReg.WriteMask == 0) { _mesa_delete_instructions(s->Program, s->IP, 1); return; } if (inst->DstReg.File == PROGRAM_TEMPORARY && !regstate->Sourced) unalias_temporary(s, inst->DstReg.Index); } /* Attention: Due to swizzle emulation code, the following * might change the instruction stream under us, so we have * to be careful with the inst pointer. */ switch (inst->Opcode) { case OPCODE_DDX: case OPCODE_DDY: case OPCODE_FRC: case OPCODE_MOV: inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask); break; case OPCODE_ADD: case OPCODE_MAX: case OPCODE_MIN: case OPCODE_MUL: inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask); inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask); break; case OPCODE_CMP: case OPCODE_MAD: inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask); inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask); inst = track_used_srcreg(s, inst, 2, inst->DstReg.WriteMask); break; case OPCODE_COS: case OPCODE_EX2: case OPCODE_LG2: case OPCODE_RCP: case OPCODE_RSQ: case OPCODE_SIN: inst = track_used_srcreg(s, inst, 0, 0x1); break; case OPCODE_DP3: inst = track_used_srcreg(s, inst, 0, 0x7); inst = track_used_srcreg(s, inst, 1, 0x7); break; case OPCODE_DP4: inst = track_used_srcreg(s, inst, 0, 0xf); inst = track_used_srcreg(s, inst, 1, 0xf); break; case OPCODE_KIL: case OPCODE_TEX: case OPCODE_TXB: case OPCODE_TXP: inst = track_used_srcreg(s, inst, 0, 0xf); break; default: _mesa_problem(s->Ctx, "NqssaDce: Unknown opcode %d\n", inst->Opcode); return; } }