Mesa (master): r600g: add r600 compile mode to compiler.

Jerome Glisse glisse at kemper.freedesktop.org
Wed Jul 21 21:06:50 UTC 2010


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jul 21 15:39:23 2010 +1000

r600g: add r600 compile mode to compiler.

some of the ALU instructions are different on r6xx vs r7xx,
separate the alu translation to separate files, and use family
to pick which compile stage to use.

---

 src/gallium/drivers/r600/r600_compiler_r600.c |   65 +++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_compiler_r700.c |   43 ++++++++++++-----
 src/gallium/drivers/r600/r600_shader.c        |    6 ++-
 src/gallium/drivers/r600/r600_shader.h        |    5 ++
 4 files changed, 106 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c
index f7234e7..27ad8f1 100644
--- a/src/gallium/drivers/r600/r600_compiler_r600.c
+++ b/src/gallium/drivers/r600/r600_compiler_r600.c
@@ -905,3 +905,68 @@ struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = {
 	{C_OPCODE_ENTRY,	INST_NOP},
 	{C_OPCODE_ARL,		INST_NOP},
 };
+
+
+static int r600_shader_alu_bytecode(struct r600_shader *rshader,
+					struct r600_shader_node *rnode,
+					struct r600_shader_inst *alu,
+					unsigned *cid)
+{
+	unsigned id = *cid;
+
+	/* don't replace gpr by pv or ps for destination register */
+	if (alu->is_op3) {
+		rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+					S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+					S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+					S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+					S_SQ_ALU_WORD0_LAST(alu->last);
+		rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+					S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+					S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+					S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+					S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+					S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) |
+					S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+	} else {
+		rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+					S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+					S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+					S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+					S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+					S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+					S_SQ_ALU_WORD0_LAST(alu->last);
+		rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+					S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+					S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+					S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+					S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) |
+					S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) |
+					S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+	}
+	*cid = id;
+	return 0;
+}
+
+int r6xx_shader_alu_translate(struct r600_shader *rshader,
+			      struct r600_shader_node *rnode,
+			      unsigned *cid)
+{
+	struct r600_shader_alu *alu;
+	unsigned id = *cid;
+	int i;
+	int r = 0;
+	LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) {
+		for (i = 0; i < alu->nalu; i++) {
+			r = r600_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
+			if (r)
+				goto out;
+		}
+		for (i = 0; i < alu->nliteral; i++) {
+			rshader->bcode[id++] = alu->literal[i];
+		}
+	}
+out:
+	*cid = id;
+	return r;
+}
diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c
index ca6447e..0b43942 100644
--- a/src/gallium/drivers/r600/r600_compiler_r700.c
+++ b/src/gallium/drivers/r600/r600_compiler_r700.c
@@ -143,14 +143,37 @@ static int r700_shader_alu_bytecode(struct r600_shader *rshader,
 	return 0;
 }
 
+static int r700_shader_alu_translate(struct r600_shader *rshader,
+				     struct r600_shader_node *rnode,
+				     unsigned *cid)
+				     
+{
+	struct r600_shader_alu *alu;
+	unsigned id = *cid;
+	int i;
+	int r = 0;
+	LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) {
+		for (i = 0; i < alu->nalu; i++) {
+			r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
+			if (r)
+				goto out;
+		}
+		for (i = 0; i < alu->nliteral; i++) {
+			rshader->bcode[id++] = alu->literal[i];
+		}
+	}
+ out:
+	*cid = id;
+	return r;
+}
+
 int r700_shader_translate(struct r600_shader *rshader)
 {
 	struct c_shader *shader = &rshader->cshader;
 	struct r600_shader_node *rnode;
 	struct r600_shader_vfetch *vfetch;
-	struct r600_shader_alu *alu;
 	struct c_vector *v;
-	unsigned id, i, end;
+	unsigned id, end;
 	int r;
 
 	r = r600_shader_register(rshader);
@@ -179,16 +202,12 @@ int r700_shader_translate(struct r600_shader *rshader)
 			if (r)
 				return r;
 		}
-		LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) {
-			for (i = 0; i < alu->nalu; i++) {
-				r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
-				if (r)
-					return r;
-			}
-			for (i = 0; i < alu->nliteral; i++) {
-				rshader->bcode[id++] = alu->literal[i];
-			}
-		}
+		if (rshader->r6xx_compile)
+			r = r6xx_shader_alu_translate(rshader, rnode, &id);
+		else
+			r = r700_shader_alu_translate(rshader, rnode, &id);
+		if (r)
+			return r;
 	}
 	id = 0;
 	LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) {
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 2b1d54a..f7d6e10 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -126,15 +126,19 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
 
 struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
 {
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
 	struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
 	struct r600_shader *rshader = &rpshader->shader;
 	int r;
+	enum radeon_family family;
 
 	if (rpshader == NULL)
 		return NULL;
 	rpshader->type = type;
+	family = radeon_get_family(rscreen->rw);
+	rshader->r6xx_compile = (family >= CHIP_R600 && family < CHIP_RV770);
 	LIST_INITHEAD(&rshader->nodes);
-	fprintf(stderr, "<<\n");
+	fprintf(stderr, "<< %s\n", rshader->r6xx_compile ? "R600" : "R700");
 	tgsi_dump(tokens, 0);
 	fprintf(stderr, "--------------------------------------------------------------\n");
 	r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index 6e1bd1e..40064ba 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -96,6 +96,7 @@ struct r600_shader {
 	u32				*bcode;			/**< bytes code */
 	enum pipe_format		resource_format[160];	/**< format of resource */
 	struct c_shader			cshader;
+	boolean r6xx_compile;
 };
 
 void r600_shader_cleanup(struct r600_shader *rshader);
@@ -122,6 +123,10 @@ int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node);
 int r700_shader_translate(struct r600_shader *rshader);
 int r600_shader_insert_fetch(struct c_shader *shader);
 
+int r6xx_shader_alu_translate(struct r600_shader *rshader,
+			      struct r600_shader_node *rnode,
+			      unsigned *cid);
+
 enum r600_instruction {
 	INST_ADD			= 0,
 	INST_MUL			= 1,




More information about the mesa-commit mailing list