summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2017-10-31 11:23:15 -0400
committerRob Clark <[email protected]>2017-11-12 12:28:59 -0500
commit4e9a6c686878e6f41f48c605ff4accbdcf630ef6 (patch)
tree3c3170b58c2037277e69429be04967c760011bb2 /src
parent4c711f4d1898b147b66e1e69b7899d08ec925d0d (diff)
freedreno/ir3: add barriers
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c49
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_legalize.c6
2 files changed, 55 insertions, 0 deletions
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) {