Christoph Bumiller
2009-Jun-20 18:48 UTC
[PATCH] nv50: move some stuff into nv50_program_tx_postprocess
The _postprocess function is called in nv50_program_tx and performs moving of FP outputs, will append clipping distance calculations, and converts unpaired half insn to long. --- src/gallium/drivers/nv50/nv50_program.c | 91 ++++++++++++++++--------------- 1 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 71a084e..7a4bc18 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -2024,6 +2024,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (depr != 0xffff) pc->result[depr*4+2].rhw = rid++; + pc->p->cfg.high_result = rid; } } @@ -2108,12 +2109,57 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) } } +static void +nv50fp_move_outputs(struct nv50_pc *pc) +{ + struct nv50_reg out; + int i; + + ctor_reg(&out, P_TEMP, -1, -1); + + for (i = 0; i < pc->result_nr * 4; i++) { + if (pc->result[i].rhw < 0) + continue; + out.hw = pc->result[i].rhw; + emit_mov(pc, &out, &pc->result[i]); + } +} + +static void nv50_program_tx_postprocess(struct nv50_pc *pc) +{ + struct nv50_program_exec *e, *e_prev = NULL; + unsigned pos; + + if (pc->p->type == PIPE_SHADER_FRAGMENT) + nv50fp_move_outputs(pc); + + for (e = pc->p->exec_head, pos = 0; e; e = e->next) { + pos += is_long(e) ? 2 : 1; + + if ((!e->next || is_long(e->next)) && (pos & 1)) { + convert_to_long(pc, e); + pos++; + } + e_prev = e->next ? e : e_prev; + } + + /* last instruction must be long */ + if (!is_long(pc->p->exec_tail)) { + convert_to_long(pc, pc->p->exec_tail); + convert_to_long(pc, e_prev); + } + + assert(!is_immd(pc->p->exec_head)); + assert(!is_immd(pc->p->exec_tail)); + + pc->p->exec_tail->inst[1] |= 0x00000001; +} + static boolean nv50_program_tx(struct nv50_program *p) { struct tgsi_parse_context parse; struct nv50_pc *pc; - unsigned k; boolean ret; pc = CALLOC_STRUCT(nv50_pc); @@ -2148,48 +2194,7 @@ nv50_program_tx(struct nv50_program *p) } } - if (p->type == PIPE_SHADER_FRAGMENT) { - struct nv50_reg out; - ctor_reg(&out, P_TEMP, -1, -1); - - for (k = 0; k < pc->result_nr * 4; k++) { - if (pc->result[k].rhw == -1) - continue; - if (pc->result[k].hw != pc->result[k].rhw) { - out.hw = pc->result[k].rhw; - emit_mov(pc, &out, &pc->result[k]); - } - if (pc->p->cfg.high_result < (pc->result[k].rhw + 1)) - pc->p->cfg.high_result = pc->result[k].rhw + 1; - } - } - - /* look for single half instructions and make them long */ - struct nv50_program_exec *e, *e_prev; - - for (k = 0, e = pc->p->exec_head, e_prev = NULL; e; e = e->next) { - if (!is_long(e)) - k++; - - if (!e->next || is_long(e->next)) { - if (k & 1) - convert_to_long(pc, e); - k = 0; - } - - if (e->next) - e_prev = e; - } - - if (!is_long(pc->p->exec_tail)) { - /* this may occur if moving FP results */ - assert(e_prev && !is_long(e_prev)); - convert_to_long(pc, e_prev); - convert_to_long(pc, pc->p->exec_tail); - } - - assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head)); - pc->p->exec_tail->inst[1] |= 0x00000001; + nv50_program_tx_postprocess(pc); p->param_nr = pc->param_nr * 4; p->immd_nr = pc->immd_nr * 4; -- 1.6.0.6 --------------090503050107050804030002 Content-Type: text/plain; name="0007-nv50-add-support-for-two-sided-lighting.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="0007-nv50-add-support-for-two-sided-lighting.patch"