diff --git a/src/panfrost/bifrost/valhall/test/test-insert-flow.cpp b/src/panfrost/bifrost/valhall/test/test-insert-flow.cpp index cafb31e573e..4a31a2b6527 100644 --- a/src/panfrost/bifrost/valhall/test/test-insert-flow.cpp +++ b/src/panfrost/bifrost/valhall/test/test-insert-flow.cpp @@ -32,13 +32,13 @@ bi_builder *A = bit_builder(mem_ctx); \ bi_builder *B = bit_builder(mem_ctx); \ { \ - bi_builder *b = A; \ + UNUSED bi_builder *b = A; \ A->shader->stage = MESA_SHADER_ ## shader_stage; \ test; \ } \ va_insert_flow_control_nops(A->shader); \ { \ - bi_builder *b = B; \ + UNUSED bi_builder *b = B; \ B->shader->stage = MESA_SHADER_ ## shader_stage; \ expected; \ } \ @@ -60,6 +60,10 @@ protected: void *mem_ctx; }; +TEST_F(InsertFlow, PreserveEmptyShader) { + CASE(FRAGMENT, {}, {}); +} + TEST_F(InsertFlow, TilebufferWait7) { CASE(FRAGMENT, { bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0)); diff --git a/src/panfrost/bifrost/valhall/va_insert_flow.c b/src/panfrost/bifrost/valhall/va_insert_flow.c index f7e75f2d3ea..1a3e7ed91e0 100644 --- a/src/panfrost/bifrost/valhall/va_insert_flow.c +++ b/src/panfrost/bifrost/valhall/va_insert_flow.c @@ -353,6 +353,19 @@ va_discard_before_block(bi_block *block) return false; } +/* + * Test if a program is empty, in the sense of having zero instructions. Empty + * shaders get special handling. + */ +static bool +bi_is_empty(bi_context *ctx) +{ + bi_foreach_instr_global(ctx, _) + return false; + + return true; +} + /* * Given a program with no flow control modifiers, insert NOPs signaling the * required flow control. Not much optimization happens here. @@ -360,6 +373,14 @@ va_discard_before_block(bi_block *block) void va_insert_flow_control_nops(bi_context *ctx) { + /* Special case: if a program is empty, leave it empty. In particular, do not + * insert NOP.end. There is special handling in the driver for skipping empty + * shaders for shader stage. The .end is not necessary and disrupts + * optimizations. + */ + if (bi_is_empty(ctx)) + return; + /* First do dataflow analysis for the scoreboard. This populates I->flow with * a bitmap of slots to wait on. *