summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/codegen
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-05-29 12:42:49 -0400
committerIlia Mirkin <[email protected]>2016-06-06 20:49:29 -0400
commit704bc0f0e98f3bbdef33cad12646d4e1bf01e8aa (patch)
treeecac8a3b25184756337e8409eeedcc8a160c1eb7 /src/gallium/drivers/nouveau/codegen
parentf64c36e2d7cdf14a43cde7963729a926e613dc4c (diff)
nvc0: add support for VOTE tgsi opcodes
Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp23
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp29
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp23
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp21
4 files changed, 75 insertions, 21 deletions
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 80e09900bc6..501d4af7915 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -1481,16 +1481,31 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
void
CodeEmitterGK110::emitVOTE(const Instruction *i)
{
- assert(i->src(0).getFile() == FILE_PREDICATE &&
- i->def(1).getFile() == FILE_PREDICATE);
+ assert(i->src(0).getFile() == FILE_PREDICATE);
code[0] = 0x00000002;
code[1] = 0x86c00000 | (i->subOp << 19);
emitPredicate(i);
- defId(i->def(0), 2);
- defId(i->def(1), 48);
+ unsigned rp = 0;
+ for (int d = 0; i->defExists(d); d++) {
+ if (i->def(d).getFile() == FILE_PREDICATE) {
+ assert(!(rp & 2));
+ rp |= 2;
+ defId(i->def(d), 48);
+ } else if (i->def(d).getFile() == FILE_GPR) {
+ assert(!(rp & 1));
+ rp |= 1;
+ defId(i->def(d), 2);
+ } else {
+ assert(!"Unhandled def");
+ }
+ }
+ if (!(rp & 1))
+ code[0] |= 255 << 2;
+ if (!(rp & 2))
+ code[1] |= 7 << 16;
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
code[1] |= 1 << 13;
srcId(i->src(0), 42);
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 a43d7b1296a..ef02dbb4c63 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -2788,23 +2788,26 @@ CodeEmitterGM107::emitMEMBAR()
void
CodeEmitterGM107::emitVOTE()
{
- int subOp;
+ assert(insn->src(0).getFile() == FILE_PREDICATE);
- assert(insn->src(0).getFile() == FILE_PREDICATE &&
- insn->def(1).getFile() == FILE_PREDICATE);
-
- switch (insn->subOp) {
- case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
- default:
- assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
- subOp = 0;
- break;
+ int r = -1, p = -1;
+ for (int i = 0; insn->defExists(i); i++) {
+ if (insn->def(i).getFile() == FILE_GPR)
+ r = i;
+ else if (insn->def(i).getFile() == FILE_PREDICATE)
+ p = i;
}
emitInsn (0x50d80000);
- emitField(0x30, 2, subOp);
- emitGPR (0x00, insn->def(0));
- emitPRED (0x2d, insn->def(1));
+ emitField(0x30, 2, insn->subOp);
+ if (r >= 0)
+ emitGPR (0x00, insn->def(r));
+ else
+ emitGPR (0x00);
+ if (p >= 0)
+ emitPRED (0x2d, insn->def(p));
+ else
+ emitPRED (0x2d);
emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
emitPRED (0x27, insn->src(0));
}
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 bc94285120e..1c3e5198c96 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -2472,16 +2472,31 @@ CodeEmitterNVC0::emitPIXLD(const Instruction *i)
void
CodeEmitterNVC0::emitVOTE(const Instruction *i)
{
- assert(i->src(0).getFile() == FILE_PREDICATE &&
- i->def(1).getFile() == FILE_PREDICATE);
+ assert(i->src(0).getFile() == FILE_PREDICATE);
code[0] = 0x00000004 | (i->subOp << 5);
code[1] = 0x48000000;
emitPredicate(i);
- defId(i->def(0), 14);
- defId(i->def(1), 32 + 22);
+ unsigned rp = 0;
+ for (int d = 0; i->defExists(d); d++) {
+ if (i->def(d).getFile() == FILE_PREDICATE) {
+ assert(!(rp & 2));
+ rp |= 2;
+ defId(i->def(d), 32 + 22);
+ } else if (i->def(d).getFile() == FILE_GPR) {
+ assert(!(rp & 1));
+ rp |= 1;
+ defId(i->def(d), 14);
+ } else {
+ assert(!"Unhandled def");
+ }
+ }
+ if (!(rp & 1))
+ code[0] |= 63 << 14;
+ if (!(rp & 2))
+ code[1] |= 7 << 22;
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
code[0] |= 1 << 23;
srcId(i->src(0), 20);
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 beb7b5310bf..ed3249e67b1 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -548,6 +548,9 @@ nv50_ir::DataType Instruction::inferSrcType() const
case TGSI_OPCODE_UBFE:
case TGSI_OPCODE_UMSB:
case TGSI_OPCODE_UP2H:
+ case TGSI_OPCODE_VOTE_ALL:
+ case TGSI_OPCODE_VOTE_ANY:
+ case TGSI_OPCODE_VOTE_EQ:
return nv50_ir::TYPE_U32;
case TGSI_OPCODE_I2F:
case TGSI_OPCODE_I2D:
@@ -835,6 +838,10 @@ static nv50_ir::operation translateOpcode(uint opcode)
NV50_IR_OPCODE_CASE(IMSB, BFIND);
NV50_IR_OPCODE_CASE(UMSB, BFIND);
+ NV50_IR_OPCODE_CASE(VOTE_ALL, VOTE);
+ NV50_IR_OPCODE_CASE(VOTE_ANY, VOTE);
+ NV50_IR_OPCODE_CASE(VOTE_EQ, VOTE);
+
NV50_IR_OPCODE_CASE(END, EXIT);
default:
@@ -861,6 +868,9 @@ static uint16_t opcodeToSubOp(uint opcode)
case TGSI_OPCODE_IMUL_HI:
case TGSI_OPCODE_UMUL_HI:
return NV50_IR_SUBOP_MUL_HIGH;
+ case TGSI_OPCODE_VOTE_ALL: return NV50_IR_SUBOP_VOTE_ALL;
+ case TGSI_OPCODE_VOTE_ANY: return NV50_IR_SUBOP_VOTE_ANY;
+ case TGSI_OPCODE_VOTE_EQ: return NV50_IR_SUBOP_VOTE_UNI;
default:
return 0;
}
@@ -3187,6 +3197,17 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
mkCmp(op, tgsi.getSetCond(), dstTy, dst0[c], srcTy, src0, src1);
}
break;
+ case TGSI_OPCODE_VOTE_ALL:
+ case TGSI_OPCODE_VOTE_ANY:
+ case TGSI_OPCODE_VOTE_EQ:
+ val0 = new_LValue(func, FILE_PREDICATE);
+ FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
+ mkCmp(OP_SET, CC_NE, TYPE_U32, val0, TYPE_U32, fetchSrc(0, c), zero);
+ mkOp1(op, dstTy, val0, val0)
+ ->subOp = tgsi::opcodeToSubOp(tgsi.getOpcode());
+ mkCvt(OP_CVT, TYPE_U32, dst0[c], TYPE_U8, val0);
+ }
+ break;
case TGSI_OPCODE_KILL_IF:
val0 = new_LValue(func, FILE_PREDICATE);
mask = 0;