From c0074b22cda3ab929018998c26dccd438e63a5c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Mon, 19 Sep 2022 14:34:28 +0200 Subject: [PATCH] r300: reduce CPU overhead in IF transformation pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right now there is a call to rc_get_variables, which performs a global analysis of the whole shader, for every IF encountered. As a result, shaders with a lot of IFs are compiled very slowly. The patological cases are shaders using relative adressing, where the lowered array access can result in tens of IFs. This patch restructures the pass to call the rc_get_variables just once at the beginning and later reuse the gathered info. We can do this, because even though we transform the shader in the meantime (like for example adding extra MOVs) the transformations are not siginificant enough to influence the relevant variable info we are using. This reduces CPU time for my shader-db by more than a half. I also checked that the generated code for all shaders in shader-db is identical. Signed-off-by: Pavel Ondračka Reviewed-by: Filip Gawin Acked-by: Emma Anholt Part-of: --- .../drivers/r300/compiler/r3xx_fragprog.c | 7 +----- .../drivers/r300/compiler/r500_fragprog.c | 23 ++++++++++++++----- .../drivers/r300/compiler/r500_fragprog.h | 3 +-- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/r300/compiler/r3xx_fragprog.c b/src/gallium/drivers/r300/compiler/r3xx_fragprog.c index e059accf2cd..825ad5c2d02 100644 --- a/src/gallium/drivers/r300/compiler/r3xx_fragprog.c +++ b/src/gallium/drivers/r300/compiler/r3xx_fragprog.c @@ -83,11 +83,6 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) { NULL, NULL } }; - struct radeon_program_transformation rewrite_if[] = { - { &r500_transform_IF, NULL }, - { NULL, NULL } - }; - struct radeon_program_transformation native_rewrite_r500[] = { { &radeonTransformALU, NULL }, { &radeonTransformDeriv, NULL }, @@ -112,7 +107,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) {"emulate branches", 1, !is_r500, rc_emulate_branches, NULL}, {"force alpha to one", 1, alpha2one, rc_local_transform, force_alpha_to_one}, {"transform TEX", 1, 1, rc_local_transform, rewrite_tex}, - {"transform IF", 1, is_r500, rc_local_transform, rewrite_if}, + {"transform IF", 1, is_r500, r500_transform_IF, NULL}, {"native rewrite", 1, is_r500, rc_local_transform, native_rewrite_r500}, {"native rewrite", 1, !is_r500, rc_local_transform, native_rewrite_r300}, {"deadcode", 1, opt, rc_dataflow_deadcode, NULL}, diff --git a/src/gallium/drivers/r300/compiler/r500_fragprog.c b/src/gallium/drivers/r300/compiler/r500_fragprog.c index 8a110f091cd..d810c252d45 100644 --- a/src/gallium/drivers/r300/compiler/r500_fragprog.c +++ b/src/gallium/drivers/r300/compiler/r500_fragprog.c @@ -39,17 +39,14 @@ /** * Rewrite IF instructions to use the ALU result special register. */ -int r500_transform_IF( +static void r500_transform_IF_instr( struct radeon_compiler * c, struct rc_instruction * inst_if, - void *data) + struct rc_list * var_list) { - if (inst_if->U.I.Opcode != RC_OPCODE_IF) - return 0; struct rc_variable * writer; struct rc_list * writer_list, * list_ptr; - struct rc_list * var_list = rc_get_variables(c); unsigned int generic_if = 0; unsigned int alu_chan; @@ -177,8 +174,22 @@ int r500_transform_IF( RC_SWIZZLE_X, RC_SWIZZLE_UNUSED, RC_SWIZZLE_UNUSED, RC_SWIZZLE_UNUSED); inst_if->U.I.SrcReg[0].Negate = 0; +} - return 1; +void r500_transform_IF( + struct radeon_compiler * c, + void *user) +{ + struct rc_list * var_list = rc_get_variables(c); + + struct rc_instruction * inst = c->Program.Instructions.Next; + while(inst != &c->Program.Instructions) { + struct rc_instruction * current = inst; + inst = inst->Next; + + if (current->U.I.Opcode == RC_OPCODE_IF) + r500_transform_IF_instr(c, current, var_list); + } } static int r500_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg) diff --git a/src/gallium/drivers/r300/compiler/r500_fragprog.h b/src/gallium/drivers/r300/compiler/r500_fragprog.h index 1c30dc0e854..091cf50ffa6 100644 --- a/src/gallium/drivers/r300/compiler/r500_fragprog.h +++ b/src/gallium/drivers/r300/compiler/r500_fragprog.h @@ -42,9 +42,8 @@ extern void r500FragmentProgramDump(struct radeon_compiler *c, void *user); extern const struct rc_swizzle_caps r500_swizzle_caps; -extern int r500_transform_IF( +extern void r500_transform_IF( struct radeon_compiler * c, - struct rc_instruction * inst_if, void* data); #endif