summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBoyan Ding <[email protected]>2017-04-10 22:56:01 +0800
committerIlia Mirkin <[email protected]>2017-04-13 02:24:59 -0400
commit2a3c4c6bc31f300ef8a6a793a4cdeded66f6f778 (patch)
treebf2bc8baf09b2e53fd8b5e914d6e5cc90d8f92e1 /src/gallium
parentf1252996f5e067401c285eff7ae1eea837a107e5 (diff)
nvc0/ir: Allow 0/1 immediate value as source of OP_VOTE
Implementation of readFirstInvocationARB() on nvidia hardware needs a ballotARB(true) used to decide the first active thread. This expressed in gm107 asm as (supposing output is $r0): vote any $r0 0x1 0x1 To model the always true input, which corresponds to the second 0x1 above, we make OP_VOTE accept immediate value 0/1 and emit "0x1" and "not 0x1" in the src field respectively. v2: Make sure that asImm() is not NULL (Samuel Pitoiset) v3: (Ilia Mirkin) Make the handling more symmetric with predicate version in gm107 Use i->getSrc(s) Signed-off-by: Boyan Ding <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp24
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp23
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp24
3 files changed, 60 insertions, 11 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 2a6c773ba25..f2efb0c60bb 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -1621,7 +1621,8 @@ CodeEmitterGK110::emitSHFL(const Instruction *i)
void
CodeEmitterGK110::emitVOTE(const Instruction *i)
{
- assert(i->src(0).getFile() == FILE_PREDICATE);
+ const ImmediateValue *imm;
+ uint32_t u32;
code[0] = 0x00000002;
code[1] = 0x86c00000 | (i->subOp << 19);
@@ -1646,9 +1647,24 @@ CodeEmitterGK110::emitVOTE(const Instruction *i)
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);
+
+ switch (i->src(0).getFile()) {
+ case FILE_PREDICATE:
+ if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+ code[0] |= 1 << 13;
+ srcId(i->src(0), 42);
+ break;
+ case FILE_IMMEDIATE:
+ imm = i->getSrc(0)->asImm();
+ assert(imm);
+ u32 = imm->reg.data.u32;
+ assert(u32 == 0 || u32 == 1);
+ code[1] |= (u32 == 1 ? 0x7 : 0xf) << 10;
+ break;
+ default:
+ assert(!"Unhandled src");
+ break;
+ }
}
void
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 944563c93cf..b1645265565 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -2931,7 +2931,8 @@ CodeEmitterGM107::emitMEMBAR()
void
CodeEmitterGM107::emitVOTE()
{
- assert(insn->src(0).getFile() == FILE_PREDICATE);
+ const ImmediateValue *imm;
+ uint32_t u32;
int r = -1, p = -1;
for (int i = 0; insn->defExists(i); i++) {
@@ -2951,8 +2952,24 @@ CodeEmitterGM107::emitVOTE()
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));
+
+ switch (insn->src(0).getFile()) {
+ case FILE_PREDICATE:
+ emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
+ emitPRED (0x27, insn->src(0));
+ break;
+ case FILE_IMMEDIATE:
+ imm = insn->getSrc(0)->asImm();
+ assert(imm);
+ u32 = imm->reg.data.u32;
+ assert(u32 == 0 || u32 == 1);
+ emitPRED(0x27);
+ emitField(0x2a, 1, u32 == 0);
+ break;
+ default:
+ assert(!"Unhandled src");
+ break;
+ }
}
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 f4c39a168be..5ca86720544 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -2583,7 +2583,8 @@ CodeEmitterNVC0::emitSHFL(const Instruction *i)
void
CodeEmitterNVC0::emitVOTE(const Instruction *i)
{
- assert(i->src(0).getFile() == FILE_PREDICATE);
+ const ImmediateValue *imm;
+ uint32_t u32;
code[0] = 0x00000004 | (i->subOp << 5);
code[1] = 0x48000000;
@@ -2608,9 +2609,24 @@ CodeEmitterNVC0::emitVOTE(const Instruction *i)
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);
+
+ switch (i->src(0).getFile()) {
+ case FILE_PREDICATE:
+ if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+ code[0] |= 1 << 23;
+ srcId(i->src(0), 20);
+ break;
+ case FILE_IMMEDIATE:
+ imm = i->getSrc(0)->asImm();
+ assert(imm);
+ u32 = imm->reg.data.u32;
+ assert(u32 == 0 || u32 == 1);
+ code[0] |= (u32 == 1 ? 0x7 : 0xf) << 20;
+ break;
+ default:
+ assert(!"Unhandled src");
+ break;
+ }
}
bool