diff options
-rw-r--r-- | src/panfrost/midgard/compiler.h | 1 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_compile.c | 2 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_emit.c | 49 |
3 files changed, 51 insertions, 1 deletions
diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index e8cb79ba163..1765bfd8551 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -646,6 +646,7 @@ void mir_analyze_helper_requirements(compiler_context *ctx); void emit_binary_bundle( compiler_context *ctx, + midgard_block *block, midgard_bundle *bundle, struct util_dynarray *emission, int next_tag); diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index e0d2f26a245..1e20cfc3d4d 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -2811,7 +2811,7 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b if (!bundle->last_writeout && (current_bundle + 1 < bundle_count)) lookahead = source_order_bundles[current_bundle + 1]->tag; - emit_binary_bundle(ctx, bundle, compiled, lookahead); + emit_binary_bundle(ctx, block, bundle, compiled, lookahead); ++current_bundle; } diff --git a/src/panfrost/midgard/midgard_emit.c b/src/panfrost/midgard/midgard_emit.c index cf283dd3ed5..34b06a2caf4 100644 --- a/src/panfrost/midgard/midgard_emit.c +++ b/src/panfrost/midgard/midgard_emit.c @@ -23,6 +23,7 @@ #include "compiler.h" #include "midgard_ops.h" +#include "midgard_quirks.h" static midgard_int_mod mir_get_imod(bool shift, nir_alu_type T, bool half, bool scalar) @@ -356,6 +357,50 @@ mir_pack_swizzle_tex(midgard_instruction *ins) /* TODO: bias component */ } +/* Up to 3 { ALU, LDST } bundles can execute in parallel with a texture op. + * Given a texture op, lookahead to see how many such bundles we can flag for + * OoO execution */ + +static bool +mir_can_run_ooo(midgard_block *block, midgard_bundle *bundle, + unsigned dependency) +{ + /* Don't read out of bounds */ + if (bundle >= (midgard_bundle *) ((char *) block->bundles.data + block->bundles.size)) + return false; + + /* Texture ops can't execute with other texture ops */ + if (!IS_ALU(bundle->tag) && bundle->tag != TAG_LOAD_STORE_4) + return false; + + /* Ensure there is no read-after-write dependency */ + + for (unsigned i = 0; i < bundle->instruction_count; ++i) { + midgard_instruction *ins = bundle->instructions[i]; + + mir_foreach_src(ins, s) { + if (ins->src[s] == dependency) + return false; + } + } + + /* Otherwise, we're okay */ + return true; +} + +static void +mir_pack_tex_ooo(midgard_block *block, midgard_bundle *bundle, midgard_instruction *ins) +{ + unsigned count = 0; + + for (count = 0; count < 3; ++count) { + if (!mir_can_run_ooo(block, bundle + count + 1, ins->dest)) + break; + } + + ins->texture.out_of_order = count; +} + /* Load store masks are 4-bits. Load/store ops pack for that. vec4 is the * natural mask width; vec8 is constrained to be in pairs, vec2 is duplicated. TODO: 8-bit? */ @@ -529,6 +574,7 @@ midgard_sampler_type(nir_alu_type t) { void emit_binary_bundle(compiler_context *ctx, + midgard_block *block, midgard_bundle *bundle, struct util_dynarray *emission, int next_tag) @@ -615,6 +661,9 @@ emit_binary_bundle(compiler_context *ctx, mir_pack_swizzle_tex(ins); + if (!(ctx->quirks & MIDGARD_NO_OOO)) + mir_pack_tex_ooo(block, bundle, ins); + unsigned osz = nir_alu_type_get_type_size(ins->dest_type); unsigned isz = nir_alu_type_get_type_size(ins->src_types[1]); |