Commit 3228b310 authored by Alyssa Rosenzweig's avatar Alyssa Rosenzweig 💜 Committed by Marge Bot
Browse files

pan/mdg: Analyze helper invocation termination


Signed-off-by: Alyssa Rosenzweig's avatarAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <mesa/mesa!5014>
parent 0da03c68
......@@ -47,6 +47,7 @@ midgard_FILES := \
midgard/midgard_emit.c \
midgard/midgard.h \
midgard/midgard_liveness.c \
midgard/midgard_helper_invocations.c \
midgard/midgard_nir.h \
midgard/midgard_ops.c \
midgard/midgard_ops.h \
......
......@@ -104,6 +104,10 @@ typedef struct midgard_instruction {
/* Special fields for an ALU instruction */
midgard_reg_info registers;
/* For textures: should helpers execute this instruction (instead of
* just helping with derivatives)? Should helpers terminate after? */
bool helper_terminate;
/* I.e. (1 << alu_bit) */
int unit;
......@@ -179,6 +183,9 @@ typedef struct midgard_block {
/* Indicates this is a fixed-function fragment epilogue block */
bool epilogue;
/* Are helper invocations required by this block? */
bool helpers_in;
} midgard_block;
typedef struct midgard_bundle {
......@@ -626,6 +633,8 @@ midgard_lower_derivatives(compiler_context *ctx, midgard_block *block);
bool mir_op_computes_derivatives(gl_shader_stage stage, unsigned op);
void mir_analyze_helper_terminate(compiler_context *ctx);
/* Final emission */
void emit_binary_bundle(
......
......@@ -27,6 +27,7 @@ libpanfrost_midgard_files = files(
'midgard_schedule.c',
'midgard_derivatives.c',
'midgard_emit.c',
'midgard_helper_invocations.c',
'midgard_ra.c',
'midgard_ra_pipeline.c',
'midgard_liveness.c',
......
......@@ -61,3 +61,100 @@
* with union as the join operation and the generating set being the union of
* sources of instructions writing executed values.
*/
/* Does a block use helpers directly */
static bool
mir_block_uses_helpers(gl_shader_stage stage, midgard_block *block)
{
mir_foreach_instr_in_block(block, ins) {
if (ins->type != TAG_TEXTURE_4) continue;
if (mir_op_computes_derivatives(stage, ins->texture.op))
return true;
}
return false;
}
static bool
mir_block_terminates_helpers(midgard_block *block)
{
/* Can't terminate if there are no helpers */
if (!block->helpers_in)
return false;
/* Can't terminate if a successor needs helpers */
pan_foreach_successor((&block->base), succ) {
if (((midgard_block *) succ)->helpers_in)
return false;
}
/* Otherwise we terminate */
return true;
}
void
mir_analyze_helper_terminate(compiler_context *ctx)
{
/* Set blocks as directly requiring helpers, and if they do add them to
* the worklist to propagate to their predecessors */
struct set *worklist = _mesa_set_create(NULL,
_mesa_hash_pointer,
_mesa_key_pointer_equal);
struct set *visited = _mesa_set_create(NULL,
_mesa_hash_pointer,
_mesa_key_pointer_equal);
mir_foreach_block(ctx, _block) {
midgard_block *block = (midgard_block *) _block;
block->helpers_in |= mir_block_uses_helpers(ctx->stage, block);
if (block->helpers_in)
_mesa_set_add(worklist, _block);
}
/* Next, propagate back. Since there are a finite number of blocks, the
* worklist (a subset of all the blocks) is finite. Since a block can
* only be added to the worklist if it is not on the visited list and
* the visited list - also a subset of the blocks - grows every
* iteration, the algorithm must terminate. */
struct set_entry *cur;
while((cur = _mesa_set_next_entry(worklist, NULL)) != NULL) {
/* Pop off a block requiring helpers */
pan_block *blk = (struct pan_block *) cur->key;
_mesa_set_remove(worklist, cur);
/* Its predecessors also require helpers */
pan_foreach_predecessor(blk, pred) {
if (!_mesa_set_search(visited, pred)) {
((midgard_block *) pred)->helpers_in = true;
_mesa_set_add(worklist, pred);
}
}
_mesa_set_add(visited, blk);
}
_mesa_set_destroy(visited, NULL);
_mesa_set_destroy(worklist, NULL);
/* Finally, set helper_terminate on the last derivative-calculating
* instruction in a block that terminates helpers */
mir_foreach_block(ctx, _block) {
midgard_block *block = (midgard_block *) _block;
if (!mir_block_terminates_helpers(block))
continue;
mir_foreach_instr_in_block_rev(block, ins) {
if (ins->type != TAG_TEXTURE_4) continue;
if (!mir_op_computes_derivatives(ctx->stage, ins->texture.op)) continue;
ins->helper_terminate = true;
break;
}
}
}
......@@ -328,6 +328,10 @@ mir_print_instruction(midgard_instruction *ins)
case TAG_TEXTURE_4: {
printf("texture");
if (ins->helper_terminate)
printf(".terminate");
break;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment