pan/midgard: Implement barriers
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 4 Feb 2020 01:23:41 +0000 (20:23 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Sun, 16 Feb 2020 14:16:47 +0000 (09:16 -0500)
Barriers execute on the texture pipeline on Midgard, so let's
tentatively handle barrier() as conservatively as possible (forcing
memory barriers of both buffers and shared memory). Implementation isn't
quite there yet -- it doesn't look at interactions of adjacent barriers
like it's supposed to -- but the core is there.

Fixes dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3835>

src/panfrost/midgard/helpers.h
src/panfrost/midgard/midgard_compile.c
src/panfrost/midgard/midgard_emit.c
src/panfrost/midgard/midgard_opt_dce.c
src/panfrost/midgard/midgard_ra.c
src/panfrost/midgard/midgard_schedule.c

index 6d10318..9854cf7 100644 (file)
 
 #define TAG_TEXTURE_4_VTX 0x2
 #define TAG_TEXTURE_4 0x3
+#define TAG_TEXTURE_4_BARRIER 0x4
 #define TAG_LOAD_STORE_4 0x5
 #define TAG_ALU_4 0x8
 #define TAG_ALU_8 0x9
index dca502b..4bc494c 100644 (file)
@@ -1505,6 +1505,21 @@ emit_vertex_builtin(compiler_context *ctx, nir_intrinsic_instr *instr)
         emit_attr_read(ctx, reg, vertex_builtin_arg(instr->intrinsic), 1, nir_type_int);
 }
 
+static void
+emit_control_barrier(compiler_context *ctx)
+{
+        midgard_instruction ins = {
+                .type = TAG_TEXTURE_4,
+                .src = { ~0, ~0, ~0, ~0 },
+                .texture = {
+                        .op = TEXTURE_OP_BARRIER,
+                        .unknown4 = 3 /* (control |) buffers | shared */
+                }
+        };
+
+        emit_mir_instruction(ctx, ins);
+}
+
 static const nir_variable *
 search_var(struct exec_list *vars, unsigned driver_loc)
 {
@@ -1814,6 +1829,16 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
                 emit_vertex_builtin(ctx, instr);
                 break;
 
+        case nir_intrinsic_memory_barrier_buffer:
+        case nir_intrinsic_memory_barrier_shared:
+                break;
+
+        case nir_intrinsic_control_barrier:
+                schedule_barrier(ctx);
+                emit_control_barrier(ctx);
+                schedule_barrier(ctx);
+                break;
+
         default:
                 printf ("Unhandled intrinsic %s\n", nir_intrinsic_infos[instr->intrinsic].name);
                 assert(0);
index 7e948fd..1db5980 100644 (file)
@@ -450,7 +450,8 @@ emit_binary_bundle(compiler_context *ctx,
         }
 
         case TAG_TEXTURE_4:
-        case TAG_TEXTURE_4_VTX: {
+        case TAG_TEXTURE_4_VTX:
+        case TAG_TEXTURE_4_BARRIER: {
                 /* Texture instructions are easy, since there is no pipelining
                  * nor VLIW to worry about. We may need to set .cont/.last
                  * flags. */
index 0b2823b..f55db21 100644 (file)
@@ -56,6 +56,10 @@ can_dce(midgard_instruction *ins)
                 if (load_store_opcode_props[ins->load_store.op].props & LDST_SIDE_FX)
                         return false;
 
+        if (ins->type == TAG_TEXTURE_4)
+                if (ins->texture.op == TEXTURE_OP_BARRIER)
+                        return false;
+
         return true;
 }
 
index eec4876..09354f3 100644 (file)
@@ -686,6 +686,9 @@ install_registers_instr(
         }
 
         case TAG_TEXTURE_4: {
+                if (ins->texture.op == TEXTURE_OP_BARRIER)
+                        break;
+
                 /* Grab RA results */
                 struct phys_reg dest = index_to_reg(ctx, l, ins->dest, mir_typesize(ins));
                 struct phys_reg coord = index_to_reg(ctx, l, ins->src[1], mir_srcsize(ins, 1));
index 2f12640..c6055a7 100644 (file)
@@ -811,7 +811,8 @@ mir_schedule_texture(
         mir_update_worklist(worklist, len, instructions, ins);
 
         struct midgard_bundle out = {
-                .tag = TAG_TEXTURE_4,
+                .tag = ins->texture.op == TEXTURE_OP_BARRIER ?
+                        TAG_TEXTURE_4_BARRIER : TAG_TEXTURE_4,
                 .instruction_count = 1,
                 .instructions = { ins }
         };