[Mesa-dev] [PATCH v2 5/9] nvc0/ir: Allow 0/1 immediate value as source of OP_VOTE

Ilia Mirkin imirkin at alum.mit.edu
Mon Apr 10 01:40:30 UTC 2017


On Sun, Apr 9, 2017 at 8:58 PM, Boyan Ding <boyan.j.ding at gmail.com> wrote:
> 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)
> ---
>  .../drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp | 24 ++++++++++++++++++----
>  .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 22 +++++++++++++++++---
>  .../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp  | 24 ++++++++++++++++++----
>  3 files changed, 59 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 58076ba4d5..87976ffebc 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->src(0).get()->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 944563c93c..0382cb3903 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,23 @@ 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->src(0).get()->asImm();
> +      assert(imm);
> +      u32 = imm->reg.data.u32;
> +      assert(u32 == 0 || u32 == 1);
> +      emitField(0x27, 4, u32 == 1 ? 0x7 : 0xf);

I'd kinda prefer this to be

emitField(0x2a, 1, u32 == 0);
emitPRED(0x27);

That way you have symmetry with the predicate version. Unfortunately
this is tricky to do in the other emitters -- the helpers in gm107 are
*way* better (well, Ben probably learned from the earlier failures).
So don't worry about trying to do it in the other ones.

> +      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 ee2d2f06c1..84c3aca1df 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> @@ -2587,7 +2587,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;
> @@ -2612,9 +2613,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->src(0).get()->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
> --
> 2.12.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list