summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-11-25 11:25:32 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-11-25 11:25:32 +1100
commit8b1c8f5e758e161bacee3f5eca2fd531f2bf56aa (patch)
tree6f6a006bebcc43b622832a4a6464ab57500f10b7 /src
parent558f3abb49475ba0aad585e7fb0c07121aecde6f (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.c79
-rw-r--r--src/mesa/pipe/nv40/nv40_shader.h2
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