r300/compiler: compute the final number of temporaries during translation
authorMarek Olšák <maraeo@gmail.com>
Wed, 1 Sep 2010 06:10:32 +0000 (08:10 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 4 Sep 2010 16:56:21 +0000 (18:56 +0200)
And not during the register allocation, which may be skipped for debugging
purposes. Also the predicate register is now added to the number of temps.

src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c

index 8c3177f1f2673eaebbd2a1b084bec25d9884f704..e9fb49e7c13777d3f2a5a39ec6650af9e670da35 100644 (file)
@@ -475,18 +475,20 @@ static void translate_vertex_program(struct radeon_compiler *c, void *user)
 
        compiler->code->pos_end = 0;    /* Not supported yet */
        compiler->code->length = 0;
+       compiler->code->num_temporaries = 0;
 
        compiler->SetHwInputOutput(compiler);
 
        for(rci = compiler->Base.Program.Instructions.Next; rci != &compiler->Base.Program.Instructions; rci = rci->Next) {
                struct rc_sub_instruction *vpi = &rci->U.I;
                unsigned int *inst = compiler->code->body.d + compiler->code->length;
+               const struct rc_opcode_info *info = rc_get_opcode_info(vpi->Opcode);
 
                /* Skip instructions writing to non-existing destination */
                if (!valid_dst(compiler->code, &vpi->DstReg))
                        continue;
 
-               if (rc_get_opcode_info(vpi->Opcode)->HasDstReg) {
+               if (info->HasDstReg) {
                        /* Relative addressing of destination operands is not supported yet. */
                        if (vpi->DstReg.RelAddr) {
                                rc_error(&compiler->Base, "Vertex program does not support relative "
@@ -608,7 +610,7 @@ static void translate_vertex_program(struct radeon_compiler *c, void *user)
                }
 
                default:
-                       rc_error(&compiler->Base, "Unknown opcode %s\n", rc_get_opcode_info(vpi->Opcode)->Name);
+                       rc_error(&compiler->Base, "Unknown opcode %s\n", info->Name);
                        return;
                }
 
@@ -625,6 +627,25 @@ static void translate_vertex_program(struct radeon_compiler *c, void *user)
                                                << PVS_DST_PRED_SENSE_SHIFT);
                }
 
+               /* Update the number of temporaries. */
+               if (info->HasDstReg && vpi->DstReg.File == RC_FILE_TEMPORARY &&
+                   vpi->DstReg.Index >= compiler->code->num_temporaries)
+                       compiler->code->num_temporaries = vpi->DstReg.Index + 1;
+
+               for (unsigned i = 0; i < info->NumSrcRegs; i++)
+                       if (vpi->SrcReg[i].File == RC_FILE_TEMPORARY &&
+                           vpi->SrcReg[i].Index >= compiler->code->num_temporaries)
+                               compiler->code->num_temporaries = vpi->SrcReg[i].Index + 1;
+
+               if (compiler->PredicateMask)
+                       if (compiler->PredicateIndex >= compiler->code->num_temporaries)
+                               compiler->code->num_temporaries = compiler->PredicateIndex + 1;
+
+               if (compiler->code->num_temporaries > compiler->Base.max_temp_regs) {
+                       rc_error(&compiler->Base, "Too many temporaries.\n");
+                       return;
+               }
+
                compiler->code->length += 4;
 
                if (compiler->Base.Error)
@@ -668,7 +689,6 @@ static void allocate_temporary_registers(struct radeon_compiler *c, void *user)
                        }
                }
        }
-       compiler->code->num_temporaries = num_orig_temps;
 
        /* Pass 2: If there is relative addressing of temporaries, we cannot change register indices. Give up. */
        for (inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
@@ -686,7 +706,6 @@ static void allocate_temporary_registers(struct radeon_compiler *c, void *user)
                }
        }
 
-       compiler->code->num_temporaries = 0;
        ta = (struct temporary_allocation*)memory_pool_malloc(&compiler->Base.Pool,
                        sizeof(struct temporary_allocation) * num_orig_temps);
        memset(ta, 0, sizeof(struct temporary_allocation) * num_orig_temps);
@@ -755,9 +774,6 @@ static void allocate_temporary_registers(struct radeon_compiler *c, void *user)
                                                ta[orig].Allocated = 1;
                                                ta[orig].HwTemp = j;
                                                hwtemps[j] = 1;
-
-                                               if (j >= compiler->code->num_temporaries)
-                                                       compiler->code->num_temporaries = j + 1;
                                        }
                                }