From 738bbee603fd3fd8ea29edab7b681e48bc981467 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Wed, 2 Oct 2019 19:47:00 -0400 Subject: [PATCH] nvc0: add support for GL_EXT_demote_to_helper_invocation Signed-off-by: Ilia Mirkin --- .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 12 ++++++++++++ src/gallium/drivers/nouveau/nv50/nv50_screen.c | 1 + src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 1 + 3 files changed, 14 insertions(+) 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 c3e3cf2dff5..d62d36008e6 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -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: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 557139494d4..f0846867621 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -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: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 435c3058a89..06f1fb2b708 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -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;