Mesa (master): r600g: split instruction into scalar

Jerome Glisse glisse at kemper.freedesktop.org
Sat Jun 5 08:13:26 PDT 2010


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

Author: Jerome Glisse <jglisse at redhat.com>
Date:   Sat Jun  5 13:16:50 2010 +0200

r600g: split instruction into scalar

Split instruction into scalar in core compiler this simplify
the way we translate the instruction in latter stage.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>

---

 src/gallium/drivers/r600/r600_compiler.h      |   19 ++-
 src/gallium/drivers/r600/r600_compiler_dump.c |   33 ++---
 src/gallium/drivers/r600/r600_compiler_r600.c |  180 ++++++++++---------------
 src/gallium/drivers/r600/r600_compiler_tgsi.c |   59 ++++++---
 4 files changed, 143 insertions(+), 148 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h
index 64dab50..3de1997 100644
--- a/src/gallium/drivers/r600/r600_compiler.h
+++ b/src/gallium/drivers/r600/r600_compiler.h
@@ -71,7 +71,7 @@ struct c_vector {
 #define C_SWIZZLE_W		3
 #define C_SWIZZLE_0		4
 #define C_SWIZZLE_1		5
-#define C_SWIZZLE_D		6	/**< discard */
+#define C_SWIZZLE_D		6
 
 #define C_FILE_NULL		0
 #define C_FILE_CONSTANT		1
@@ -247,18 +247,21 @@ struct c_vector {
 
 struct c_operand {
 	struct c_vector		*vector;
-	unsigned		swizzle[4];
-	unsigned		flag[4];
+	unsigned		swizzle;
+	unsigned		flag;
 };
 
-struct c_instruction {
-	struct c_instruction	*next, *prev;
-	unsigned		opcode;
+struct c_op {
 	unsigned		ninput;
 	struct c_operand	input[3];
 	struct c_operand	output;
-	unsigned		write_mask;
-	void			*backend;
+	unsigned		opcode;
+};
+
+struct c_instruction {
+	struct c_instruction	*next, *prev;
+	unsigned		nop;
+	struct c_op		op[5];
 };
 
 struct c_node;
diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c
index 9df6a38..4850320 100644
--- a/src/gallium/drivers/r600/r600_compiler_dump.c
+++ b/src/gallium/drivers/r600/r600_compiler_dump.c
@@ -229,28 +229,25 @@ static void pindent(unsigned indent)
 static void c_node_dump(struct c_node *node, unsigned indent)
 {
 	struct c_instruction *i;
-	unsigned j;
+	unsigned j, k;
 
 	pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode));
 	c_list_for_each(i, &node->insts) {
-		pindent(indent); fprintf(stderr, "%s", c_get_name(c_opcode_str, i->opcode));
-		fprintf(stderr, " %s[%d][%s%s%s%s]",
-				c_get_name(c_file_str, i->output.vector->file),
-				i->output.vector->id,
-				c_get_name(c_file_swz, i->output.swizzle[0]),
-				c_get_name(c_file_swz, i->output.swizzle[1]),
-				c_get_name(c_file_swz, i->output.swizzle[2]),
-				c_get_name(c_file_swz, i->output.swizzle[3]));
-		for (j = 0; j < i->ninput; j++) {
-			fprintf(stderr, " %s[%d][%s%s%s%s]",
-					c_get_name(c_file_str, i->input[j].vector->file),
-					i->input[j].vector->id,
-					c_get_name(c_file_swz, i->input[j].swizzle[0]),
-					c_get_name(c_file_swz, i->input[j].swizzle[1]),
-					c_get_name(c_file_swz, i->input[j].swizzle[2]),
-					c_get_name(c_file_swz, i->input[j].swizzle[3]));
+		for (k = 0; k < i->nop; k++) {
+			pindent(indent);
+			fprintf(stderr, "%s", c_get_name(c_opcode_str, i->op[k].opcode));
+			fprintf(stderr, " %s[%d][%s]",
+				c_get_name(c_file_str, i->op[k].output.vector->file),
+				i->op[k].output.vector->id,
+				c_get_name(c_file_swz, i->op[k].output.swizzle));
+			for (j = 0; j < i->op[k].ninput; j++) {
+				fprintf(stderr, " %s[%d][%s]",
+						c_get_name(c_file_str, i->op[k].input[j].vector->file),
+						i->op[k].input[j].vector->id,
+						c_get_name(c_file_swz, i->op[k].input[j].swizzle));
+			}
+			fprintf(stderr, ";\n");
 		}
-		fprintf(stderr, ";\n");
 	}
 }
 
diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c
index 1be5bf2..623ac04 100644
--- a/src/gallium/drivers/r600/r600_compiler_r600.c
+++ b/src/gallium/drivers/r600/r600_compiler_r600.c
@@ -60,16 +60,31 @@ int r600_shader_insert_fetch(struct c_shader *shader)
 		if (vr == NULL)
 			return -ENOMEM;
 		memset(&instruction, 0, sizeof(struct c_instruction));
-		instruction.opcode = C_OPCODE_VFETCH;
-		instruction.write_mask = 0xF;
-		instruction.ninput = 2;
-		instruction.output.vector = v;
-		instruction.input[0].vector = vi;
-		instruction.input[1].vector = vr;
-		instruction.output.swizzle[0] = C_SWIZZLE_X;
-		instruction.output.swizzle[1] = C_SWIZZLE_Y;
-		instruction.output.swizzle[2] = C_SWIZZLE_Z;
-		instruction.output.swizzle[3] = C_SWIZZLE_W;
+		instruction.nop = 4;
+		instruction.op[0].opcode = C_OPCODE_VFETCH;
+		instruction.op[1].opcode = C_OPCODE_VFETCH;
+		instruction.op[2].opcode = C_OPCODE_VFETCH;
+		instruction.op[3].opcode = C_OPCODE_VFETCH;
+		instruction.op[0].ninput = 2;
+		instruction.op[1].ninput = 2;
+		instruction.op[2].ninput = 2;
+		instruction.op[3].ninput = 2;
+		instruction.op[0].output.vector = v;
+		instruction.op[1].output.vector = v;
+		instruction.op[2].output.vector = v;
+		instruction.op[3].output.vector = v;
+		instruction.op[0].input[0].vector = vi;
+		instruction.op[0].input[1].vector = vr;
+		instruction.op[1].input[0].vector = vi;
+		instruction.op[1].input[1].vector = vr;
+		instruction.op[2].input[0].vector = vi;
+		instruction.op[2].input[1].vector = vr;
+		instruction.op[3].input[0].vector = vi;
+		instruction.op[3].input[1].vector = vr;
+		instruction.op[0].output.swizzle = C_SWIZZLE_X;
+		instruction.op[1].output.swizzle = C_SWIZZLE_Y;
+		instruction.op[2].output.swizzle = C_SWIZZLE_Z;
+		instruction.op[3].output.swizzle = C_SWIZZLE_W;
 		r = c_node_add_new_instruction_head(&shader->entry, &instruction);
 		if (r)
 			return r;
@@ -316,7 +331,7 @@ static int r600_shader_add_vfetch(struct r600_shader *rshader,
 
 	if (instruction == NULL)
 		return 0;
-	if (instruction->opcode != C_OPCODE_VFETCH)
+	if (instruction->op[0].opcode != C_OPCODE_VFETCH)
 		return 0;
 	if (!c_list_empty(&node->alu)) {
 		rnode = r600_shader_new_node(rshader, node->node);
@@ -327,13 +342,13 @@ static int r600_shader_add_vfetch(struct r600_shader *rshader,
 	vfetch = calloc(1, sizeof(struct r600_shader_vfetch));
 	if (vfetch == NULL)
 		return -ENOMEM;
-	r = r600_shader_find_gpr(rshader, instruction->output.vector, 0, &vfetch->dst[0]);
+	r = r600_shader_find_gpr(rshader, instruction->op[0].output.vector, 0, &vfetch->dst[0]);
 	if (r)
 		return r;
-	r = r600_shader_find_gpr(rshader, instruction->input[0].vector, 0, &vfetch->src[0]);
+	r = r600_shader_find_gpr(rshader, instruction->op[0].input[0].vector, 0, &vfetch->src[0]);
 	if (r)
 		return r;
-	r = r600_shader_find_gpr(rshader, instruction->input[1].vector, 0, &vfetch->src[1]);
+	r = r600_shader_find_gpr(rshader, instruction->op[0].input[1].vector, 0, &vfetch->src[1]);
 	if (r)
 		return r;
 	vfetch->dst[0].chan = C_SWIZZLE_X;
@@ -355,7 +370,7 @@ static int r600_node_translate(struct r600_shader *rshader, struct c_node *node)
 	if (rnode == NULL)
 		return -ENOMEM;
 	c_list_for_each(instruction, &node->insts) {
-		switch (instruction->opcode) {
+		switch (instruction->op[0].opcode) {
 		case C_OPCODE_VFETCH:
 			r = r600_shader_add_vfetch(rshader, rnode, instruction);
 			if (r) {
@@ -414,79 +429,13 @@ static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshade
 	return alu;
 }
 
-static int r600_shader_node_add_alu(struct r600_shader *rshader,
-					struct r600_shader_node *node,
-					struct r600_shader_alu *alu,
-					unsigned instruction,
-					unsigned ninput,
-					struct r600_shader_operand *dst,
-					struct r600_shader_operand src[3])
-{
-	struct r600_shader_alu *nalu;
-	unsigned nconstant = 0, nliteral = 0, slot, i;
-
-	/* count number of constant & literal */
-	for (i = 0; i < ninput; i++) {
-		if (src[i].vector->file == C_FILE_IMMEDIATE) {
-			nliteral++;
-			nconstant++;
-		}
-	}
-
-	slot = dst->chan;
-	if (r600_instruction_info[instruction].is_trans) {
-		slot = 4;
-	}
-
-	/* allocate new alu group if necessary */
-	nalu = alu;
-	if (alu == NULL) {
-		nalu = r600_shader_insert_alu(rshader, node);
-		if (nalu == NULL)
-			return -ENOMEM;
-		alu = nalu;
-	}
-	if ((alu->alu[slot].inst != INST_NOP &&
-		alu->alu[4].inst != INST_NOP) ||
-		(alu->nconstant + nconstant) > 4 ||
-		(alu->nliteral + nliteral) > 4) {
-		/* neither trans neither dst slot are free need new alu */
-		nalu = r600_shader_insert_alu(rshader, node);
-		if (nalu == NULL)
-			return -ENOMEM;
-		alu = nalu;
-	}
-	if (alu->alu[slot].inst != INST_NOP) {
-		slot = 4;
-	}
-
-	alu->alu[slot].dst = *dst;
-	alu->alu[slot].inst = instruction;
-	alu->alu[slot].opcode = r600_instruction_info[instruction].opcode;
-	alu->alu[slot].is_op3 = r600_instruction_info[instruction].is_op3;
-	for (i = 0; i < ninput; i++) {
-		alu->alu[slot].src[i] = src[i];
-		if (src[i].vector->file == C_FILE_IMMEDIATE) {
-			alu->literal[alu->nliteral++] = src[i].vector->channel[0]->value;
-			alu->literal[alu->nliteral++] = src[i].vector->channel[1]->value;
-			alu->literal[alu->nliteral++] = src[i].vector->channel[2]->value;
-			alu->literal[alu->nliteral++] = src[i].vector->channel[3]->value;
-		}
-	}
-	return 0;
-}
-
 static int r600_shader_alu_translate(struct r600_shader *rshader,
 					struct r600_shader_node *node,
 					struct c_instruction *instruction)
 {
-	struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->opcode];
-	struct r600_instruction_info *info;
-	struct r600_shader_alu *alu;
 	struct r600_shader_node *rnode;
-	int r, i, j;
-	struct r600_shader_operand dst;
-	struct r600_shader_operand src[3];
+	struct r600_shader_alu *alu;
+	int i, j, r, comp;
 
 	if (!c_list_empty(&node->vfetch)) {
 		rnode = r600_shader_new_node(rshader, node->node);
@@ -496,40 +445,57 @@ static int r600_shader_alu_translate(struct r600_shader *rshader,
 		}
 		node = rnode;
 	}
+
+	/* initialize alu */
 	alu = r600_shader_insert_alu(rshader, node);
-	if (alu == NULL) {
-		fprintf(stderr, "%s %d instert alu node failed\n", __func__, __LINE__);
-		return -ENOMEM;
-	}
-	for (i = 0; i < 4; i++) {
-		if (!(instruction->write_mask) || instruction->output.swizzle[i] == C_SWIZZLE_D)
-			continue;
-		if (ainfo->instruction == INST_NOP) {
-			fprintf(stderr, "%s:%d unsupported instruction %d\n", __FILE__, __LINE__, instruction->opcode);
-			continue;
-		}
-		info = &r600_instruction_info[ainfo->instruction];
-		r = r600_shader_find_gpr(rshader, instruction->output.vector,
-					instruction->output.swizzle[i], &dst);
-		if (r) {
-			fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
-			return r;
+
+	/* check special operation like lit */
+
+	/* go through operation */
+	for (i = 0; i < instruction->nop; i++) {
+		struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->op[i].opcode];
+		struct r600_instruction_info *iinfo = &r600_instruction_info[ainfo->instruction];
+		unsigned comp;
+
+		/* check that output is a valid component */
+		comp = instruction->op[i].output.swizzle;
+		switch (comp) {
+		case C_SWIZZLE_X:
+		case C_SWIZZLE_Y:
+		case C_SWIZZLE_Z:
+		case C_SWIZZLE_W:
+			break;
+		case C_SWIZZLE_0:
+		case C_SWIZZLE_1:
+		default:
+			fprintf(stderr, "%s %d invalid output\n", __func__, __LINE__);
+			return -EINVAL;
 		}
-		for (j = 0; j < instruction->ninput; j++) {
-			r = r600_shader_find_gpr(rshader, instruction->input[j].vector,
-					instruction->input[j].swizzle[i], &src[j]);
+		alu->alu[comp].inst = ainfo->instruction;
+		alu->alu[comp].opcode = iinfo->opcode;
+		alu->alu[comp].is_op3 = iinfo->is_op3;
+		for (j = 0; j < instruction->op[i].ninput; j++) {
+			r = r600_shader_find_gpr(rshader, instruction->op[i].input[j].vector,
+					instruction->op[i].input[j].swizzle, &alu->alu[comp].src[j]);
 			if (r) {
 				fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
 				return r;
 			}
 		}
-		r = r600_shader_node_add_alu(rshader, node, alu, ainfo->instruction,
-					instruction->ninput, &dst, src);
+		r = r600_shader_find_gpr(rshader, instruction->op[i].output.vector,
+				instruction->op[i].output.swizzle, &alu->alu[comp].dst);
 		if (r) {
-			fprintf(stderr, "%s %d failed\n", __FILE__, __LINE__);
+			fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
 			return r;
 		}
 	}
+	for (i = instruction->nop; i >= 0; i--) {
+		if (alu->alu[i].inst != INST_NOP) {
+			alu->alu[i].last = 1;
+			alu->nalu = i + 1;
+			break;
+		}
+	}
 	return 0;
 }
 
@@ -576,12 +542,14 @@ int r600_shader_legalize(struct r600_shader *rshader)
 	struct r600_shader_node *node, *nnode;
 	struct r600_shader_alu *alu, *nalu;
 
+#if 0
 	c_list_for_each_safe(node, nnode, &rshader->nodes) {
 		c_list_for_each_safe(alu, nalu, &node->alu) {
 			alu->nalu = 5;
 			alu->alu[4].last = 1;
 		}
 	}
+#endif
 	return 0;
 }
 
diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c
index 563ca06..172cf15 100644
--- a/src/gallium/drivers/r600/r600_compiler_tgsi.c
+++ b/src/gallium/drivers/r600/r600_compiler_tgsi.c
@@ -146,7 +146,7 @@ static int ntransform_instruction(struct tgsi_shader *ts)
 	struct c_shader *shader = ts->shader;
 	struct c_instruction instruction;
 	unsigned opcode;
-	int i, r;
+	int i, j, r;
 
 	if (fi->Instruction.NumDstRegs > 1) {
 		fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
@@ -192,21 +192,48 @@ static int ntransform_instruction(struct tgsi_shader *ts)
 	}
 	/* FIXME add flow instruction handling */
 	memset(&instruction, 0, sizeof(struct c_instruction));
-	instruction.opcode = opcode;
-	instruction.ninput = fi->Instruction.NumSrcRegs;
-	instruction.write_mask = fi->Dst[0].Register.WriteMask;
-	for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
-		instruction.input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index];
-		instruction.input[i].swizzle[0] = fi->Src[i].Register.SwizzleX;
-		instruction.input[i].swizzle[1] = fi->Src[i].Register.SwizzleY;
-		instruction.input[i].swizzle[2] = fi->Src[i].Register.SwizzleZ;
-		instruction.input[i].swizzle[3] = fi->Src[i].Register.SwizzleW;
+	instruction.nop = 0;
+	for (j = 0; j < 4; j++) {
+		instruction.op[instruction.nop].opcode = opcode;
+		instruction.op[instruction.nop].ninput = fi->Instruction.NumSrcRegs;
+		for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
+			instruction.op[instruction.nop].input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index];
+			switch (j) {
+			case 0:
+				instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleX;
+				break;
+			case 1:
+				instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleY;
+				break;
+			case 2:
+				instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleZ;
+				break;
+			case 3:
+				instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleW;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+		instruction.op[instruction.nop].output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index];
+		switch (j) {
+		case 0:
+			instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D;
+			break;
+		case 1:
+			instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Y : C_SWIZZLE_D;
+			break;
+		case 2:
+			instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Z : C_SWIZZLE_D;
+			break;
+		case 3:
+			instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_W : C_SWIZZLE_D;
+			break;
+		default:
+			return -EINVAL;
+		}
+		instruction.nop++;
 	}
-	instruction.output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index];
-	instruction.output.swizzle[0] = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D;
-	instruction.output.swizzle[1] = (fi->Dst[0].Register.WriteMask & 0x2) ? C_SWIZZLE_Y : C_SWIZZLE_D;
-	instruction.output.swizzle[2] = (fi->Dst[0].Register.WriteMask & 0x4) ? C_SWIZZLE_Z : C_SWIZZLE_D;
-	instruction.output.swizzle[3] = (fi->Dst[0].Register.WriteMask & 0x8) ? C_SWIZZLE_W : C_SWIZZLE_D;
 	return c_node_add_new_instruction(ts->node, &instruction);
 }
 



More information about the mesa-commit mailing list