nvc0: add support for GL_EXT_demote_to_helper_invocation
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 2 Oct 2019 23:47:00 +0000 (19:47 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 8 Oct 2019 00:42:11 +0000 (20:42 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c

index c3e3cf2dff594683972fee76924d1fb40b028239..d62d36008e618d3fd3804b03d096bb2e3c4e5b07 100644 (file)
@@ -821,6 +821,7 @@ static nv50_ir::operation translateOpcode(uint opcode)
    NV50_IR_OPCODE_CASE(DDY, DFDY);
    NV50_IR_OPCODE_CASE(DDY_FINE, DFDY);
    NV50_IR_OPCODE_CASE(KILL, DISCARD);
+   NV50_IR_OPCODE_CASE(DEMOTE, DISCARD);
 
    NV50_IR_OPCODE_CASE(SEQ, SET);
    NV50_IR_OPCODE_CASE(SGT, SET);
@@ -1581,6 +1582,9 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
    if (insn.getOpcode() == TGSI_OPCODE_INTERP_SAMPLE)
       info->prop.fp.readsSampleLocations = true;
 
+   if (insn.getOpcode() == TGSI_OPCODE_DEMOTE)
+      info->prop.fp.usesDiscard = true;
+
    if (insn.dstCount()) {
       Instruction::DstRegister dst = insn.getDst(0);
 
@@ -3463,6 +3467,11 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
       if (!tgsi.getDst(0).isMasked(1))
          mkOp1(OP_RDSV, TYPE_U32, dst0[1], mkSysVal(SV_CLOCK, 0))->fixed = 1;
       break;
+   case TGSI_OPCODE_READ_HELPER:
+      if (!tgsi.getDst(0).isMasked(0))
+         mkOp1(OP_RDSV, TYPE_U32, dst0[0], mkSysVal(SV_THREAD_KILL, 0))
+            ->fixed = 1;
+      break;
    case TGSI_OPCODE_KILL_IF:
       val0 = new_LValue(func, FILE_PREDICATE);
       mask = 0;
@@ -3476,6 +3485,9 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
       }
       break;
    case TGSI_OPCODE_KILL:
+   case TGSI_OPCODE_DEMOTE:
+      // TODO: Should we make KILL exit that invocation? Some old shaders
+      // don't like that.
       mkOp(OP_DISCARD, TYPE_NONE, NULL);
       break;
    case TGSI_OPCODE_TEX:
index 557139494d4e4b9fb534a26f86a7dcb0f4f696c0..f0846867621bc8db0a4f8f9b848ccd96e78564f4 100644 (file)
@@ -330,6 +330,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_FBFETCH_COHERENT:
    case PIPE_CAP_TGSI_SKIP_SHRINK_IO_ARRAYS:
    case PIPE_CAP_TGSI_ATOMINC_WRAP:
+   case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index 435c3058a8941fc11c61c620aaf450510df65553..06f1fb2b7088da0a4024ed1daf4ac97d0400d18d 100644 (file)
@@ -281,6 +281,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_DEST_SURFACE_SRGB_CONTROL:
    case PIPE_CAP_TGSI_DIV:
    case PIPE_CAP_TGSI_ATOMINC_WRAP:
+   case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION:
       return 1;
    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
       return nouveau_screen(pscreen)->vram_domain & NOUVEAU_BO_VRAM ? 1 : 0;