[Mesa-dev] [PATCH 5/5] nvc0: add support for VOTE tgsi opcodes

Samuel Pitoiset samuel.pitoiset at gmail.com
Mon Jun 6 14:13:52 UTC 2016


Not surprising that code emission for VOTE was not totally correct 
because it was first attempt in that area and it was just impossible to 
test.

Assuming that now this thing is correct, this patch is:

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

On 05/29/2016 08:01 PM, Ilia Mirkin wrote:
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>  .../drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp | 23 ++++++++++++++----
>  .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 27 +++++++++++++---------
>  .../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp  | 23 ++++++++++++++----
>  .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 21 +++++++++++++++++
>  src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     |  5 ++--
>  5 files changed, 77 insertions(+), 22 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 80e0990..501d4af 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 a43d7b1..7e3cd8b 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> @@ -2790,21 +2790,26 @@ CodeEmitterGM107::emitVOTE()
>  {
>     int subOp;
>
> -   assert(insn->src(0).getFile() == FILE_PREDICATE &&
> -          insn->def(1).getFile() == FILE_PREDICATE);
> +   assert(insn->src(0).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 9159e34..9e45c25 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> @@ -2468,16 +2468,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 cd98f70..d995cc8 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;
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> index 934998c..b9437b2 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> @@ -230,11 +230,11 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
>     case PIPE_CAP_CULL_DISTANCE:
>     case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
>     case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
> +   case PIPE_CAP_COMPUTE:
> +   case PIPE_CAP_TGSI_VOTE:
>        return 1;
>     case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
>        return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
> -   case PIPE_CAP_COMPUTE:
> -      return 1;
>     case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
>        return nouveau_screen(pscreen)->vram_domain & NOUVEAU_BO_VRAM ? 1 : 0;
>
> @@ -261,7 +261,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
>     case PIPE_CAP_PCI_BUS:
>     case PIPE_CAP_PCI_DEVICE:
>     case PIPE_CAP_PCI_FUNCTION:
> -   case PIPE_CAP_TGSI_VOTE:
>        return 0;
>
>     case PIPE_CAP_VENDOR_ID:
>

-- 
-Samuel


More information about the mesa-dev mailing list