summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2014-02-23 14:39:04 -0500
committerRob Clark <robclark@freedesktop.org>2014-02-23 14:58:23 -0500
commit1c953b7cda8169c1132259d83efff4df7afbf74a (patch)
tree81effc5b135a0ca182c3c851e2a7b067e36516f4
parent67cea4b32a27aaf8eb729cdb0a3fec2ff582a922 (diff)
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 <robclark@freedesktop.org>
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_compiler.c32
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c32
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_lowering.c70
-rw-r--r--src/gallium/drivers/freedreno/freedreno_lowering.h26
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_<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_ */