diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-12-16 18:36:18 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-12-16 18:36:18 +1100 |
commit | 505e50de1019ca002408f0be6ded89ba714acfa7 (patch) | |
tree | 1670de8378119a80969a90252b8602683081df9f /src/mesa/pipe/nv40 | |
parent | ab4c2e014d4117d6ef43685a57c0ea1b93ba5562 (diff) |
nv40: grow fragprog as needed
Diffstat (limited to 'src/mesa/pipe/nv40')
-rw-r--r-- | src/mesa/pipe/nv40/nv40_fragprog.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/src/mesa/pipe/nv40/nv40_fragprog.c b/src/mesa/pipe/nv40/nv40_fragprog.c index e801dae8e1..f532eccd7b 100644 --- a/src/mesa/pipe/nv40/nv40_fragprog.c +++ b/src/mesa/pipe/nv40/nv40_fragprog.c @@ -39,7 +39,9 @@ struct nv40_fpc { uint colour_id; boolean inst_has_const; - int inst_const_id; + int inst_const_id; + + unsigned inst_offset; }; static INLINE struct nv40_sreg @@ -60,8 +62,18 @@ temp(struct nv40_fpc *fpc) (d), (m), (s0), none, none) static void -emit_src(struct nv40_fpc *fpc, uint32_t *hw, int pos, struct nv40_sreg src) +grow_insns(struct nv40_fpc *fpc, int size) { + struct nv40_fragment_program *fp = fpc->fp; + + fp->insn_len += size; + fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len); +} + +static void +emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src) +{ + uint32_t *hw = &fpc->fp->insn[fpc->inst_offset]; uint32_t sr = 0; switch (src.type) { @@ -103,9 +115,10 @@ emit_src(struct nv40_fpc *fpc, uint32_t *hw, int pos, struct nv40_sreg src) } static void -emit_dst(struct nv40_fpc *fpc, uint32_t *hw, struct nv40_sreg dst) +emit_dst(struct nv40_fpc *fpc, struct nv40_sreg dst) { struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; switch (dst.type) { case NV40SR_TEMP: @@ -135,7 +148,12 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) { struct nv40_fragment_program *fp = fpc->fp; - uint32_t *hw = &fp->insn[fp->insn_len]; + uint32_t *hw; + + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + memset(hw, 0, sizeof(uint32_t) * 4); fpc->inst_has_const = FALSE; @@ -156,17 +174,16 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, (dst.cc_swz[2] << NV40_FP_OP_COND_SWZ_Z_SHIFT) | (dst.cc_swz[3] << NV40_FP_OP_COND_SWZ_W_SHIFT)); - emit_dst(fpc, hw, dst); - emit_src(fpc, hw, 0, s0); - emit_src(fpc, hw, 1, s1); - emit_src(fpc, hw, 2, s2); + emit_dst(fpc, dst); + emit_src(fpc, 0, s0); + emit_src(fpc, 1, s1); + emit_src(fpc, 2, s2); - fp->insn_len += 4; if (fpc->inst_has_const) { + grow_insns(fpc, 4); fp->consts[fp->num_consts].pipe_id = fpc->inst_const_id; - fp->consts[fp->num_consts].hw_id = fp->insn_len; + fp->consts[fp->num_consts].hw_id = fpc->inst_offset + 4; fp->num_consts++; - fp->insn_len += 4; } } @@ -175,11 +192,8 @@ nv40_fp_tex(struct nv40_fpc *fpc, int sat, int op, int unit, struct nv40_sreg dst, int mask, struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) { - struct nv40_fragment_program *fp = fpc->fp; - uint32_t *hw = &fp->insn[fp->insn_len]; - nv40_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2); - hw[0] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT); + fpc->fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT); } static INLINE struct nv40_sreg @@ -622,7 +636,6 @@ nv40_fragprog_translate(struct nv40_context *nv40, fpc = calloc(1, sizeof(struct nv40_fpc)); if (!fpc) return; - fp->insn = calloc(1, 128*4*sizeof(uint32_t)); fpc->fp = fp; fpc->high_temp = -1; fp->num_regs = 2; @@ -667,12 +680,17 @@ nv40_fragprog_translate(struct nv40_context *nv40, } } - if (fpc->inst_has_const == FALSE) - fp->insn[fp->insn_len - 4] |= 0x00000001; - else - fp->insn[fp->insn_len - 8] |= 0x00000001; - fp->insn[fp->insn_len++] = 0x00000001; - + /* Terminate final instruction */ + fp->insn[fpc->inst_offset] |= 0x00000001; + + /* Append NOP + END instruction, may or may not be necessary. */ + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + fp->insn[fpc->inst_offset + 0] = 0x00000001; + fp->insn[fpc->inst_offset + 1] = 0x00000000; + fp->insn[fpc->inst_offset + 2] = 0x00000000; + fp->insn[fpc->inst_offset + 3] = 0x00000000; + fp->translated = TRUE; fp->on_hw = FALSE; out_err: |