freedreno/lowering: cleanup api
authorRob Clark <robclark@freedesktop.org>
Sun, 23 Feb 2014 19:39:04 +0000 (14:39 -0500)
committerRob Clark <robclark@freedesktop.org>
Sun, 23 Feb 2014 19:58:23 +0000 (14:58 -0500)
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 <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/freedreno_lowering.c
src/gallium/drivers/freedreno/freedreno_lowering.h

index 30c2b51743d29bb19ddef6259f654f5c7685582c..cf75760eb90f6a7a0369991a664bb095e3e7052b 100644 (file)
@@ -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);
 }
 
index 9ace26ebdbf9cd9654c1a86822151d9b6233a8b9..f38c158693f2bdfef41b94911b117099f54c22a9 100644 (file)
@@ -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);
 }
 
index b4c089cce6ae1b7fcecebbc03cf3e70483dea784..0fd759e94f149005f0585f476736cf351caa4dae 100644 (file)
@@ -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)
index 8cfcdb7c39bdeadf38fb7165547c144222b783b0..607a5acbadbaa0cb06804f6f8f9542726ed35502 100644 (file)
@@ -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;
 }
index 60191d08497949907fe4ff91014ac2740946a2e0..2862e5d3b6b313c6e555cd67ecb5a78b2dfbe97c 100644 (file)
 #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_<opc> is TRUE then
+        * enable lowering of TGSI_OPCODE_<opc>
+        */
+       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_ */