Mesa (master): r600g: add TXD support.

Dave Airlie airlied at kemper.freedesktop.org
Wed Jun 15 05:19:23 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jun 15 15:15:41 2011 +1000

r600g: add TXD support.

This at least passes the piglit arb_shader_texture_lod-texgrad test,
the AMD shader analyzer seems to multiply the V component by an unspecified
constant value no idea why.

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/r600_asm.c    |    3 ++
 src/gallium/drivers/r600/r600_pipe.c   |    2 +-
 src/gallium/drivers/r600/r600_shader.c |   61 +++++++++++++++++++++++++++++---
 src/gallium/drivers/r600/r600d.h       |    4 ++
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index aeb1175..c447a03 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1383,6 +1383,9 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
 				break;
 			}
 		}
+		/* slight hack to make gradients always go into same cf */
+		if (ntex->inst == SQ_TEX_INST_SET_GRADIENTS_H)
+			bc->force_add_cf = 1;
 	}
 
 	/* cf can contains only alu or only vtx or only tex */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 4cf11dc..16fe6c5 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -375,6 +375,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+	case PIPE_CAP_SM3:
 		return 1;
 
 	/* Supported except the original R600. */
@@ -395,7 +396,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_INSTANCEID:
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
-	case PIPE_CAP_SM3:
 		return 0;
 
 	case PIPE_CAP_ARRAY_TEXTURES:
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 1b9f663..9a0df23 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -1761,10 +1761,60 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 		inst->Src[0].Register.File != TGSI_FILE_INPUT) ||
 		ctx->src[0].neg || ctx->src[0].abs;
 	boolean src_loaded = FALSE;
+	unsigned sampler_src_reg = 1;
 
 	src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
 
-	if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
+	if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
+		/* TGSI moves the sampler to src reg 3 for TXD */
+		sampler_src_reg = 3;
+
+		/* set gradients h/v */
+		memset(&tex, 0, sizeof(struct r600_bc_tex));
+		tex.inst = SQ_TEX_INST_SET_GRADIENTS_H;
+		tex.sampler_id = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
+		tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
+		tex.src_gpr = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+		tex.src_sel_x = ctx->src[1].swizzle[0];
+		tex.src_sel_y = ctx->src[1].swizzle[1];
+		tex.src_sel_z = ctx->src[1].swizzle[2];
+		tex.src_sel_w = ctx->src[1].swizzle[3];
+		tex.src_rel = ctx->src[1].rel;
+		tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */
+		tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7;
+		if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
+			tex.coord_type_x = 1;
+			tex.coord_type_y = 1;
+			tex.coord_type_z = 1;
+			tex.coord_type_w = 1;
+		}
+		r = r600_bc_add_tex(ctx->bc, &tex);
+		if (r)
+			return r;
+
+		/* set gradients h/v */
+		memset(&tex, 0, sizeof(struct r600_bc_tex));
+		tex.inst = SQ_TEX_INST_SET_GRADIENTS_V;
+		tex.sampler_id = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
+		tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
+		tex.src_gpr = ctx->file_offset[inst->Src[2].Register.File] + inst->Src[2].Register.Index;
+		tex.src_sel_x = ctx->src[2].swizzle[0];
+		tex.src_sel_y = ctx->src[2].swizzle[1];
+		tex.src_sel_z = ctx->src[2].swizzle[2];
+		tex.src_sel_w = ctx->src[2].swizzle[3];
+		tex.src_rel = ctx->src[2].rel;
+		tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */
+		tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7;
+		if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
+			tex.coord_type_x = 1;
+			tex.coord_type_y = 1;
+			tex.coord_type_z = 1;
+			tex.coord_type_w = 1;
+		}
+		r = r600_bc_add_tex(ctx->bc, &tex);
+		if (r)
+			return r;
+	} else if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
 		int out_chan;
 		/* Add perspective divide */
 		if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
@@ -1957,7 +2007,8 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
 	memset(&tex, 0, sizeof(struct r600_bc_tex));
 	tex.inst = opcode;
-	tex.sampler_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+       
+	tex.sampler_id = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
 	tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
 	tex.src_gpr = src_gpr;
 	tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
@@ -3082,7 +3133,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_SNE,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
 	{TGSI_OPCODE_STR,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_TEX,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-	{TGSI_OPCODE_TXD,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+	{TGSI_OPCODE_TXD,	0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
 	{TGSI_OPCODE_TXP,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
 	{TGSI_OPCODE_UP2H,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_UP2US,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
@@ -3240,7 +3291,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_SNE,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
 	{TGSI_OPCODE_STR,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_TEX,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-	{TGSI_OPCODE_TXD,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+	{TGSI_OPCODE_TXD,	0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
 	{TGSI_OPCODE_TXP,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
 	{TGSI_OPCODE_UP2H,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_UP2US,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
@@ -3398,7 +3449,7 @@ static struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_SNE,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
 	{TGSI_OPCODE_STR,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_TEX,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-	{TGSI_OPCODE_TXD,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+	{TGSI_OPCODE_TXD,	0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
 	{TGSI_OPCODE_TXP,	0, SQ_TEX_INST_SAMPLE, tgsi_tex},
 	{TGSI_OPCODE_UP2H,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_UP2US,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 9281b08..95672b1 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -3468,6 +3468,10 @@
 
 #define SQ_TEX_INST_SAMPLE 0x10
 #define SQ_TEX_INST_SAMPLE_L 0x11
+#define SQ_TEX_INST_SAMPLE_G 0x14
 #define SQ_TEX_INST_SAMPLE_C 0x18
 
+#define SQ_TEX_INST_SET_GRADIENTS_H 0xB
+#define SQ_TEX_INST_SET_GRADIENTS_V 0xC
+
 #endif




More information about the mesa-commit mailing list