This fixes the following piglit tests:
shaders/glsl-derivs-swizzle
shaders/glsl-fs-shadow2d
shaders/glsl-fs-shadow2d-01
shaders/glsl-fs-shadow2d-07
spec/ARB_texture_rg/fs-shadow2d-red-01
From 37ede956be2312cc6fea3c01a69ff267de5ae7e7 Mon Sep 17 00:00:00 2001
From: Fabian Bieler <[email protected]>
Date: Wed, 23 Mar 2011 18:12:44 +0100
Subject: [PATCH 1/3] r600g: Handle texture fetch instructions with swizzle on source register

---
 src/gallium/drivers/r600/r600_shader.c |   50 ++++++++++++++++++++++++-------
 1 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index e7285d6..55e63b9 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -1526,9 +1526,11 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 	unsigned src_gpr;
 	int r, i;
 	int opcode;
-	boolean src_not_temp =
+	/* Texture fetch instructions can only use gprs as source. */
+	const boolean src_requires_loading =
 		inst->Src[0].Register.File != TGSI_FILE_TEMPORARY &&
 		inst->Src[0].Register.File != TGSI_FILE_INPUT;
+	boolean src_loaded = FALSE;
 
 	src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
 
@@ -1570,13 +1572,28 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 		r = r600_bc_add_alu(ctx->bc, &alu);
 		if (r)
 			return r;
-		src_not_temp = FALSE;
+		src_loaded = TRUE;
 		src_gpr = ctx->temp_reg;
 	}
 
 	if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) {
-		static const unsigned src0_swizzle[] = {2, 2, 0, 1};
-		static const unsigned src1_swizzle[] = {1, 0, 2, 2};
+		unsigned src0_swizzle[4];
+		unsigned src1_swizzle[4];
+		if (src_loaded) {
+			src0_swizzle[0] = 2; src0_swizzle[1] = 2;
+			src0_swizzle[2] = 0; src0_swizzle[3] = 1;
+			src1_swizzle[0] = 1; src1_swizzle[1] = 0;
+			src1_swizzle[2] = 2; src1_swizzle[3] = 2;
+		} else {
+			src0_swizzle[0] = ctx->src[0].swizzle[2];
+			src0_swizzle[1] = ctx->src[0].swizzle[2];
+			src0_swizzle[2] = ctx->src[0].swizzle[0];
+			src0_swizzle[3] = ctx->src[0].swizzle[1];
+			src1_swizzle[0] = ctx->src[0].swizzle[1];
+			src1_swizzle[1] = ctx->src[0].swizzle[0];
+			src1_swizzle[2] = ctx->src[0].swizzle[2];
+			src1_swizzle[3] = ctx->src[0].swizzle[2];
+		}
 
 		/* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */
 		for (i = 0; i < 4; i++) {
@@ -1655,11 +1672,11 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 		if (r)
 			return r;
 
-		src_not_temp = FALSE;
+		src_loaded = TRUE;
 		src_gpr = ctx->temp_reg;
 	}
 
-	if (src_not_temp) {
+	if (src_requires_loading && !src_loaded) {
 		for (i = 0; i < 4; i++) {
 			memset(&alu, 0, sizeof(struct r600_bc_alu));
 			alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
@@ -1673,6 +1690,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 			if (r)
 				return r;
 		}
+		src_loaded = TRUE;
 		src_gpr = ctx->temp_reg;
 	}
 
@@ -1691,12 +1709,20 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 	tex.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7;
 	tex.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7;
 	tex.dst_sel_w = (inst->Dst[0].Register.WriteMask & 8) ? 3 : 7;
-	tex.src_sel_x = 0;
-	tex.src_sel_y = 1;
-	tex.src_sel_z = 2;
-	tex.src_sel_w = 3;
+	if (src_loaded) {
+		tex.src_sel_x = 0;
+		tex.src_sel_y = 1;
+		tex.src_sel_z = 2;
+		tex.src_sel_w = 3;
+	} else {
+		tex.src_sel_x = ctx->src[0].swizzle[0];
+		tex.src_sel_y = ctx->src[0].swizzle[1];
+		tex.src_sel_z = ctx->src[0].swizzle[2];
+		tex.src_sel_w = ctx->src[0].swizzle[3];
+	}
 
 	if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) {
+		assert(src_loaded);
 		tex.src_sel_x = 1;
 		tex.src_sel_y = 0;
 		tex.src_sel_z = 3;
@@ -1712,12 +1738,12 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
 	if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
 		tex.coord_type_z = 0;
-		tex.src_sel_z = 1;
+		tex.src_sel_z = tex.src_sel_y;
 	} else if (inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
 		tex.coord_type_z = 0;
 
 	if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D || inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D)
-		tex.src_sel_w = 2;
+		tex.src_sel_w = tex.src_sel_z;
 
 	r = r600_bc_add_tex(ctx->bc, &tex);
 	if (r)
-- 
1.7.4.1

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to