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:
committed by
Marge Bot
parent
19eec024d2
commit
c0074b22cd
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user