From: Kristian H. Kristensen Date: Wed, 23 Oct 2019 01:19:50 +0000 (-0700) Subject: freedreno/ir3: Add new synchronization opcodes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=581cd596928bf6bc34ef806e4f015a86ab82f728;p=mesa.git freedreno/ir3: Add new synchronization opcodes There are two new opcodes in use in tesselation control shaders: category 0, opcodes 13 and 15. unk13 is a kill type of instruction that terminates threads where !p0.x and it used to narrow down a patch wavefront to just thread 0. Then, once thread 0 has written the tess levels, it issues unk15, which might signal the TE that another patch has been fully written. Signed-off-by: Kristian H. Kristensen Acked-by: Eric Anholt Reviewed-by: Rob Clark --- diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c index 344bb7bd98c..85a9c9e5d71 100644 --- a/src/freedreno/ir3/disasm-a3xx.c +++ b/src/freedreno/ir3/disasm-a3xx.c @@ -166,6 +166,7 @@ static void print_instr_cat0(struct disasm_ctx *ctx, instr_t *instr) switch (cat0->opc) { case OPC_KILL: + case OPC_CONDEND: fprintf(ctx->out, " %sp0.%c", cat0->inv ? "!" : "", component[cat0->comp]); break; @@ -908,6 +909,8 @@ static const struct opc_info { OPC(0, OPC_CHMASK, chmask), OPC(0, OPC_CHSH, chsh), OPC(0, OPC_FLOW_REV, flow_rev), + OPC(0, OPC_CONDEND, condend), + OPC(0, OPC_ENDPATCH, endpatch), /* category 1: */ OPC(1, OPC_MOV, ), diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index 9ad07d3173e..9f460c9cdce 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -51,6 +51,9 @@ typedef enum { OPC_CHSH = _OPC(0, 10), OPC_FLOW_REV = _OPC(0, 11), + OPC_CONDEND = _OPC(0, 13), + OPC_ENDPATCH = _OPC(0, 15), + /* category 1: */ OPC_MOV = _OPC(1, 0), diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index fa7aa418027..a0a2dcbd805 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -154,6 +154,9 @@ static int emit_cat0(struct ir3_instruction *instr, void *ptr, cat0->sync = !!(instr->flags & IR3_INSTR_SY); cat0->opc_cat = 0; + if (instr->opc == OPC_CONDEND || instr->opc == OPC_ENDPATCH) + cat0->dummy4 = 16; + return 0; } diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 7e69e8ea8ed..436feca2374 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -614,7 +614,7 @@ static inline bool is_flow(struct ir3_instruction *instr) static inline bool is_kill(struct ir3_instruction *instr) { - return instr->opc == OPC_KILL; + return instr->opc == OPC_KILL || instr->opc == OPC_CONDEND; } static inline bool is_nop(struct ir3_instruction *instr) @@ -1309,6 +1309,8 @@ INSTR1(KILL) INSTR0(END) INSTR0(CHSH) INSTR0(CHMASK) +INSTR1(CONDEND) +INSTR0(ENDPATCH) /* cat2 instructions, most 2 src but some 1 src: */ INSTR2(ADD_F) diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 53fd4f919ee..a7c41b36b10 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -136,6 +136,9 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) last_input_needs_ss = false; } + if (last_n && opc_cat(last_n->opc) == 0 && opc_op(last_n->opc) == 13) + n->flags |= IR3_INSTR_SS; + /* NOTE: consider dst register too.. it could happen that * texture sample instruction (for example) writes some * components which are unused. A subsequent instruction