diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile index ff3801d..3167d49 100644 --- a/src/mesa/drivers/dri/r300/compiler/Makefile +++ b/src/mesa/drivers/dri/r300/compiler/Makefile @@ -23,6 +23,7 @@ C_SOURCES = \ radeon_dataflow_deadcode.c \ radeon_dataflow_swizzles.c \ radeon_optimize.c \ + radeon_rename_regs.c \ r3xx_fragprog.c \ r300_fragprog.c \ r300_fragprog_swizzle.c \ diff --git a/src/mesa/drivers/dri/r300/compiler/SConscript b/src/mesa/drivers/dri/r300/compiler/SConscript index 50d9cdb..c6f47a6 100755 --- a/src/mesa/drivers/dri/r300/compiler/SConscript +++ b/src/mesa/drivers/dri/r300/compiler/SConscript @@ -22,6 +22,7 @@ r300compiler = env.ConvenienceLibrary( 'radeon_pair_schedule.c', 'radeon_pair_regalloc.c', 'radeon_optimize.c', + 'radeon_rename_regs.c', 'radeon_emulate_branches.c', 'radeon_emulate_loops.c', 'radeon_dataflow.c', diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index b53571a..19b3327 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -29,6 +29,7 @@ #include "radeon_emulate_loops.h" #include "radeon_program_alu.h" #include "radeon_program_tex.h" +#include "radeon_rename_regs.h" #include "r300_fragprog.h" #include "r300_fragprog_swizzle.h" #include "r500_fragprog.h" @@ -175,6 +176,13 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) debug_program_log(c, "after dataflow passes"); + if(!c->Base.is_r500){ + rc_rename_regs(&c->Base); + if (c->Base.Error) + return; + debug_program_log(c, "after tex rename"); + } + rc_pair_translate(c); if (c->Base.Error) return; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c new file mode 100644 index 0000000..dfadbec --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c @@ -0,0 +1,111 @@ +/* + * Copyright 2010 Tom Stellard + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_rename_regs.h" + +#include "radeon_compiler.h" +#include "radeon_dataflow.h" + +struct reg_rename { + int old_index; + int new_index; + int temp_index; +}; + +static void rename_regs(void * data, struct rc_instruction * inst, + rc_register_file * file, unsigned int * index) +{ + struct reg_rename *r = data; + + /* The order of these if statements matters, because if + * r->old_index = r->new_index, then reversing these if + * statements will result in changes all of old_index register + * to temp_index. */ + if(r->old_index == *index && *file == RC_FILE_TEMPORARY){ + *index = r->new_index; + } + else if(r->new_index == *index && *file == RC_FILE_TEMPORARY){ + *index = r->temp_index; + } +} + +static void rename_all( + struct radeon_compiler *c, + struct rc_instruction * start, + unsigned int old, + unsigned int new, + unsigned int temp) +{ + struct rc_instruction * inst; + struct reg_rename r; + r.old_index = old; + r.new_index = new; + r.temp_index = temp; + for(inst = start; inst != &c->Program.Instructions; + inst = inst->Next){ + rc_remap_registers(inst, rename_regs, &r); + } +} + +void rc_rename_regs(struct radeon_compiler * c) +{ + unsigned int cur_index = 0; + struct rc_instruction * inst; + /* XXX It is likely that we will use more than RC_REGISTER_MAX_INDEX, + * so this should probably be dynamically allocated. + */ + unsigned int masks[RC_REGISTER_MAX_INDEX]; + memset(masks, 0, sizeof(masks)); + + for(inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; + inst = inst->Next){ + const struct rc_opcode_info * info; + if(inst->Type != RC_INSTRUCTION_NORMAL){ + rc_error(c, "%s only works with normal instructions.", + __FUNCTION__); + return; + } + unsigned int old_index, temp_index; + struct rc_dst_register * dst = &inst->U.I.DstReg; + info = rc_get_opcode_info(inst->U.I.Opcode); + if(!info->HasDstReg || dst->File != RC_FILE_TEMPORARY){ + continue; + } + if(!masks[dst->Index] || masks[dst->Index] == dst->WriteMask){ + old_index = dst->Index; + /* We need to set dst->Index here so get free temporary + * will work. */ + dst->Index = cur_index++; + /* This is not efficient, we should keep our own list.*/ + temp_index = rc_find_free_temporary(c); + rename_all(c, inst->Next, old_index, + dst->Index, temp_index); + } + masks[dst->Index] |= dst->WriteMask; + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h new file mode 100644 index 0000000..4323b99 --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h @@ -0,0 +1,9 @@ + +#ifndef RADEON_RENAME_REGS_H +#define RADEON_RENAME_REGS_H + +struct radeon_compiler; + +void rc_rename_regs(struct radeon_compiler * c); + +#endif /* RADEON_RENAME_REGS_H */