pan/midgard: Implement barriers

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>
This commit is contained in:
Alyssa Rosenzweig 2020-02-03 20:23:41 -05:00
parent 4f0b928921
commit 3f59098d1a
6 changed files with 37 additions and 2 deletions

View File

@ -131,6 +131,7 @@
#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

View 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);

View 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. */

View 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;
}

View 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));

View 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 }
};