From 4e9a6c686878e6f41f48c605ff4accbdcf630ef6 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 31 Oct 2017 11:23:15 -0400 Subject: [PATCH] freedreno/ir3: add barriers Signed-off-by: Rob Clark --- .../drivers/freedreno/ir3/ir3_compiler_nir.c | 49 +++++++++++++++++++ .../drivers/freedreno/ir3/ir3_legalize.c | 6 +++ 2 files changed, 55 insertions(+) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index ac38ec61311..ba0db12e04c 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -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]); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c index fffa76504da..d6850eb12a0 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c @@ -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) { -- 2.30.2