void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c) { int is_r500 = c->Base.is_r500; int opt = !c->Base.disable_optimizations; /* Lists of instruction transformations. */ struct radeon_program_transformation alu_rewrite_r500[] = { { &r300_transform_vertex_alu, 0 }, { &r300_transform_trig_scale_vertex, 0 }, { 0, 0 } }; struct radeon_program_transformation alu_rewrite_r300[] = { { &r300_transform_vertex_alu, 0 }, { &r300_transform_trig_simple, 0 }, { 0, 0 } }; /* Note: These passes have to be done seperately from ALU rewrite, * otherwise non-native ALU instructions with source conflits * or non-native modifiers will not be treated properly. */ struct radeon_program_transformation emulate_modifiers[] = { { &transform_nonnative_modifiers, 0 }, { 0, 0 } }; struct radeon_program_transformation resolve_src_conflicts[] = { { &transform_source_conflicts, 0 }, { 0, 0 } }; /* List of compiler passes. */ struct radeon_compiler_pass vs_list[] = { /* NAME DUMP PREDICATE FUNCTION PARAM */ {"add artificial outputs", 0, 1, rc_vs_add_artificial_outputs, NULL}, {"transform loops", 1, 1, rc_transform_loops, NULL}, {"emulate branches", 1, !is_r500, rc_emulate_branches, NULL}, {"emulate negative addressing", 1, 1, rc_emulate_negative_addressing, NULL}, {"native rewrite", 1, is_r500, rc_local_transform, alu_rewrite_r500}, {"native rewrite", 1, !is_r500, rc_local_transform, alu_rewrite_r300}, {"emulate modifiers", 1, !is_r500, rc_local_transform, emulate_modifiers}, {"deadcode", 1, opt, rc_dataflow_deadcode, dataflow_outputs_mark_used}, {"dataflow optimize", 1, opt, rc_optimize, NULL}, /* This pass must be done after optimizations. */ {"source conflict resolve", 1, 1, rc_local_transform, resolve_src_conflicts}, {"register allocation", 1, opt, allocate_temporary_registers, NULL}, {"dead constants", 1, 1, rc_remove_unused_constants, &c->code->constants_remap_table}, {"final code validation", 0, 1, rc_validate_final_shader, NULL}, {"machine code generation", 0, 1, translate_vertex_program, NULL}, {"dump machine code", 0, c->Base.Debug & RC_DBG_LOG, r300_vertex_program_dump, NULL}, {NULL, 0, 0, NULL, NULL} }; c->Base.type = RC_VERTEX_PROGRAM; c->Base.SwizzleCaps = &r300_vertprog_swizzle_caps; rc_run_compiler(&c->Base, vs_list); c->code->InputsRead = c->Base.Program.InputsRead; c->code->OutputsWritten = c->Base.Program.OutputsWritten; rc_constants_copy(&c->code->constants, &c->Base.Program.Constants); }
void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) { compiler->Base.SwizzleCaps = &r300_vertprog_swizzle_caps; addArtificialOutputs(compiler); { struct radeon_program_transformation transformations[] = { { &r300_transform_vertex_alu, 0 }, }; radeonLocalTransform(&compiler->Base, 1, transformations); } if (compiler->Base.Debug) { fprintf(stderr, "Vertex program after native rewrite:\n"); rc_print_program(&compiler->Base.Program); fflush(stderr); } { /* Note: This pass has to be done seperately from ALU rewrite, * otherwise non-native ALU instructions with source conflits * will not be treated properly. */ struct radeon_program_transformation transformations[] = { { &transform_source_conflicts, 0 }, }; radeonLocalTransform(&compiler->Base, 1, transformations); } if (compiler->Base.Debug) { fprintf(stderr, "Vertex program after source conflict resolve:\n"); rc_print_program(&compiler->Base.Program); fflush(stderr); } rc_dataflow_deadcode(&compiler->Base, &dataflow_outputs_mark_used, compiler); if (compiler->Base.Debug) { fprintf(stderr, "Vertex program after deadcode:\n"); rc_print_program(&compiler->Base.Program); fflush(stderr); } rc_dataflow_swizzles(&compiler->Base); allocate_temporary_registers(compiler); if (compiler->Base.Debug) { fprintf(stderr, "Vertex program after dataflow:\n"); rc_print_program(&compiler->Base.Program); fflush(stderr); } translate_vertex_program(compiler); rc_constants_copy(&compiler->code->constants, &compiler->Base.Program.Constants); compiler->code->InputsRead = compiler->Base.Program.InputsRead; compiler->code->OutputsWritten = compiler->Base.Program.OutputsWritten; if (compiler->Base.Debug) { fprintf(stderr, "Final vertex program code:\n"); r300_vertex_program_dump(compiler->code); } }
void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) { int is_r500 = c->Base.is_r500; int opt = !c->Base.disable_optimizations; /* Lists of instruction transformations. */ struct radeon_program_transformation rewrite_tex[] = { { &radeonTransformTEX, c }, { 0, 0 } }; struct radeon_program_transformation rewrite_if[] = { { &r500_transform_IF, 0 }, {0, 0} }; struct radeon_program_transformation native_rewrite_r500[] = { { &radeonTransformALU, 0 }, { &radeonTransformDeriv, 0 }, { &radeonTransformTrigScale, 0 }, { 0, 0 } }; struct radeon_program_transformation native_rewrite_r300[] = { { &radeonTransformALU, 0 }, { &r300_transform_trig_simple, 0 }, { 0, 0 } }; /* 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}, {"transform IF", 1, is_r500, rc_local_transform, rewrite_if}, {"native rewrite", 1, is_r500, rc_local_transform, native_rewrite_r500}, {"native rewrite", 1, !is_r500, rc_local_transform, native_rewrite_r300}, {"deadcode", 1, opt, rc_dataflow_deadcode, dataflow_outputs_mark_use}, {"emulate loops", 1, !is_r500, rc_emulate_loops, NULL}, {"register rename", 1, !is_r500 || opt, rc_rename_regs, NULL}, {"dataflow optimize", 1, opt, rc_optimize, NULL}, {"inline literals", 1, is_r500 && opt, rc_inline_literals, NULL}, {"dataflow swizzles", 1, 1, rc_dataflow_swizzles, NULL}, {"dead constants", 1, 1, rc_remove_unused_constants, &c->code->constants_remap_table}, {"pair translate", 1, 1, rc_pair_translate, NULL}, {"pair scheduling", 1, 1, rc_pair_schedule, &opt}, {"dead sources", 1, 1, rc_pair_remove_dead_sources, NULL}, {"register allocation", 1, 1, rc_pair_regalloc, &opt}, {"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 & RC_DBG_LOG), r500FragmentProgramDump, NULL}, {"dump machine code", 0, !is_r500 && (c->Base.Debug & RC_DBG_LOG), r300FragmentProgramDump, NULL}, {NULL, 0, 0, NULL, NULL} }; c->Base.type = RC_FRAGMENT_PROGRAM; c->Base.SwizzleCaps = c->Base.is_r500 ? &r500_swizzle_caps : &r300_swizzle_caps; rc_run_compiler(&c->Base, fs_list); rc_constants_copy(&c->code->constants, &c->Base.Program.Constants); }
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); } } }