freedreno/ir3: Add new synchronization opcodes
authorKristian H. Kristensen <hoegsberg@google.com>
Wed, 23 Oct 2019 01:19:50 +0000 (18:19 -0700)
committerKristian H. Kristensen <hoegsberg@google.com>
Fri, 8 Nov 2019 00:37:02 +0000 (16:37 -0800)
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 <hoegsberg@google.com>
Acked-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/freedreno/ir3/disasm-a3xx.c
src/freedreno/ir3/instr-a3xx.h
src/freedreno/ir3/ir3.c
src/freedreno/ir3/ir3.h
src/freedreno/ir3/ir3_legalize.c

index 344bb7bd98cd8c8204bfbb451a319c7940593957..85a9c9e5d71bab56152d512af01a7c1829b63e1e 100644 (file)
@@ -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, ),
index 9ad07d3173e2481cf4cbf8e59d21b176c56d9e5f..9f460c9cdce7e27d34008a1f08dcd6db22f182b3 100644 (file)
@@ -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),
 
index fa7aa4180275f49beaa0fc76e7bbdfa3783e4685..a0a2dcbd8051586d8bec8b2461a272fc86e33002 100644 (file)
@@ -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;
 }
 
index 7e69e8ea8edab4ac74850a7d7e18cb705a23861a..436feca2374f7c2cf8bd440c144726214a9ec69e 100644 (file)
@@ -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)
index 53fd4f919ee1a47d30eaed6f4735c2349fd12d19..a7c41b36b10cf53cf6a7804b33f0d0149de0d047 100644 (file)
@@ -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