Mesa (9.1): r600g: Fix UMAD on Cayman

Dave Airlie airlied at kemper.freedesktop.org
Wed May 15 01:11:13 UTC 2013


Module: Mesa
Branch: 9.1
Commit: c3eb301a3a09f4b1b471afdbd16a4f986702f194
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c3eb301a3a09f4b1b471afdbd16a4f986702f194

Author: Martin Andersson <g02maran at gmail.com>
Date:   Tue Apr  2 22:43:33 2013 +0200

r600g: Fix UMAD on Cayman

The multiplication part of tgsi_umad did not work on Cayman, because it did
not populate the correct vector slots.

This fixed hardlocks in the EXT_transform_feedback/order tests.

NOTE: This is a candidate for the stable branches.
(might not be easy to cherry-pick though)

Signed-off-by: Marek Olšák <maraeo at gmail.com>
Stable backport:
Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/r600_shader.c |   51 ++++++++++++++++++++++----------
 1 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index e8992ba..e0fb18b 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -5760,7 +5760,7 @@ static int tgsi_umad(struct r600_shader_ctx *ctx)
 {
 	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
 	struct r600_bytecode_alu alu;
-	int i, j, r;
+	int i, j, k, r;
 	int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask);
 
 	/* src0 * src1 */
@@ -5768,21 +5768,40 @@ static int tgsi_umad(struct r600_shader_ctx *ctx)
 		if (!(inst->Dst[0].Register.WriteMask & (1 << i)))
 			continue;
 
-		memset(&alu, 0, sizeof(struct r600_bytecode_alu));
-
-		alu.dst.chan = i;
-		alu.dst.sel = ctx->temp_reg;
-		alu.dst.write = 1;
-
-		alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT);
-		for (j = 0; j < 2; j++) {
-		        r600_bytecode_src(&alu.src[j], &ctx->src[j], i);
-		}
-
-		alu.last = 1;
-		r = r600_bytecode_add_alu(ctx->bc, &alu);
-		if (r)
-			return r;
+                if (ctx->bc->chip_class == CAYMAN) {
+                        for (j = 0; j < 4; j++) {
+                                memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+                                alu.dst.chan = j;
+                                alu.dst.sel = ctx->temp_reg;
+                                alu.dst.write = (j == i);
+
+                                if (j == 3)
+                                        alu.last = 1;
+                                alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT);
+                                for (k = 0; k < inst->Instruction.NumSrcRegs; k++) {
+                                        r600_bytecode_src(&alu.src[k], &ctx->src[k], i);
+                                }
+                                r = r600_bytecode_add_alu(ctx->bc, &alu);
+                                if (r)
+                                        return r;
+                        }
+                } else {
+                        memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+
+                        alu.dst.chan = i;
+                        alu.dst.sel = ctx->temp_reg;
+                        alu.dst.write = 1;
+
+                        alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT);
+                        for (j = 0; j < 2; j++) {
+                                r600_bytecode_src(&alu.src[j], &ctx->src[j], i);
+                        }
+
+                        alu.last = 1;
+                        r = r600_bytecode_add_alu(ctx->bc, &alu);
+                        if (r)
+                                return r;
+                }
 	}
 
 




More information about the mesa-commit mailing list