All pastes #1895312 Raw Edit

Something

public text v1 · immutable
#1895312 ·published 2010-07-06 04:37 UTC
rendered paste body
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 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;
 		}
 	}