callback(data, c->OutputDepth, RC_MASK_W);
}
-static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
+static void rc_rewrite_depth_out(struct radeon_compiler *cc, void *user)
{
+ struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
struct rc_instruction *rci;
for (rci = c->Base.Program.Instructions.Next; rci != &c->Base.Program.Instructions; rci = rci->Next) {
}
}
-static void debug_program_log(struct r300_fragment_program_compiler* c, const char * where)
-{
- if (c->Base.Debug) {
- fprintf(stderr, "Fragment Program: %s\n", where);
- rc_print_program(&c->Base.Program);
- }
-}
-
void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{
- rewrite_depth_out(c);
-
- /* This transformation needs to be done before any of the IF
- * instructions are modified. */
- radeonTransformKILP(&c->Base);
-
- debug_program_log(c, "before compilation");
-
- if (c->Base.is_r500) {
- rc_unroll_loops(&c->Base);
- debug_program_log(c, "after unroll loops");
- } else {
- rc_transform_loops(&c->Base, NULL);
- debug_program_log(c, "after transform loops");
-
- rc_emulate_branches(&c->Base, NULL);
- debug_program_log(c, "after emulate branches");
- }
-
- if (c->Base.is_r500) {
- struct radeon_program_transformation transformations[] = {
- { &r500_transform_IF, 0 },
- { &radeonTransformALU, 0 },
- { &radeonTransformDeriv, 0 },
- { &radeonTransformTrigScale, 0 },
- { 0, 0 }
- };
- rc_local_transform(&c->Base, transformations);
-
- debug_program_log(c, "after native rewrite part 1");
-
- c->Base.SwizzleCaps = &r500_swizzle_caps;
- } else {
- struct radeon_program_transformation transformations[] = {
- { &radeonTransformALU, 0 },
- { &r300_transform_trig_simple, 0 },
- { 0, 0 }
- };
- rc_local_transform(&c->Base, transformations);
-
- debug_program_log(c, "after native rewrite part 1");
-
- c->Base.SwizzleCaps = &r300_swizzle_caps;
- }
+ int is_r500 = c->Base.is_r500;
+ int kill_consts = c->Base.remove_unused_constants;
- /* Run the common transformations too.
- * Remember, lowering comes last! */
- struct radeon_program_transformation common_transformations[] = {
+ /* Lists of instruction transformations. */
+ struct radeon_program_transformation rewrite_tex[] = {
{ &radeonTransformTEX, c },
{ 0, 0 }
};
- rc_local_transform(&c->Base, common_transformations);
-
- common_transformations[0].function = &radeonTransformALU;
- rc_local_transform(&c->Base, common_transformations);
-
- if (c->Base.Error)
- return;
-
- debug_program_log(c, "after native rewrite part 2");
-
- rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use);
- if (c->Base.Error)
- return;
-
- debug_program_log(c, "after deadcode");
-
- if (!c->Base.is_r500) {
- rc_emulate_loops(&c->Base);
- debug_program_log(c, "after emulate loops");
- }
-
- rc_optimize(&c->Base);
-
- debug_program_log(c, "after dataflow optimize");
-
- rc_dataflow_swizzles(&c->Base, NULL);
- if (c->Base.Error)
- return;
-
- debug_program_log(c, "after dataflow passes");
- if (c->Base.remove_unused_constants) {
- rc_remove_unused_constants(&c->Base,
- &c->code->constants_remap_table);
+ struct radeon_program_transformation native_rewrite_r500[] = {
+ { &r500_transform_IF, 0 },
+ { &radeonTransformALU, 0 },
+ { &radeonTransformDeriv, 0 },
+ { &radeonTransformTrigScale, 0 },
+ { 0, 0 }
+ };
- debug_program_log(c, "after constants cleanup");
- }
+ struct radeon_program_transformation native_rewrite_r300[] = {
+ { &radeonTransformALU, 0 },
+ { &r300_transform_trig_simple, 0 },
+ { 0, 0 }
+ };
- if (!c->Base.is_r500) {
+ /* List of compiler passes. */
+ struct radeon_compiler_pass fs_list[] = {
+ /* NAME DUMP PREDICATE FUNCTION PARAM */
+ {"rewrite depth out", 1, 1, rc_rewrite_depth_out, NULL},
+ /* This transformation needs to be done before any of the IF
+ * instructions are modified. */
+ {"transform KILP", 1, 1, rc_transform_KILP, NULL},
+ {"unroll loops", 1, is_r500, rc_unroll_loops, NULL},
+ {"transform loops", 1, !is_r500, rc_transform_loops, NULL},
+ {"emulate branches", 1, !is_r500, rc_emulate_branches, NULL},
+ {"transform TEX", 1, 1, rc_local_transform, rewrite_tex},
+ {"native rewrite", 1, is_r500, rc_local_transform, native_rewrite_r500},
+ {"native rewrite", 1, !is_r500, rc_local_transform, native_rewrite_r300},
+ {"deadcode", 1, 1, rc_dataflow_deadcode, dataflow_outputs_mark_use},
+ {"emulate loops", 1, !is_r500, rc_emulate_loops, NULL},
+ {"dataflow optimize", 1, 1, rc_optimize, NULL},
+ {"dataflow swizzles", 1, 1, rc_dataflow_swizzles, NULL},
+ {"dead constants", 1, kill_consts, rc_remove_unused_constants, &c->code->constants_remap_table},
/* This pass makes it easier for the scheduler to group TEX
* instructions and reduces the chances of creating too
* many texture indirections.*/
- rc_rename_regs(&c->Base);
- if (c->Base.Error)
- return;
- debug_program_log(c, "after register rename");
- }
-
- rc_pair_translate(c);
- if (c->Base.Error)
- return;
-
- debug_program_log(c, "after pair translate");
-
- rc_pair_schedule(c);
- if (c->Base.Error)
- return;
-
- debug_program_log(c, "after pair scheduling");
-
- rc_pair_regalloc(c);
-
- if (c->Base.Error)
- return;
+ {"register rename", 1, !is_r500, rc_rename_regs, NULL},
+ {"pair translate", 1, 1, rc_pair_translate, NULL},
+ {"pair scheduling", 1, 1, rc_pair_schedule, NULL},
+ {"register allocation", 1, 1, rc_pair_regalloc, NULL},
+ {"final code validation", 0, 1, rc_validate_final_shader, NULL},
+ {"machine code generation", 0, is_r500, r500BuildFragmentProgramHwCode, NULL},
+ {"machine code generation", 0, !is_r500, r300BuildFragmentProgramHwCode, NULL},
+ {"dump machine code", 0, is_r500 && c->Base.Debug, r500FragmentProgramDump, NULL},
+ {"dump machine code", 0, !is_r500 && c->Base.Debug, r300FragmentProgramDump, NULL},
+ {NULL, 0, 0, NULL, NULL}
+ };
- debug_program_log(c, "after register allocation");
+ c->Base.SwizzleCaps = c->Base.is_r500 ? &r500_swizzle_caps : &r300_swizzle_caps;
- if (c->Base.is_r500) {
- r500BuildFragmentProgramHwCode(c);
- } else {
- r300BuildFragmentProgramHwCode(c);
- }
+ rc_run_compiler(&c->Base, fs_list, "Fragment Program");
rc_constants_copy(&c->code->constants, &c->Base.Program.Constants);
-
- if (c->Base.Debug) {
- if (c->Base.is_r500) {
- r500FragmentProgramDump(c->code);
- } else {
- r300FragmentProgramDump(c->code);
- }
- }
-
- /* Check the number of constants. */
- if (!c->Base.Error) {
- unsigned max = c->Base.is_r500 ? R500_PFS_NUM_CONST_REGS : R300_PFS_NUM_CONST_REGS;
-
- if (c->Base.Program.Constants.Count > max) {
- rc_error(&c->Base, "Too many constants. Max: %i, Got: %i\n",
- max, c->Base.Program.Constants.Count);
- }
- }
}