diff options
author | Boyan Ding <[email protected]> | 2017-04-10 22:56:01 +0800 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2017-04-13 02:24:59 -0400 |
commit | 2a3c4c6bc31f300ef8a6a793a4cdeded66f6f778 (patch) | |
tree | bf2bc8baf09b2e53fd8b5e914d6e5cc90d8f92e1 /src | |
parent | f1252996f5e067401c285eff7ae1eea837a107e5 (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')
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 |