freedreno/ir3: add barriers
authorRob Clark <robdclark@gmail.com>
Tue, 31 Oct 2017 15:23:15 +0000 (11:23 -0400)
committerRob Clark <robdclark@gmail.com>
Sun, 12 Nov 2017 17:28:59 +0000 (12:28 -0500)
Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/freedreno/ir3/ir3_legalize.c

index ac38ec613117d31399a2ee641b78ff50d53ee479..ba0db12e04c8fb167eed5d575b3133dbafdef22f 100644 (file)
@@ -1406,6 +1406,44 @@ emit_intrinsic_atomic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
        return atomic;
 }
 
+static void
+emit_intrinsic_barrier(struct ir3_context *ctx, nir_intrinsic_instr *intr)
+{
+       struct ir3_block *b = ctx->block;
+       struct ir3_instruction *barrier;
+
+       switch (intr->intrinsic) {
+       case nir_intrinsic_barrier:
+               barrier = ir3_BAR(b);
+               barrier->cat7.g = true;
+               barrier->cat7.l = true;
+               barrier->flags = IR3_INSTR_SS | IR3_INSTR_SY;
+               break;
+       case nir_intrinsic_memory_barrier:
+       case nir_intrinsic_memory_barrier_atomic_counter:
+       case nir_intrinsic_memory_barrier_buffer:
+               barrier = ir3_FENCE(b);
+               barrier->cat7.g = true;
+               barrier->cat7.r = true;
+               barrier->cat7.w = true;
+               break;
+       case nir_intrinsic_group_memory_barrier:
+       case nir_intrinsic_memory_barrier_image:
+       case nir_intrinsic_memory_barrier_shared:
+               barrier = ir3_FENCE(b);
+               barrier->cat7.g = true;
+               barrier->cat7.l = true;
+               barrier->cat7.r = true;
+               barrier->cat7.w = true;
+               break;
+       default:
+               unreachable("boo");
+       }
+
+       /* make sure barrier doesn't get DCE'd */
+       array_insert(b, b->keeps, barrier);
+}
+
 static void add_sysval_input_compmask(struct ir3_context *ctx,
                gl_system_value slot, unsigned compmask,
                struct ir3_instruction *instr)
@@ -1526,6 +1564,17 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                        emit_intrinsic_atomic(ctx, intr);
                }
                break;
+       case nir_intrinsic_barrier:
+       case nir_intrinsic_memory_barrier:
+       case nir_intrinsic_group_memory_barrier:
+       case nir_intrinsic_memory_barrier_atomic_counter:
+       case nir_intrinsic_memory_barrier_buffer:
+       case nir_intrinsic_memory_barrier_image:
+       case nir_intrinsic_memory_barrier_shared:
+               emit_intrinsic_barrier(ctx, intr);
+               /* note that blk ptr no longer valid, make that obvious: */
+               b = NULL;
+               break;
        case nir_intrinsic_store_output:
                idx = nir_intrinsic_base(intr);
                const_offset = nir_src_as_const_value(intr->src[1]);
index fffa76504da7f4f5880318715e221e0289dc2856..d6850eb12a09edb9ca85c545ee31a98f4f72c183 100644 (file)
@@ -67,6 +67,7 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
 {
        struct ir3_instruction *last_input = NULL;
        struct ir3_instruction *last_rel = NULL;
+       struct ir3_instruction *last_n = NULL;
        struct list_head instr_list;
        regmask_t needs_ss_war;       /* write after read */
        regmask_t needs_ss;
@@ -95,6 +96,9 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
                        ctx->max_bary = MAX2(ctx->max_bary, inloc->iim_val);
                }
 
+               if (last_n && is_barrier(last_n))
+                       n->flags |= IR3_INSTR_SS | IR3_INSTR_SY;
+
                /* NOTE: consider dst register too.. it could happen that
                 * texture sample instruction (for example) writes some
                 * components which are unused.  A subsequent instruction
@@ -208,6 +212,8 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
 
                if (is_input(n))
                        last_input = n;
+
+               last_n = n;
        }
 
        if (last_input) {