r300: reduce CPU overhead in IF transformation pass

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 <pavel.ondracka@gmail.com>
Reviewed-by: Filip Gawin <filip@gawin.net>
Acked-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18678>
This commit is contained in:
Pavel Ondračka
2022-09-19 14:34:28 +02:00
committed by Marge Bot
parent 19eec024d2
commit c0074b22cd
3 changed files with 19 additions and 14 deletions
@@ -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},
@@ -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)
@@ -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