From 1c953b7cda8169c1132259d83efff4df7afbf74a Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 23 Feb 2014 14:39:04 -0500 Subject: [PATCH] freedreno/lowering: cleanup api Make things configurable, and tweak the API a bit to avoid an extra tgsi_shader_scan(). Getting closer to something generic which can be moved out of freedreno and shaderd by other drivers. Signed-off-by: Rob Clark --- .../drivers/freedreno/a3xx/fd3_compiler.c | 32 +++++++-- .../drivers/freedreno/a3xx/fd3_compiler_old.c | 32 +++++++-- .../drivers/freedreno/a3xx/fd3_program.c | 2 +- .../drivers/freedreno/freedreno_lowering.c | 70 +++++++++++++++---- .../drivers/freedreno/freedreno_lowering.h | 26 ++++++- 5 files changed, 138 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c index 30c2b51743d..cf75760eb90 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c @@ -39,6 +39,8 @@ #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_scan.h" +#include "freedreno_lowering.h" + #include "fd3_compiler.h" #include "fd3_program.h" #include "fd3_util.h" @@ -49,6 +51,7 @@ struct fd3_compile_context { const struct tgsi_token *tokens; + bool free_tokens; struct ir3_shader *ir; struct fd3_shader_stateobj *so; @@ -135,8 +138,29 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, { unsigned ret, base = 0; struct tgsi_shader_info *info = &ctx->info; + const struct fd_lowering_config lconfig = { + .lower_DST = true, + .lower_XPD = true, + .lower_SCS = true, + .lower_LRP = true, + .lower_FRC = true, + .lower_POW = true, + .lower_LIT = true, + .lower_EXP = true, + .lower_LOG = true, + .lower_DP4 = true, + .lower_DP3 = true, + .lower_DPH = true, + .lower_DP2 = true, + .lower_DP2A = true, + }; - ctx->tokens = tokens; + ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info); + ctx->free_tokens = !!ctx->tokens; + if (!ctx->tokens) { + /* no lowering */ + ctx->tokens = tokens; + } ctx->ir = so->ir; ctx->so = so; ctx->next_inloc = 8; @@ -150,8 +174,6 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, memset(ctx->base_reg, 0, sizeof(ctx->base_reg)); - tgsi_scan_shader(tokens, &ctx->info); - #define FM(x) (1 << TGSI_FILE_##x) /* optimize can't deal with relative addressing: */ if (info->indirect_files & (FM(TEMPORARY) | FM(INPUT) | @@ -180,7 +202,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, so->first_immediate = ctx->base_reg[TGSI_FILE_IMMEDIATE]; ctx->immediate_idx = 4 * (ctx->info.file_max[TGSI_FILE_IMMEDIATE] + 1); - ret = tgsi_parse_init(&ctx->parser, tokens); + ret = tgsi_parse_init(&ctx->parser, ctx->tokens); if (ret != TGSI_PARSE_OK) return ret; @@ -207,6 +229,8 @@ compile_error(struct fd3_compile_context *ctx, const char *format, ...) static void compile_free(struct fd3_compile_context *ctx) { + if (ctx->free_tokens) + free((void *)ctx->tokens); tgsi_parse_free(&ctx->parser); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c index 9ace26ebdbf..f38c158693f 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c @@ -39,6 +39,8 @@ #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_scan.h" +#include "freedreno_lowering.h" + #include "fd3_compiler.h" #include "fd3_program.h" #include "fd3_util.h" @@ -49,6 +51,7 @@ struct fd3_compile_context { const struct tgsi_token *tokens; + bool free_tokens; struct ir3_shader *ir; struct ir3_block *block; struct fd3_shader_stateobj *so; @@ -122,8 +125,29 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, { unsigned ret, base = 0; struct tgsi_shader_info *info = &ctx->info; + const struct fd_lowering_config lconfig = { + .lower_DST = true, + .lower_XPD = true, + .lower_SCS = true, + .lower_LRP = true, + .lower_FRC = true, + .lower_POW = true, + .lower_LIT = true, + .lower_EXP = true, + .lower_LOG = true, + .lower_DP4 = true, + .lower_DP3 = true, + .lower_DPH = true, + .lower_DP2 = true, + .lower_DP2A = true, + }; - ctx->tokens = tokens; + ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info); + ctx->free_tokens = !!ctx->tokens; + if (!ctx->tokens) { + /* no lowering */ + ctx->tokens = tokens; + } ctx->ir = so->ir; ctx->block = ir3_block_create(ctx->ir, 0, 0, 0); ctx->so = so; @@ -137,8 +161,6 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, regmask_init(&ctx->needs_sy); memset(ctx->base_reg, 0, sizeof(ctx->base_reg)); - tgsi_scan_shader(tokens, &ctx->info); - /* Immediates go after constants: */ ctx->base_reg[TGSI_FILE_CONSTANT] = 0; ctx->base_reg[TGSI_FILE_IMMEDIATE] = @@ -161,7 +183,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_stateobj *so, so->first_immediate = ctx->base_reg[TGSI_FILE_IMMEDIATE]; ctx->immediate_idx = 4 * (ctx->info.file_max[TGSI_FILE_IMMEDIATE] + 1); - ret = tgsi_parse_init(&ctx->parser, tokens); + ret = tgsi_parse_init(&ctx->parser, ctx->tokens); if (ret != TGSI_PARSE_OK) return ret; @@ -188,6 +210,8 @@ compile_error(struct fd3_compile_context *ctx, const char *format, ...) static void compile_free(struct fd3_compile_context *ctx) { + if (ctx->free_tokens) + free((void *)ctx->tokens); tgsi_parse_free(&ctx->parser); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c index b4c089cce6a..0fd759e94f1 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c @@ -90,7 +90,7 @@ create_shader(struct pipe_context *pctx, const struct pipe_shader_state *cso, enum shader_t type) { struct fd3_shader_stateobj *so = CALLOC_STRUCT(fd3_shader_stateobj); - const struct tgsi_token *tokens = fd_transform_lowering(cso->tokens); + const struct tgsi_token *tokens = cso->tokens; int ret; if (!so) diff --git a/src/gallium/drivers/freedreno/freedreno_lowering.c b/src/gallium/drivers/freedreno/freedreno_lowering.c index 8cfcdb7c39b..607a5acbadb 100644 --- a/src/gallium/drivers/freedreno/freedreno_lowering.c +++ b/src/gallium/drivers/freedreno/freedreno_lowering.c @@ -37,7 +37,8 @@ struct fd_lowering_context { struct tgsi_transform_context base; - struct tgsi_shader_info info; + const struct fd_lowering_config *config; + struct tgsi_shader_info *info; unsigned numtmp; struct { struct tgsi_full_src_register src; @@ -985,7 +986,7 @@ transform_instr(struct tgsi_transform_context *tctx, if (!ctx->emitted_decls) { struct tgsi_full_declaration decl; struct tgsi_full_immediate immed; - unsigned tmpbase = ctx->info.file_max[TGSI_FILE_TEMPORARY] + 1; + unsigned tmpbase = ctx->info->file_max[TGSI_FILE_TEMPORARY] + 1; int i; /* declare immediate: */ @@ -998,7 +999,7 @@ transform_instr(struct tgsi_transform_context *tctx, tctx->emit_immediate(tctx, &immed); ctx->imm.Register.File = TGSI_FILE_IMMEDIATE; - ctx->imm.Register.Index = ctx->info.immediate_count; + ctx->imm.Register.Index = ctx->info->immediate_count; ctx->imm.Register.SwizzleX = TGSI_SWIZZLE_X; ctx->imm.Register.SwizzleY = TGSI_SWIZZLE_Y; ctx->imm.Register.SwizzleZ = TGSI_SWIZZLE_Z; @@ -1028,47 +1029,90 @@ transform_instr(struct tgsi_transform_context *tctx, switch (inst->Instruction.Opcode) { case TGSI_OPCODE_DST: + if (!ctx->config->lower_DST) + goto skip; transform_dst(tctx, inst); break; case TGSI_OPCODE_XPD: + if (!ctx->config->lower_XPD) + goto skip; transform_xpd(tctx, inst); break; case TGSI_OPCODE_SCS: + if (!ctx->config->lower_SCS) + goto skip; transform_scs(tctx, inst); break; case TGSI_OPCODE_LRP: + if (!ctx->config->lower_LRP) + goto skip; transform_lrp(tctx, inst); break; case TGSI_OPCODE_FRC: + if (!ctx->config->lower_FRC) + goto skip; transform_frc(tctx, inst); break; case TGSI_OPCODE_POW: + if (!ctx->config->lower_POW) + goto skip; transform_pow(tctx, inst); break; case TGSI_OPCODE_LIT: + if (!ctx->config->lower_LIT) + goto skip; transform_lit(tctx, inst); break; case TGSI_OPCODE_EXP: + if (!ctx->config->lower_EXP) + goto skip; transform_exp(tctx, inst); break; case TGSI_OPCODE_LOG: + if (!ctx->config->lower_LOG) + goto skip; transform_log(tctx, inst); break; case TGSI_OPCODE_DP4: + if (!ctx->config->lower_DP4) + goto skip; + transform_dotp(tctx, inst); + break; case TGSI_OPCODE_DP3: + if (!ctx->config->lower_DP3) + goto skip; + transform_dotp(tctx, inst); + break; case TGSI_OPCODE_DPH: + if (!ctx->config->lower_DPH) + goto skip; + transform_dotp(tctx, inst); + break; case TGSI_OPCODE_DP2: + if (!ctx->config->lower_DP2) + goto skip; + transform_dotp(tctx, inst); + break; case TGSI_OPCODE_DP2A: + if (!ctx->config->lower_DP2A) + goto skip; transform_dotp(tctx, inst); break; default: + skip: tctx->emit_instruction(tctx, inst); break; } } +/* returns NULL if no lowering required, else returns the new + * tokens (which caller is required to free()). In either case + * returns the current info. + */ const struct tgsi_token * -fd_transform_lowering(const struct tgsi_token *tokens) +fd_transform_lowering(const struct fd_lowering_config *config, + const struct tgsi_token *tokens, + struct tgsi_shader_info *info) { struct fd_lowering_context ctx; struct tgsi_token *newtoks; @@ -1076,10 +1120,12 @@ fd_transform_lowering(const struct tgsi_token *tokens) memset(&ctx, 0, sizeof(ctx)); ctx.base.transform_instruction = transform_instr; + ctx.info = info; + ctx.config = config; - tgsi_scan_shader(tokens, &ctx.info); + tgsi_scan_shader(tokens, info); -#define OPCS(x) (ctx.info.opcode_count[TGSI_OPCODE_ ## x]) +#define OPCS(x) ((config->lower_ ## x) ? info->opcode_count[TGSI_OPCODE_ ## x] : 0) /* if there are no instructions to lower, then we are done: */ if (!(OPCS(DST) || OPCS(XPD) || @@ -1095,7 +1141,7 @@ fd_transform_lowering(const struct tgsi_token *tokens) OPCS(DPH) || OPCS(DP2) || OPCS(DP2A))) - return tokens; + return NULL; #if 0 /* debug */ _debug_printf("BEFORE:"); @@ -1168,20 +1214,16 @@ fd_transform_lowering(const struct tgsi_token *tokens) newtoks = tgsi_alloc_tokens(newlen); if (!newtoks) - goto out; + return NULL; tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); + tgsi_scan_shader(newtoks, info); + #if 0 /* debug */ _debug_printf("AFTER:"); tgsi_dump(newtoks, 0); #endif -out: -// XXX caller frees orig tokens.. need to change the api around so -// called by compiler.. compiler then would have to know to free -// new tokens. Should be able to get rid of an extra tgsi_scan step.. -// but need to move the tgsi dump stuff into compiler then?? -// free((struct tgsi_token *)tokens); return newtoks; } diff --git a/src/gallium/drivers/freedreno/freedreno_lowering.h b/src/gallium/drivers/freedreno/freedreno_lowering.h index 60191d08497..2862e5d3b6b 100644 --- a/src/gallium/drivers/freedreno/freedreno_lowering.h +++ b/src/gallium/drivers/freedreno/freedreno_lowering.h @@ -30,7 +30,31 @@ #define FREEDRENO_LOWERING_H_ #include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_scan.h" -const struct tgsi_token * fd_transform_lowering(const struct tgsi_token *tokens); +struct fd_lowering_config { + /* Individual OPC lowerings, if lower_ is TRUE then + * enable lowering of TGSI_OPCODE_ + */ + unsigned lower_DST : 1; + unsigned lower_XPD : 1; + unsigned lower_SCS : 1; + unsigned lower_LRP : 1; + unsigned lower_FRC : 1; + unsigned lower_POW : 1; + unsigned lower_LIT : 1; + unsigned lower_EXP : 1; + unsigned lower_LOG : 1; + unsigned lower_DP4 : 1; + unsigned lower_DP3 : 1; + unsigned lower_DPH : 1; + unsigned lower_DP2 : 1; + unsigned lower_DP2A : 1; +}; + +const struct tgsi_token * fd_transform_lowering( + const struct fd_lowering_config *config, + const struct tgsi_token *tokens, + struct tgsi_shader_info *info); #endif /* FREEDRENO_LOWERING_H_ */ -- 2.30.2