r300/compiler: refactor fragment shader compilation
authorMarek Olšák <maraeo@gmail.com>
Wed, 1 Sep 2010 03:01:19 +0000 (05:01 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 4 Sep 2010 16:56:21 +0000 (18:56 +0200)
This cleans up the mess in r3xx_compile_fragment_program.

19 files changed:
src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c
src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h
src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h

index 794db8335a2022730d86050064dbf23a5293355f..3c83deffcb56c6866d689334cb77a44b74e62592 100644 (file)
 #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;
 
index 8b755703be4a5c525c32b5ad917814ffae23e9ea..0c88bab2f33d9a9f74923bf8d3523b754640195a 100644 (file)
@@ -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
index ba5461bef48a8940057aa184d87b79041ebf6dc6..eead2ea4260cc2a53fa71e74c69683d205439dcd 100644 (file)
@@ -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;
 
index a3c34beb02f8a71f6623804fac0aed0bd4735b13..096afe8ad6a209b88f0291db4f596968b4a2f2b0 100644 (file)
@@ -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);
-               }
-       }
 }
index 80a120497e32271bf3b4ec8982d9344cf221b7e2..627ce374ef1824ad641231d9e9ae30cd2de16b37 100644 (file)
@@ -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;
index 4efbae7ba672929143407995a268ab0c286346e4..1e665e27641ebbfd0d7cc7c6f7e18dcfad3ce49f 100644 (file)
@@ -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;
 
index 8a6aafe5af12cf67f7b2b848d71671f4c29bd647..3220349f26cd96c66804dc42b7d2b512ceee0862 100644 (file)
@@ -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;
 
index 7a7a33ec71341ec9f4fafa1ec72c529539121b31..795d9cc2b6d7d7dbd0c51509055f312655abb28a 100644 (file)
@@ -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 */
index 026556f319f757e952163cbf0893c6de808acf63..cd4fcbabb938d1f22677cf2b736150bb0292db81 100644 (file)
@@ -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;
index 4e37330f81a13ef0a7071ef0389bf07434346cba..cd800c059d953cad3692ce134862b806f4de91ee 100644 (file)
@@ -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 */
index 7a3f35950a635e776fe71df0369df314025e65f1..8db521e51b9cad10dcf2ab56777814916229b3fe 100644 (file)
@@ -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) {
index 3664a6512707db98145c8aeaa14c1899a3df0ad8..d0ee497eca55ea17e8eba16e9a53233b922376bd 100644 (file)
@@ -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;
 
index fc540496c415c9d9da840466e0a80f4cce94fb36..8e232bb2436e976528d393769d8d92740b07d419 100644 (file)
@@ -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)) {
index 8327e9aced693c7b12e488bf10bd29a950c65815..9fe39344f8e127eb96c6159983c9fbae0d40ef0a 100644 (file)
@@ -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) {
index bdff995b071506a69028912152f17f229bd3db02..4d3e26f28cd21db174a6cc0bea1833786019c24b 100644 (file)
@@ -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;
index 903f13746de0c7bf917856629496e2c99a7ee9b1..b5f361e624faa9d2038e060f073a42d6d137b6d8 100644 (file)
@@ -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_ */
index 44ef2524980a7fdf52bb295b1593af6179370d92..28a163ff4471730bfe6e5fbd0b30fc57cb140aae 100644 (file)
@@ -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_ */
index 31c98668838630dd1b92d0ba4f1293655f9901f4..31d25f9ab8a933518aae8662d2fa2cddbfb6c225 100644 (file)
@@ -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;
index 4323b995d84605fbe03c0bf7ff9d67fc70fc1e8f..3baf29f612011d2c4aab3a657b739cf65180a13a 100644 (file)
@@ -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 */