mesa: fix some issues in _mesa_combine_programs()
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 25 Mar 2008 18:27:32 +0000 (12:27 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 25 Mar 2008 18:30:05 +0000 (12:30 -0600)
Use a temporay register to connect outputs of first program to inputs of
second program.
Also, fix bug in replace_registers(): didn't search/replace DstReg.

src/mesa/shader/program.c

index 39c4ca1dd5de436c02720d598652fd983192347f..09a8494bd3670ba995f73b2160dda131665170b5 100644 (file)
@@ -426,6 +426,7 @@ replace_registers(struct prog_instruction *inst, GLuint numInst,
 {
    GLuint i, j;
    for (i = 0; i < numInst; i++) {
+      /* src regs */
       for (j = 0; j < _mesa_num_inst_src_regs(inst->Opcode); j++) {
          if (inst[i].SrcReg[j].File == oldFile &&
              inst[i].SrcReg[j].Index == oldIndex) {
@@ -433,6 +434,11 @@ replace_registers(struct prog_instruction *inst, GLuint numInst,
             inst[i].SrcReg[j].Index = newIndex;
          }
       }
+      /* dst reg */
+      if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
+         inst[i].DstReg.File = newFile;
+         inst[i].DstReg.Index = newIndex;
+      }
    }
 }
 
@@ -504,12 +510,25 @@ _mesa_combine_programs(GLcontext *ctx,
 
       newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
 
-      /* connect color outputs/inputs */
+      /* Connect color outputs of fprogA to color inputs of fprogB, via a
+       * new temporary register.
+       */
       if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
           (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
+         GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
+         if (!tempReg) {
+            _mesa_problem(ctx, "No free temp regs found in "
+                          "_mesa_combine_programs(), using 31");
+            tempReg = 31;
+         }
+         /* replace writes to result.color[0] with tempReg */
+         replace_registers(newInst, lenA,
+                           PROGRAM_OUTPUT, FRAG_RESULT_COLR,
+                           PROGRAM_TEMPORARY, tempReg);
+         /* replace reads from input.color[0] with tempReg */
          replace_registers(newInst + lenA, lenB,
                            PROGRAM_INPUT, FRAG_ATTRIB_COL0,
-                           PROGRAM_OUTPUT, FRAG_RESULT_COLR);
+                           PROGRAM_TEMPORARY, tempReg);
       }
 
       inputsB = progB->InputsRead;