From: Marek Olšák Date: Wed, 1 Sep 2010 03:01:19 +0000 (+0200) Subject: r300/compiler: refactor fragment shader compilation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fba5f6bda76f5236f6f05aa81157a08949cde7c3;p=mesa.git r300/compiler: refactor fragment shader compilation This cleans up the mess in r3xx_compile_fragment_program. --- diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c index 794db8335a2..3c83deffcb5 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c @@ -32,9 +32,10 @@ #include "../r300_reg.h" /* just some random things... */ -void r300FragmentProgramDump(struct rX00_fragment_program_code *c) +void r300FragmentProgramDump(struct radeon_compiler *c, void *user) { - struct r300_fragment_program_code *code = &c->code.r300; + struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; + struct r300_fragment_program_code *code = &compiler->code->code.r300; int n, i, j; static int pc = 0; diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h index 8b755703be4..0c88bab2f33 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h @@ -37,8 +37,8 @@ #include "radeon_program.h" -extern void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler); +extern void r300BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user); -extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c); +extern void r300FragmentProgramDump(struct radeon_compiler *c, void *user); #endif diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c index ba5461bef48..eead2ea4260 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c @@ -328,8 +328,9 @@ static int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst) * Final compilation step: Turn the intermediate radeon_program into * machine-readable instructions. */ -void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler) +void r300BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user) { + struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; struct r300_emit_state emit; struct r300_fragment_program_code *code = &compiler->code->code.r300; diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index a3c34beb02f..096afe8ad6a 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -47,8 +47,9 @@ static void dataflow_outputs_mark_use(void * userdata, void * data, 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) { @@ -89,157 +90,67 @@ static void rewrite_depth_out(struct r300_fragment_program_compiler * c) } } -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); - } - } } diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c index 80a120497e3..627ce374ef1 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c @@ -247,9 +247,10 @@ static char *to_texop(int val) return NULL; } -void r500FragmentProgramDump(struct rX00_fragment_program_code *c) +void r500FragmentProgramDump(struct radeon_compiler *c, void *user) { - struct r500_fragment_program_code *code = &c->code.r500; + struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; + struct r500_fragment_program_code *code = &compiler->code->code.r500; fprintf(stderr, "R500 Fragment Program:\n--------\n"); int n, i; diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h index 4efbae7ba67..1e665e27641 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h @@ -36,9 +36,9 @@ #include "radeon_compiler.h" #include "radeon_swizzle.h" -extern void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler); +extern void r500BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user); -extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c); +extern void r500FragmentProgramDump(struct radeon_compiler *c, void *user); extern struct rc_swizzle_caps r500_swizzle_caps; diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index 8a6aafe5af1..3220349f26c 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -546,8 +546,9 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst } } -void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler) +void r500BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user) { + struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; struct emit_state s; struct r500_fragment_program_code *code = &compiler->code->code.r500; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h index 7a7a33ec713..795d9cc2b6d 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h @@ -65,6 +65,6 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, void *user); void rc_dataflow_swizzles(struct radeon_compiler * c, void *user); /*@}*/ -void rc_optimize(struct radeon_compiler * c); +void rc_optimize(struct radeon_compiler * c, void *user); #endif /* RADEON_DATAFLOW_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c index 026556f319f..cd4fcbabb93 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c @@ -487,7 +487,7 @@ void rc_transform_loops(struct radeon_compiler *c, void *user) } } -void rc_unroll_loops(struct radeon_compiler *c) +void rc_unroll_loops(struct radeon_compiler *c, void *user) { struct rc_instruction * inst; struct loop_info loop; @@ -503,7 +503,7 @@ void rc_unroll_loops(struct radeon_compiler *c) } } -void rc_emulate_loops(struct radeon_compiler *c) +void rc_emulate_loops(struct radeon_compiler *c, void *user) { struct emulate_loop_state * s = &c->loop_state; int i; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h index 4e37330f81a..cd800c059d9 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h @@ -25,8 +25,8 @@ struct emulate_loop_state { void rc_transform_loops(struct radeon_compiler *c, void *user); -void rc_unroll_loops(struct radeon_compiler * c); +void rc_unroll_loops(struct radeon_compiler * c, void *user); -void rc_emulate_loops(struct radeon_compiler * c); +void rc_emulate_loops(struct radeon_compiler * c, void *user); #endif /* RADEON_EMULATE_LOOPS_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c index 7a3f35950a6..8db521e51b9 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c @@ -446,7 +446,7 @@ static void constant_folding(struct radeon_compiler * c, struct rc_instruction * constant_folding_add(inst); } -void rc_optimize(struct radeon_compiler * c) +void rc_optimize(struct radeon_compiler * c, void *user) { struct rc_instruction * inst = c->Program.Instructions.Next; while(inst != &c->Program.Instructions) { diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c index 3664a651270..d0ee497eca5 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c @@ -292,8 +292,9 @@ static void alloc_input(void * data, unsigned int input, unsigned int hwreg) } -void rc_pair_regalloc(struct r300_fragment_program_compiler *c) +void rc_pair_regalloc(struct radeon_compiler *cc, void *user) { + struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; unsigned maxtemps = c->Base.max_temp_regs; struct regalloc_state s; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c index fc540496c41..8e232bb2436 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c @@ -529,8 +529,9 @@ static int is_controlflow(struct rc_instruction * inst) return 0; } -void rc_pair_schedule(struct r300_fragment_program_compiler *c) +void rc_pair_schedule(struct radeon_compiler *cc, void *user) { + struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; struct rc_instruction * inst = c->Base.Program.Instructions.Next; while(inst != &c->Base.Program.Instructions) { if (is_controlflow(inst)) { diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c index 8327e9aced6..9fe39344f8e 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c @@ -262,8 +262,10 @@ static void check_opcode_support(struct r300_fragment_program_compiler *c, * Translate all ALU instructions into corresponding pair instructions, * performing no other changes. */ -void rc_pair_translate(struct r300_fragment_program_compiler *c) +void rc_pair_translate(struct radeon_compiler *cc, void *user) { + struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; + for(struct rc_instruction * inst = c->Base.Program.Instructions.Next; inst != &c->Base.Program.Instructions; inst = inst->Next) { diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c index bdff995b071..4d3e26f28cd 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c @@ -1081,7 +1081,7 @@ int radeonTransformDeriv(struct radeon_compiler* c, * This needs to be done in its own pass, because it modifies the instructions * before and after KILP. */ -void radeonTransformKILP(struct radeon_compiler * c) +void rc_transform_KILP(struct radeon_compiler * c, void *user) { struct rc_instruction * inst; for (inst = c->Program.Instructions.Next; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h index 903f13746de..b5f361e624f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h @@ -60,6 +60,7 @@ int radeonTransformDeriv( struct rc_instruction * inst, void*); -void radeonTransformKILP(struct radeon_compiler * c); +void rc_transform_KILP(struct radeon_compiler * c, + void *user); #endif /* __RADEON_PROGRAM_ALU_H_ */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 44ef2524980..28a163ff447 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -32,7 +32,7 @@ #include "radeon_opcodes.h" #include "radeon_program_constants.h" -struct r300_fragment_program_compiler; +struct radeon_compiler; /** @@ -118,9 +118,9 @@ int rc_pair_alloc_source(struct rc_pair_instruction *pair, /*@{*/ struct radeon_pair_handler; -void rc_pair_translate(struct r300_fragment_program_compiler *c); -void rc_pair_schedule(struct r300_fragment_program_compiler *c); -void rc_pair_regalloc(struct r300_fragment_program_compiler *c); +void rc_pair_translate(struct radeon_compiler *cc, void *user); +void rc_pair_schedule(struct radeon_compiler *cc, void *user); +void rc_pair_regalloc(struct radeon_compiler *cc, void *user); /*@}*/ #endif /* __RADEON_PROGRAM_PAIR_H_ */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c index 31c98668838..31d25f9ab8a 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c @@ -87,7 +87,7 @@ static void rename_all( * This function assumes all the instructions are still of type * RC_INSTRUCTION_NORMAL. */ -void rc_rename_regs(struct radeon_compiler * c) +void rc_rename_regs(struct radeon_compiler *c, void *user) { unsigned int cur_index = 0; unsigned int icount; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h index 4323b995d84..3baf29f6120 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h @@ -4,6 +4,6 @@ struct radeon_compiler; -void rc_rename_regs(struct radeon_compiler * c); +void rc_rename_regs(struct radeon_compiler *c, void *user); #endif /* RADEON_RENAME_REGS_H */