diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-11-25 11:25:32 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-11-25 11:25:32 +1100 |
commit | 8b1c8f5e758e161bacee3f5eca2fd531f2bf56aa (patch) | |
tree | 6f6a006bebcc43b622832a4a6464ab57500f10b7 /src | |
parent | 558f3abb49475ba0aad585e7fb0c07121aecde6f (diff) |
nv40: fp arbitrary swizzling/negation
Pretty bad implementation, goal was to get glBitmap working.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/pipe/nv40/nv40_fragprog.c | 79 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_shader.h | 2 |
2 files changed, 81 insertions, 0 deletions
diff --git a/src/mesa/pipe/nv40/nv40_fragprog.c b/src/mesa/pipe/nv40/nv40_fragprog.c index 09b68513ba..e6fee2bf5a 100644 --- a/src/mesa/pipe/nv40/nv40_fragprog.c +++ b/src/mesa/pipe/nv40/nv40_fragprog.c @@ -4,6 +4,7 @@ #include "pipe/tgsi/exec/tgsi_token.h" #include "pipe/tgsi/exec/tgsi_parse.h" +#include "pipe/tgsi/exec/tgsi_util.h" #include "nv40_context.h" #include "nv40_dma.h" @@ -263,6 +264,66 @@ tgsi_mask(uint tgsi) } static boolean +src_native_swz(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc, + struct nv40_sreg *src) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg tgsi = tgsi_src(fpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= (1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= (1 << c); + } + + if (mask == MASK_ALL) + return TRUE; + + *src = temp(fpc); + + if (mask) + arith(fpc, 0, MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(fpc, 0, SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(fpc, 0, STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv40_sreg one = temp(fpc); + arith(fpc, 0, STR, one, neg_mask, one, none, none); + arith(fpc, 0, MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + +static boolean nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, const struct tgsi_full_instruction *finst) { @@ -289,6 +350,18 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc; fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(fpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + switch (fsrc->SrcRegister.File) { case TGSI_FILE_INPUT: if (ai == -1 || ai == fsrc->SrcRegister.Index) { @@ -625,6 +698,12 @@ nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) if (!fp->buffer) fp->buffer = ws->buffer_create(ws, 0x100); +#if 0 + int i; + for (i = 0; i < fp->insn_len; i++) + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); +#endif + nv40->pipe.winsys->buffer_data(nv40->pipe.winsys, fp->buffer, fp->insn_len * sizeof(uint32_t), fp->insn, diff --git a/src/mesa/pipe/nv40/nv40_shader.h b/src/mesa/pipe/nv40/nv40_shader.h index 855562eb0d..207dafd748 100644 --- a/src/mesa/pipe/nv40/nv40_shader.h +++ b/src/mesa/pipe/nv40/nv40_shader.h @@ -353,6 +353,8 @@ # define NV40_FP_OP_OPCODE_RCP 0x1A # define NV40_FP_OP_OPCODE_EX2 0x1C # define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_STR 0x20 +# define NV40_FP_OP_OPCODE_SFL 0x21 # define NV40_FP_OP_OPCODE_COS 0x22 # define NV40_FP_OP_OPCODE_SIN 0x23 # define NV40_FP_OP_OPCODE_PK2H 0x24 |