summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_pair_schedule.c90
1 files changed, 57 insertions, 33 deletions
diff --git a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
index 94cf9a77cea..b3b0f6fc25b 100644
--- a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
+++ b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
@@ -896,7 +896,16 @@ static int convert_rgb_to_alpha(
return 0;
}
- pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
+ /* If we are converting a full instruction with RC_OPCODE_REPL_ALPHA
+ * as the RGB opcode, then the Alpha instruction will already contain
+ * the correct opcode and instruction args, so we do not want to
+ * overwrite them.
+ */
+ if (pair_inst->RGB.Opcode != RC_OPCODE_REPL_ALPHA) {
+ pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
+ memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
+ sizeof(pair_inst->Alpha.Arg));
+ }
pair_inst->Alpha.DestIndex = new_index;
pair_inst->Alpha.WriteMask = RC_MASK_W;
pair_inst->Alpha.Target = pair_inst->RGB.Target;
@@ -904,8 +913,6 @@ static int convert_rgb_to_alpha(
pair_inst->Alpha.DepthWriteMask = pair_inst->RGB.DepthWriteMask;
pair_inst->Alpha.Saturate = pair_inst->RGB.Saturate;
pair_inst->Alpha.Omod = pair_inst->RGB.Omod;
- memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
- sizeof(pair_inst->Alpha.Arg));
/* Move the swizzles into the first chan */
for (i = 0; i < info->NumSrcRegs; i++) {
unsigned int j;
@@ -935,6 +942,48 @@ static int convert_rgb_to_alpha(
return 1;
}
+static void try_convert_and_pair(
+ struct schedule_state *s,
+ struct schedule_instruction ** inst_list)
+{
+ struct schedule_instruction * list_ptr = *inst_list;
+ while (list_ptr && *inst_list && (*inst_list)->NextReady) {
+ int paired = 0;
+ if (list_ptr->Instruction->U.P.Alpha.Opcode != RC_OPCODE_NOP
+ && list_ptr->Instruction->U.P.RGB.Opcode
+ != RC_OPCODE_REPL_ALPHA) {
+ goto next;
+ }
+ if (list_ptr->NumWriteValues == 1
+ && convert_rgb_to_alpha(s, list_ptr)) {
+
+ struct schedule_instruction * pair_ptr;
+ remove_inst_from_list(inst_list, list_ptr);
+ add_inst_to_list_score(&s->ReadyAlpha, list_ptr);
+
+ for (pair_ptr = s->ReadyRGB; pair_ptr;
+ pair_ptr = pair_ptr->NextReady) {
+ if (merge_instructions(&pair_ptr->Instruction->U.P,
+ &list_ptr->Instruction->U.P)) {
+ remove_inst_from_list(&s->ReadyAlpha, list_ptr);
+ remove_inst_from_list(&s->ReadyRGB, pair_ptr);
+ pair_ptr->PairedInst = list_ptr;
+
+ add_inst_to_list(&s->ReadyFullALU, pair_ptr);
+ list_ptr = *inst_list;
+ paired = 1;
+ break;
+ }
+
+ }
+ }
+ if (!paired) {
+next:
+ list_ptr = list_ptr->NextReady;
+ }
+ }
+}
+
/**
* This function attempts to merge RGB and Alpha instructions together.
*/
@@ -969,38 +1018,13 @@ static void pair_instructions(struct schedule_state * s)
return;
}
+ /* Full instructions that have RC_OPCODE_REPL_ALPHA in the RGB
+ * slot can be converted into Alpha instructions. */
+ try_convert_and_pair(s, &s->ReadyFullALU);
+
/* Try to convert some of the RGB instructions to Alpha and
* try to pair it with another RGB. */
- rgb_ptr = s->ReadyRGB;
- while (rgb_ptr && s->ReadyRGB && s->ReadyRGB->NextReady) {
- int paired = 0;
- if (rgb_ptr->NumWriteValues == 1
- && convert_rgb_to_alpha(s, rgb_ptr)) {
-
- struct schedule_instruction * pair_ptr;
- remove_inst_from_list(&s->ReadyRGB, rgb_ptr);
- add_inst_to_list_score(&s->ReadyAlpha, rgb_ptr);
-
- for (pair_ptr = s->ReadyRGB; pair_ptr;
- pair_ptr = pair_ptr->NextReady) {
- if (merge_instructions(&pair_ptr->Instruction->U.P,
- &rgb_ptr->Instruction->U.P)) {
- remove_inst_from_list(&s->ReadyAlpha, rgb_ptr);
- remove_inst_from_list(&s->ReadyRGB, pair_ptr);
- pair_ptr->PairedInst = rgb_ptr;
-
- add_inst_to_list(&s->ReadyFullALU, pair_ptr);
- rgb_ptr = s->ReadyRGB;
- paired = 1;
- break;
- }
-
- }
- }
- if (!paired) {
- rgb_ptr = rgb_ptr->NextReady;
- }
- }
+ try_convert_and_pair(s, &s->ReadyRGB);
}
static void update_max_score(