summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h2
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp14
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp15
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp14
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp7
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp31
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h1
7 files changed, 81 insertions, 3 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
index 16dc1d1..1f7de51 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
@@ -146,6 +146,8 @@ struct nv50_ir_prog_info
bool earlyFragTests;
bool separateFragData;
bool usesDiscard;
+ bool persampleInvocation;
+ bool usesSampleMaskIn;
} fp;
struct {
uint32_t inputOffset; /* base address for user args */
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
index 83009c5..6a5981d 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -1113,12 +1113,26 @@ CodeEmitterGK110::emitSLCT(const CmpInstruction *i)
}
}
+static void
+selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
+{
+ int loc = entry->loc;
+ if (data.force_persample_interp)
+ code[loc + 1] |= 1 << 13;
+ else
+ code[loc + 1] &= ~(1 << 13);
+}
+
void CodeEmitterGK110::emitSELP(const Instruction *i)
{
emitForm_21(i, 0x250, 0x050);
if (i->src(2).mod & Modifier(NV50_IR_MOD_NOT))
code[1] |= 1 << 13;
+
+ if (i->subOp == 1) {
+ addInterp(0, 0, selpFlip);
+ }
}
void CodeEmitterGK110::emitTEXBAR(const Instruction *i)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 9dc2e30..a43d7b1 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -894,6 +894,16 @@ CodeEmitterGM107::emitI2I()
emitGPR (0x00, insn->def(0));
}
+static void
+selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
+{
+ int loc = entry->loc;
+ if (data.force_persample_interp)
+ code[loc + 1] |= 1 << 10;
+ else
+ code[loc + 1] &= ~(1 << 10);
+}
+
void
CodeEmitterGM107::emitSEL()
{
@@ -915,9 +925,14 @@ CodeEmitterGM107::emitSEL()
break;
}
+ emitINV (0x2a, insn->src(2));
emitPRED(0x27, insn->src(2));
emitGPR (0x08, insn->src(0));
emitGPR (0x00, insn->def(0));
+
+ if (insn->subOp == 1) {
+ addInterp(0, 0, selpFlip);
+ }
}
void
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
index 8819e3b..14f4be4 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -1177,12 +1177,26 @@ CodeEmitterNVC0::emitSLCT(const CmpInstruction *i)
code[0] |= 1 << 5;
}
+static void
+selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
+{
+ int loc = entry->loc;
+ if (data.force_persample_interp)
+ code[loc + 1] |= 1 << 20;
+ else
+ code[loc + 1] &= ~(1 << 20);
+}
+
void CodeEmitterNVC0::emitSELP(const Instruction *i)
{
emitForm_A(i, HEX64(20000000, 00000004));
if (i->src(2).mod & Modifier(NV50_IR_MOD_NOT))
code[1] |= 1 << 20;
+
+ if (i->subOp == 1) {
+ addInterp(0, 0, selpFlip);
+ }
}
void CodeEmitterNVC0::emitTEXBAR(const Instruction *i)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index d59950e..69e1a34 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -1273,6 +1273,13 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
case TGSI_SEMANTIC_DRAWID:
info->prop.vp.usesDrawParameters = true;
break;
+ case TGSI_SEMANTIC_SAMPLEID:
+ case TGSI_SEMANTIC_SAMPLEPOS:
+ info->prop.fp.persampleInvocation = true;
+ break;
+ case TGSI_SEMANTIC_SAMPLEMASK:
+ info->prop.fp.usesSampleMaskIn = true;
+ break;
default:
break;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index 3bce962..1068c21 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -153,6 +153,7 @@ NVC0LegalizeSSA::visit(BasicBlock *bb)
NVC0LegalizePostRA::NVC0LegalizePostRA(const Program *prog)
: rZero(NULL),
carry(NULL),
+ pOne(NULL),
needTexBar(prog->getTarget()->getChipset() >= 0xe0)
{
}
@@ -451,10 +452,12 @@ NVC0LegalizePostRA::visit(Function *fn)
insertTextureBarriers(fn);
rZero = new_LValue(fn, FILE_GPR);
+ pOne = new_LValue(fn, FILE_PREDICATE);
carry = new_LValue(fn, FILE_FLAGS);
rZero->reg.data.id = prog->getTarget()->getFileSize(FILE_GPR);
carry->reg.data.id = 0;
+ pOne->reg.data.id = 7;
return true;
}
@@ -466,8 +469,15 @@ NVC0LegalizePostRA::replaceZero(Instruction *i)
if (s == 2 && i->op == OP_SUCLAMP)
continue;
ImmediateValue *imm = i->getSrc(s)->asImm();
- if (imm && imm->reg.data.u64 == 0)
- i->setSrc(s, rZero);
+ if (imm) {
+ if (i->op == OP_SELP && s == 2) {
+ i->setSrc(s, pOne);
+ if (imm->reg.data.u64 == 0)
+ i->src(s).mod = i->src(s).mod ^ Modifier(NV50_IR_MOD_NOT);
+ } else if (imm->reg.data.u64 == 0) {
+ i->setSrc(s, rZero);
+ }
+ }
}
}
@@ -2204,10 +2214,25 @@ NVC0LoweringPass::handleRDSV(Instruction *i)
off);
break;
}
- case SV_SAMPLE_MASK:
+ case SV_SAMPLE_MASK: {
ld = bld.mkOp1(OP_PIXLD, TYPE_U32, i->getDef(0), bld.mkImm(0));
ld->subOp = NV50_IR_SUBOP_PIXLD_COVMASK;
+ Instruction *sampleid =
+ bld.mkOp1(OP_PIXLD, TYPE_U32, bld.getSSA(), bld.mkImm(0));
+ sampleid->subOp = NV50_IR_SUBOP_PIXLD_SAMPLEID;
+ Value *masked =
+ bld.mkOp2v(OP_AND, TYPE_U32, bld.getSSA(), ld->getDef(0),
+ bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
+ bld.loadImm(NULL, 1), sampleid->getDef(0)));
+ if (prog->driver->prop.fp.persampleInvocation) {
+ bld.mkMov(i->getDef(0), masked);
+ } else {
+ bld.mkOp3(OP_SELP, TYPE_U32, i->getDef(0), ld->getDef(0), masked,
+ bld.mkImm(0))
+ ->subOp = 1;
+ }
break;
+ }
case SV_BASEVERTEX:
case SV_BASEINSTANCE:
case SV_DRAWID:
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
index 17883a9..c007e09 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
@@ -79,6 +79,7 @@ private:
private:
LValue *rZero;
LValue *carry;
+ LValue *pOne;
const bool needTexBar;
};