summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2008-05-20 09:47:50 -0700
committerCorbin Simpson <[email protected]>2008-05-20 09:47:50 -0700
commit2bda1a9502206ca2b7b35e39c82356f91de06914 (patch)
treec94324fee7cb345cb4efebe811ca38bf7cd287dc /src/mesa
parent94994b13c51e076a4df069d550ec2f27550f6a28 (diff)
r5xx: Count refs so we don't have to guess on temp reg allocation.
As a bonus, we can now have multiple temp temps, by slot.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/r300/r500_fragprog.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c
index f7c5efcee27..5869dca9336 100644
--- a/src/mesa/drivers/dri/r300/r500_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r500_fragprog.c
@@ -134,8 +134,17 @@ static inline GLuint make_strq_swizzle(struct prog_src_register src) {
return swiz;
}
-static int get_temp(struct r500_fragment_program *fp) {
- return fp->max_temp_idx + 1;
+static int get_temp(struct r500_fragment_program *fp, int slot) {
+
+ COMPILE_STATE;
+
+ int r = cs->temp_in_use + 1 + slot;
+
+ if (r > R500_US_NUM_TEMP_REGS) {
+ ERROR("Too many temporary registers requested, can't compile!\n");
+ }
+
+ return r;
}
/* Borrowed verbatim from r300_fragprog since it hasn't changed. */
@@ -227,7 +236,7 @@ static void emit_tex(struct r500_fragment_program *fp,
hwsrc = make_src(fp, fpi->SrcReg[0]);
if (fpi->DstReg.File == PROGRAM_OUTPUT) {
- hwdest = get_temp(fp);
+ hwdest = get_temp(fp, 0);
} else {
hwdest = dest;
}
@@ -274,8 +283,8 @@ static void emit_tex(struct r500_fragment_program *fp,
counter++;
fp->inst[counter].inst0 = R500_INST_TYPE_OUT
| R500_INST_TEX_SEM_WAIT | (mask << 4);
- fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp));
- fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp));
+ fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0));
+ fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0));
fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0
| MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB)
| R500_ALU_RGB_SEL_B_SRC0
@@ -907,7 +916,7 @@ static void init_program(r300ContextPtr r300, struct r500_fragment_program *fp)
struct gl_fragment_program *mp = &fp->mesa_program;
struct prog_instruction *fpi;
GLuint InputsRead = mp->Base.InputsRead;
- GLuint temps_used = 0; /* for fp->temps[] */
+ GLuint temps_used = 0;
int i, j;
/* New compile, reset tracking data */
@@ -989,17 +998,23 @@ static void init_program(r300ContextPtr r300, struct r500_fragment_program *fp)
cs->inputs[i].reg = 0;
}
- /* Pre-parse the mesa program, grabbing refcounts on input/temp regs.
- * That way, we can free up the reg when it's no longer needed
- */
if (!mp->Base.Instructions) {
ERROR("No instructions found in program, going to go die now.\n");
return;
}
- fp->max_temp_idx = fp->temp_reg_offset + 1;
+ for (fpi = mp->Base.Instructions; fpi->Opcode != OPCODE_END; fpi++) {
+ for (i = 0; i < 3; i++) {
+ if (fpi->SrcReg[i].File == PROGRAM_TEMPORARY) {
+ if (fpi->SrcReg[i].Index > temps_used)
+ temps_used = fpi->SrcReg[i].Index;
+ }
+ }
+ }
cs->temp_in_use = temps_used;
+
+ fp->max_temp_idx = fp->temp_reg_offset + cs->temp_in_use + 1;
}
static void update_params(struct r500_fragment_program *fp)