summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/nv50_program.c
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2009-12-24 12:39:42 +0100
committerChristoph Bumiller <[email protected]>2009-12-24 12:48:00 +0100
commitd29f55546dec74ca77dce3a3bf581c251be1d397 (patch)
tree37715047ca16895352a49a98f26f2395d34cb41d /src/gallium/drivers/nv50/nv50_program.c
parentb5a408bae518ededbb871d113dab89f3e15bfb45 (diff)
nv50: make edgeflags work
It doesn't seem to be possible to set the egdeflag in the vertex shader, so we need to fallback to pushing vertices through the FIFO and use method 0x15e4 if they are used. This only works if VP does MOV OUT[X] IN[Y] where X is the edgeflag output, and Y is saved so we can tell the correct input later. The VP still writes the useless values to wasted outputs as punishment.
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_program.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 679c28ce4b1..ce3fa5fc88b 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -159,6 +159,8 @@ struct nv50_pc {
unsigned insn_nr;
boolean allow32;
+
+ uint8_t edgeflag_out;
};
static INLINE struct nv50_reg *
@@ -2554,10 +2556,16 @@ prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)
mask = dst->WriteMask;
if (dst->File == TGSI_FILE_TEMPORARY)
- reg = pc->temp;
+ reg = pc->temp;
else
- if (dst->File == TGSI_FILE_OUTPUT)
- reg = pc->result;
+ if (dst->File == TGSI_FILE_OUTPUT) {
+ reg = pc->result;
+
+ if (insn->Instruction.Opcode == TGSI_OPCODE_MOV &&
+ dst->Index == pc->edgeflag_out &&
+ insn->Src[0].Register.File == TGSI_FILE_INPUT)
+ pc->p->cfg.edgeflag_in = insn->Src[0].Register.Index;
+ }
if (reg) {
for (c = 0; c < 4; c++) {
@@ -2856,6 +2864,9 @@ nv50_program_tx_prep(struct nv50_pc *pc)
if (p->cfg.io_nr > first)
p->cfg.io_nr = first;
break;
+ case TGSI_SEMANTIC_EDGEFLAG:
+ pc->edgeflag_out = first;
+ break;
/*
case TGSI_SEMANTIC_CLIP_DISTANCE:
p->cfg.clpd = MIN2(p->cfg.clpd, first);
@@ -3104,6 +3115,8 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p)
p->cfg.two_side[0].hw = 0x40;
p->cfg.two_side[1].hw = 0x40;
+ p->cfg.edgeflag_in = pc->edgeflag_out = 0xff;
+
switch (p->type) {
case PIPE_SHADER_VERTEX:
p->cfg.psiz = 0x40;