mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 19:40:10 +01:00
ir3: make shpe a terminator
shpe is a bit of a special instruction: it's not really a terminator (i.e., it does not perform a jump) but it does have to stay at the end of its block. Up to now, we tried to enforce this by creating const write barriers on shpe; the assumption being that everything that happens in the preamble ends in a write to the const file so shpe stays at the end. Alas, it turns out this is not true: things like sampler prefetches do not write the const file and nothing was preventing those from being scheduled after shpe. Instead of trying to create even more barrier dependencies, fix this by making shpe a terminator. Both sched and postsched treat terminators specially to make sure they always stay at the end of their block. Signed-off-by: Job Noorman <jnoorman@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34290>
This commit is contained in:
parent
f5019ee0d4
commit
dd1ba74777
4 changed files with 13 additions and 8 deletions
|
|
@ -604,7 +604,7 @@ ir3_find_shpe(struct ir3 *ir)
|
|||
}
|
||||
|
||||
foreach_block (block, &ir->block_list) {
|
||||
struct ir3_instruction *last = ir3_block_get_last_non_terminator(block);
|
||||
struct ir3_instruction *last = ir3_block_get_terminator(block);
|
||||
|
||||
if (last && last->opc == OPC_SHPE) {
|
||||
return last;
|
||||
|
|
@ -666,9 +666,6 @@ ir3_create_empty_preamble(struct ir3 *ir)
|
|||
|
||||
b.cursor = ir3_after_block(body_block);
|
||||
struct ir3_instruction *shpe = ir3_SHPE(&b);
|
||||
shpe->barrier_class = shpe->barrier_conflict = IR3_BARRIER_CONST_W;
|
||||
array_insert(body_block, body_block->keeps, shpe);
|
||||
ir3_JUMP(&b);
|
||||
body_block->successors[0] = main_start_block;
|
||||
ir3_block_add_predecessor(main_start_block, body_block);
|
||||
ir3_block_link_physical(body_block, main_start_block);
|
||||
|
|
|
|||
|
|
@ -1009,6 +1009,7 @@ is_terminator(struct ir3_instruction *instr)
|
|||
case OPC_BRAA:
|
||||
case OPC_BRAO:
|
||||
case OPC_SHPS:
|
||||
case OPC_SHPE:
|
||||
case OPC_GETONE:
|
||||
case OPC_GETLAST:
|
||||
case OPC_PREDT:
|
||||
|
|
|
|||
|
|
@ -3363,9 +3363,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
|
|||
break;
|
||||
|
||||
case nir_intrinsic_preamble_end_ir3: {
|
||||
struct ir3_instruction *instr = ir3_SHPE(b);
|
||||
instr->barrier_class = instr->barrier_conflict = IR3_BARRIER_CONST_W;
|
||||
array_insert(ctx->block, ctx->block->keeps, instr);
|
||||
ir3_SHPE(b);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_store_const_ir3: {
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,16 @@ block_sched(struct ir3 *ir)
|
|||
*/
|
||||
assert(terminator);
|
||||
assert(terminator->opc == OPC_JUMP || terminator->opc == OPC_PREDT ||
|
||||
terminator->opc == OPC_PREDF);
|
||||
terminator->opc == OPC_PREDF || terminator->opc == OPC_SHPE);
|
||||
|
||||
/* shpe is not a branch (we just treat it as a terminator to make sure
|
||||
* it stays at the end of its block) so add one now.
|
||||
*/
|
||||
if (terminator->opc == OPC_SHPE) {
|
||||
struct ir3_builder b = ir3_builder_at(ir3_after_instr(terminator));
|
||||
terminator = ir3_JUMP(&b);
|
||||
}
|
||||
|
||||
terminator->cat0.target = block->successors[0];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue