rendered paste bodydiff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
index a279549..1fdf90f 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
@@ -481,9 +481,99 @@ static int is_controlflow(struct rc_instruction * inst)
return 0;
}
+static void rewrite_tex_dst_reg(struct r300_fragment_program_compiler *c)
+{
+ char used_regs[RC_REGISTER_MAX_INDEX];
+ struct rc_instruction * inst;
+ memset(used_regs, 0, sizeof(used_regs));
+
+ for(inst = c->Base.Program.Instructions.Next;
+ inst != &c->Base.Program.Instructions;
+ inst = inst->Next){
+ struct rc_instruction * temp;
+ int old_index, new_index;
+ const struct rc_opcode_info * info;
+ if(inst->Type != RC_INSTRUCTION_NORMAL || is_controlflow(inst))
+ continue;
+
+ info = rc_get_opcode_info(inst->U.I.Opcode);
+ if(!info->HasDstReg){
+ continue;
+ }
+ old_index = inst->U.I.DstReg.Index;
+ if(!used_regs[old_index]){
+ used_regs[old_index] = 1;
+ continue;
+ }
+ fprintf(stderr, "Rewriting TEX\n");
+ new_index = rc_find_free_temporary(&c->Base);
+ for(temp = inst; temp != &c->Base.Program.Instructions;
+ temp = temp->Next){
+ unsigned int i;
+ switch(temp->Type){
+ case RC_INSTRUCTION_NORMAL:
+ info = rc_get_opcode_info(temp->U.I.Opcode);
+ if(info->HasDstReg){
+ struct rc_dst_register *dst = &temp->U.I.DstReg;
+ if(dst->Index == old_index
+ && dst->File == RC_FILE_TEMPORARY){
+ dst->Index = new_index;
+ }
+ }
+ for(i=0; i < info->NumSrcRegs; i++){
+ struct rc_src_register *src =
+ &temp->U.I.SrcReg[i];
+ if(src->Index == old_index
+ && src->File == RC_FILE_TEMPORARY){
+ src->Index = new_index;
+ }
+ }
+ break;
+ case RC_INSTRUCTION_PAIR:
+ {
+ struct radeon_pair_instruction_rgb rgb =
+ temp->U.P.RGB;
+ struct radeon_pair_instruction_alpha alpha =
+ temp->U.P.Alpha;
+ /* RGB */
+ info = rc_get_opcode_info(rgb.Opcode);
+ /* If WriteMask is defined, then the
+ * destination register is a temporary. */
+ if(rgb.DestIndex == old_index
+ && info->HasDstReg
+ && rgb.WriteMask){
+ rgb.DestIndex = new_index;
+ }
+ for(i = 0; i < info->NumSrcRegs; i++){
+ if(rgb.Src[i].Index == old_index && rgb.Src[i].File == RC_FILE_TEMPORARY){
+ rgb.Src[i].Index = new_index;
+ }
+ }
+
+ /* Alpha */
+ info = rc_get_opcode_info(alpha.Opcode);
+ if(alpha.DestIndex == old_index && info->HasDstReg && alpha.WriteMask){
+ alpha.DestIndex = new_index;
+ }
+ for(i = 0; i < info->NumSrcRegs; i++){
+ if(alpha.Src[i].Index == old_index && alpha.Src[i].File == RC_FILE_TEMPORARY){
+ alpha.Src[i].Index = new_index;
+ }
+ }
+ break;
+ }
+ }
+ used_regs[new_index] = 1;
+ }
+ }
+}
+
void rc_pair_schedule(struct r300_fragment_program_compiler *c)
{
struct rc_instruction * inst = c->Base.Program.Instructions.Next;
+
+ rewrite_tex_dst_reg(c);
+
while(inst != &c->Base.Program.Instructions) {
if (is_controlflow(inst)) {
inst = inst->Next;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
index a3c41d7..969ef84 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -90,6 +90,56 @@ struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register
return tmp;
}
+static void mark_used_registers_pair(struct rc_pair_instruction * pair,
+ char * used)
+{
+ const struct rc_opcode_info * info;
+ unsigned int i;
+ struct radeon_pair_instruction_rgb rgb = pair->RGB;
+ struct radeon_pair_instruction_alpha alpha = pair->Alpha;
+
+ /* RGB */
+ info = rc_get_opcode_info(rgb.Opcode);
+ /* If WriteMask is defined, then the destination register is a
+ * temporary. */
+ if(info->HasDstReg && rgb.WriteMask){
+ used[rgb.DestIndex] = 1;
+ }
+ for(i = 0; i < info->NumSrcRegs; i++){
+ if(rgb.Src[i].File == RC_FILE_TEMPORARY){
+ used[rgb.Src[i].Index] = 1;
+ }
+ }
+
+ /* Alpha */
+ info = rc_get_opcode_info(alpha.Opcode);
+ if(info->HasDstReg && alpha.WriteMask){
+ used[alpha.DestIndex] = 1;
+ }
+ for(i = 0; i < info->NumSrcRegs; i++){
+ if(alpha.Src[i].File == RC_FILE_TEMPORARY){
+ used[alpha.Src[i].Index] = 1;
+ }
+ }
+}
+
+static void mark_used_registers_normal(struct rc_sub_instruction * inst,
+ char * used)
+{
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
+ unsigned int k;
+
+ for (k = 0; k < opcode->NumSrcRegs; k++) {
+ if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
+ used[inst->SrcReg[k].Index] = 1;
+ }
+ if (opcode->HasDstReg) {
+ if (inst->DstReg.File == RC_FILE_TEMPORARY)
+ used[inst->DstReg.Index] = 1;
+ }
+}
+
+
unsigned int rc_find_free_temporary(struct radeon_compiler * c)
{
char used[RC_REGISTER_MAX_INDEX];
@@ -99,18 +149,17 @@ unsigned int rc_find_free_temporary(struct radeon_compiler * c)
memset(used, 0, sizeof(used));
for (rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
- const struct rc_sub_instruction *inst = &rcinst->U.I;
- const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
- unsigned int k;
-
- for (k = 0; k < opcode->NumSrcRegs; k++) {
- if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
- used[inst->SrcReg[k].Index] = 1;
- }
-
- if (opcode->HasDstReg) {
- if (inst->DstReg.File == RC_FILE_TEMPORARY)
- used[inst->DstReg.Index] = 1;
+ switch(rcinst->Type){
+ case RC_INSTRUCTION_NORMAL:
+ mark_used_registers_normal(&rcinst->U.I, used);
+ break;
+ case RC_INSTRUCTION_PAIR:
+ mark_used_registers_pair(&rcinst->U.P, used);
+ break;
+ default:
+ rc_error(c, "%s: Unknown instruction type.",
+ __FUNCTION__);
+ break;
}
}