Mesa (master): freedreno/lowering: cleanup api

Rob Clark robclark at kemper.freedesktop.org
Sun Feb 23 20:26:45 UTC 2014


Module: Mesa
Branch: master
Commit: 1c953b7cda8169c1132259d83efff4df7afbf74a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1c953b7cda8169c1132259d83efff4df7afbf74a

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sun Feb 23 14:39:04 2014 -0500

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 at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/fd3_compiler.c  |   32 +++++++--
 .../drivers/freedreno/a3xx/fd3_compiler_old.c      |   32 +++++++--
 src/gallium/drivers/freedreno/a3xx/fd3_program.c   |    2 +-
 src/gallium/drivers/freedreno/freedreno_lowering.c |   70 ++++++++++++++++----
 src/gallium/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 30c2b51..cf75760 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 9ace26e..f38c158 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 b4c089c..0fd759e 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 8cfcdb7..607a5ac 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 60191d0..2862e5d 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_ */




More information about the mesa-commit mailing list