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 6d1031841a542d8b02f8c2facdc3a9a5ca9fee77..9854cf72759fc8befb39d61ce298a52ae44c49a2 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 dca502bd4259afe80dd3e55a81ac108e9b486511..4bc494ca1be45e82cc13070a15a2493ce7daf5bc 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 7e948fd19c51054c33f6278eb939738694f066d7..1db5980e374eb341eb810ad8fa1db245e1813576 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 0b2823be782e2ac95af9f9264f8d6da6b98e3018..f55db21cef268ce3d6f0c87f1874e886f855fc59 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 eec4876eefe60a01023f420c2f13df2d86f37070..09354f3eb5367351856d734f6889faaa89b34b2f 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 2f12640f7ac23e739473bbb376c785b4893eb81c..c6055a7114079dba56070e2d2ae1d22dfdf96d54 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 }
         };