Mesa (master): r600g: first pass at texture support

Jerome Glisse glisse at kemper.freedesktop.org
Sat Jul 24 00:57:27 UTC 2010


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

Author: Jerome Glisse <jglisse at redhat.com>
Date:   Fri Jul 23 20:55:48 2010 -0400

r600g: first pass at texture support

This add texture support to the assembler, generated code is
wrong (tested against working dump).

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

---

 src/gallium/drivers/r600/r600_asm.c     |   91 +++++++++++++++++++++++++++++--
 src/gallium/drivers/r600/r600_asm.h     |   29 ++++++++++
 src/gallium/drivers/r600/r600_context.c |    2 +-
 src/gallium/drivers/r600/r600_helper.c  |   11 +++-
 src/gallium/drivers/r600/r600_shader.c  |   31 +++++++++--
 src/gallium/drivers/r600/r600_sq.h      |    2 +
 6 files changed, 152 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 6e48703..e678a2f 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -38,6 +38,7 @@ static struct r600_bc_cf *r600_bc_cf(void)
 	LIST_INITHEAD(&cf->list);
 	LIST_INITHEAD(&cf->alu);
 	LIST_INITHEAD(&cf->vtx);
+	LIST_INITHEAD(&cf->tex);
 	return cf;
 }
 
@@ -61,6 +62,16 @@ static struct r600_bc_vtx *r600_bc_vtx(void)
 	return vtx;
 }
 
+static struct r600_bc_tex *r600_bc_tex(void)
+{
+	struct r600_bc_tex *tex = CALLOC_STRUCT(r600_bc_tex);
+
+	if (tex == NULL)
+		return NULL;
+	LIST_INITHEAD(&tex->list);
+	return tex;
+}
+
 int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
 {
 	LIST_INITHEAD(&bc->cf);
@@ -149,8 +160,14 @@ int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
 {
 	struct r600_bc_alu *alu;
 
-	if (bc->cf_last == NULL ||
-		bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||
+	if (bc->cf_last == NULL) {
+		R600_ERR("no last CF\n");
+		return -EINVAL;
+	}
+	if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+		return 0;
+	}
+	if (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||
 		LIST_IS_EMPTY(&bc->cf_last->alu)) {
 		R600_ERR("last CF is not ALU (%p)\n", bc->cf_last);
 		return -EINVAL;
@@ -186,13 +203,39 @@ int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
 		bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX;
 	}
 	LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx);
-	/* each fetch use 6 dwords */
+	/* each fetch use 4 dwords */
 	bc->cf_last->ndw += 4;
 	bc->ndw += 4;
 	return 0;
 }
 
-int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
+{
+	struct r600_bc_tex *ntex = r600_bc_tex();
+	int r;
+
+	if (ntex == NULL)
+		return -ENOMEM;
+	memcpy(ntex, tex, sizeof(struct r600_bc_tex));
+
+	/* cf can contains only alu or only vtx or only tex */
+	if (bc->cf_last == NULL ||
+		bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+		r = r600_bc_add_cf(bc);
+		if (r) {
+			free(ntex);
+			return r;
+		}
+		bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX;
+	}
+	LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex);
+	/* each texture fetch use 4 dwords */
+	bc->cf_last->ndw += 4;
+	bc->ndw += 4;
+	return 0;
+}
+
+static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
 {
 	bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
 				S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
@@ -209,6 +252,35 @@ int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
 	return 0;
 }
 
+static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id)
+{
+	bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) |
+				S_SQ_TEX_WORD0_RESOURCE_ID(tex->resource_id) |
+				S_SQ_TEX_WORD0_SRC_GPR(tex->src_gpr) |
+				S_SQ_TEX_WORD0_SRC_REL(tex->src_rel);
+	bc->bytecode[id++] = S_SQ_TEX_WORD1_DST_GPR(tex->dst_gpr) |
+				S_SQ_TEX_WORD1_DST_REL(tex->dst_rel) |
+				S_SQ_TEX_WORD1_DST_SEL_X(tex->dst_sel_x) |
+				S_SQ_TEX_WORD1_DST_SEL_Y(tex->dst_sel_y) |
+				S_SQ_TEX_WORD1_DST_SEL_Z(tex->dst_sel_z) |
+				S_SQ_TEX_WORD1_DST_SEL_W(tex->dst_sel_w) |
+				S_SQ_TEX_WORD1_LOD_BIAS(tex->lod_bias) |
+				S_SQ_TEX_WORD1_COORD_TYPE_X(tex->coord_type_x) |
+				S_SQ_TEX_WORD1_COORD_TYPE_Y(tex->coord_type_y) |
+				S_SQ_TEX_WORD1_COORD_TYPE_Z(tex->coord_type_z) |
+				S_SQ_TEX_WORD1_COORD_TYPE_W(tex->coord_type_w);
+	bc->bytecode[id++] = S_SQ_TEX_WORD2_OFFSET_X(tex->offset_x) |
+				S_SQ_TEX_WORD2_OFFSET_Y(tex->offset_y) |
+				S_SQ_TEX_WORD2_OFFSET_Z(tex->offset_z) |
+				S_SQ_TEX_WORD2_SAMPLER_ID(tex->sampler_id) |
+				S_SQ_TEX_WORD2_SRC_SEL_X(tex->src_sel_x) |
+				S_SQ_TEX_WORD2_SRC_SEL_Y(tex->src_sel_y) |
+				S_SQ_TEX_WORD2_SRC_SEL_Z(tex->src_sel_z) |
+				S_SQ_TEX_WORD2_SRC_SEL_W(tex->src_sel_w);
+	bc->bytecode[id++] = 0;
+	return 0;
+}
+
 int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
 {
 	unsigned i;
@@ -262,6 +334,7 @@ int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
 					S_SQ_CF_ALU_WORD1_BARRIER(1) |
 					S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
 		break;
+	case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
 	case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
 	case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
 		bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
@@ -295,6 +368,7 @@ int r600_bc_build(struct r600_bc *bc)
 	struct r600_bc_cf *cf;
 	struct r600_bc_alu *alu;
 	struct r600_bc_vtx *vtx;
+	struct r600_bc_tex *tex;
 	unsigned addr;
 	int r;
 
@@ -306,6 +380,7 @@ int r600_bc_build(struct r600_bc *bc)
 		switch (cf->inst) {
 		case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
 			break;
+		case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
 		case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
 		case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
 			/* fetch node need to be 16 bytes aligned*/
@@ -373,6 +448,14 @@ int r600_bc_build(struct r600_bc *bc)
 				addr += 4;
 			}
 			break;
+		case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+			LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+				r = r600_bc_tex_build(bc, tex, addr);
+				if (r)
+					return r;
+				addr += 4;
+			}
+			break;
 		case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
 		case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
 			break;
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index 8a874a9..88fb957 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -51,6 +51,33 @@ struct r600_bc_alu {
 	u32				value[4];
 };
 
+struct r600_bc_tex {
+	struct list_head		list;
+	unsigned			inst;
+	unsigned			resource_id;
+	unsigned			src_gpr;
+	unsigned			src_rel;
+	unsigned			dst_gpr;
+	unsigned			dst_rel;
+	unsigned			dst_sel_x;
+	unsigned			dst_sel_y;
+	unsigned			dst_sel_z;
+	unsigned			dst_sel_w;
+	unsigned			lod_bias;
+	unsigned			coord_type_x;
+	unsigned			coord_type_y;
+	unsigned			coord_type_z;
+	unsigned			coord_type_w;
+	unsigned			offset_x;
+	unsigned			offset_y;
+	unsigned			offset_z;
+	unsigned			sampler_id;
+	unsigned			src_sel_x;
+	unsigned			src_sel_y;
+	unsigned			src_sel_z;
+	unsigned			src_sel_w;
+};
+
 struct r600_bc_vtx {
 	struct list_head		list;
 	unsigned			inst;
@@ -87,6 +114,7 @@ struct r600_bc_cf {
 	unsigned			ndw;
 	unsigned			id;
 	struct list_head		alu;
+	struct list_head		tex;
 	struct list_head		vtx;
 	struct r600_bc_output		output;
 };
@@ -106,6 +134,7 @@ int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
 int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu);
 int r600_bc_add_literal(struct r600_bc *bc, const u32 *value);
 int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx);
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex);
 int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output);
 int r600_bc_build(struct r600_bc *bc);
 
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c
index 3c5195f..05575b5 100644
--- a/src/gallium/drivers/r600/r600_context.c
+++ b/src/gallium/drivers/r600/r600_context.c
@@ -55,7 +55,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,
 	 */
 	if (!dc)
 		radeon_ctx_dump_bof(rctx->ctx, "gallium.bof");
-#if 1
+#if 0
 	radeon_ctx_submit(rctx->ctx);
 #endif
 	rctx->ctx = radeon_ctx_decref(rctx->ctx);
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
index e3175b6..7241ab1 100644
--- a/src/gallium/drivers/r600/r600_helper.c
+++ b/src/gallium/drivers/r600/r600_helper.c
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <util/u_inlines.h>
 #include "r600_screen.h"
+#include "r600_context.h"
 #include "r600d.h"
 
 int r600_conv_pipe_format(unsigned pformat, unsigned *format)
@@ -49,6 +50,12 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
 	case PIPE_FORMAT_R8G8B8A8_SSCALED:
 		*format = V_0280A0_COLOR_8_8_8_8;
 		return 0;
+	case PIPE_FORMAT_R32_FLOAT:
+		*format = V_0280A0_COLOR_32_FLOAT;
+		return 0;
+	case PIPE_FORMAT_R32G32_FLOAT:
+		*format = V_0280A0_COLOR_32_32_FLOAT;
+		return 0;
 	case PIPE_FORMAT_L8_UNORM:
 	case PIPE_FORMAT_A8_UNORM:
 	case PIPE_FORMAT_I8_UNORM:
@@ -60,8 +67,6 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
 	case PIPE_FORMAT_R64G64_FLOAT:
 	case PIPE_FORMAT_R64G64B64_FLOAT:
 	case PIPE_FORMAT_R64G64B64A64_FLOAT:
-	case PIPE_FORMAT_R32_FLOAT:
-	case PIPE_FORMAT_R32G32_FLOAT:
 	case PIPE_FORMAT_R32_UNORM:
 	case PIPE_FORMAT_R32G32_UNORM:
 	case PIPE_FORMAT_R32G32B32_UNORM:
@@ -111,7 +116,7 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
 	case PIPE_FORMAT_R32G32B32_FIXED:
 	case PIPE_FORMAT_R32G32B32A32_FIXED:
 	default:
-		fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat);
+		R600_ERR("unsupported %d\n", pformat);
 		return -EINVAL;
 	}
 }
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index d788ab8..e865f01 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -23,6 +23,7 @@
 #include "pipe/p_shader_tokens.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_dump.h"
 #include "util/u_format.h"
 #include "r600_screen.h"
 #include "r600_context.h"
@@ -259,10 +260,6 @@ static int tgsi_is_supported(struct r600_shader_ctx *ctx)
 		R600_ERR("label unsupported\n");
 		return -EINVAL;
 	}
-	if (i->Instruction.Texture) {
-		R600_ERR("texture unsupported\n");
-		return -EINVAL;
-	}
 	for (j = 0; j < i->Instruction.NumSrcRegs; j++) {
 		if (i->Src[j].Register.Indirect ||
 			i->Src[j].Register.Dimension ||
@@ -321,6 +318,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
 		break;
 	case TGSI_FILE_CONSTANT:
 	case TGSI_FILE_TEMPORARY:
+	case TGSI_FILE_SAMPLER:
 		break;
 	default:
 		R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
@@ -381,7 +379,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
 		tgsi_parse_token(&ctx.parse);
 		switch (ctx.parse.FullToken.Token.Type) {
 		case TGSI_TOKEN_TYPE_IMMEDIATE:
-//			R600_ERR("TGSI_TOKEN_TYPE_IMMEDIATE unsupported\n");
 			immediate = &ctx.parse.FullToken.FullImmediate;
 			value[0] = immediate->u[0].Uint;
 			value[1] = immediate->u[1].Uint;
@@ -713,6 +710,28 @@ static int tgsi_dp(struct r600_shader_ctx *ctx)
 	return tgsi_helper_copy(ctx, inst);
 }
 
+static int tgsi_tex(struct r600_shader_ctx *ctx)
+{
+	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+	struct r600_bc_tex tex;
+
+	memset(&tex, 0, sizeof(struct r600_bc_tex));
+	tex.inst = ctx->inst_info->r600_opcode;
+	tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+	tex.sampler_id = tex.resource_id;
+	tex.src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
+	tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Src[0].Register.Index;
+	tex.dst_sel_x = 0;
+	tex.dst_sel_y = 1;
+	tex.dst_sel_z = 2;
+	tex.dst_sel_w = 3;
+	tex.src_sel_x = 0;
+	tex.src_sel_y = 1;
+	tex.src_sel_z = 2;
+	tex.src_sel_w = 3;
+	return r600_bc_add_tex(ctx->bc, &tex);
+}
+
 static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_ARL,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_MOV,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
@@ -771,7 +790,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_STR,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_TEX,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
 	{TGSI_OPCODE_TXD,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
-	{TGSI_OPCODE_TXP,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+	{TGSI_OPCODE_TXP,	0, 0x10, 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},
 	{TGSI_OPCODE_UP4B,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h
index 4770ab0..002660c 100644
--- a/src/gallium/drivers/r600/r600_sq.h
+++ b/src/gallium/drivers/r600/r600_sq.h
@@ -546,6 +546,8 @@
 #define   S_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) & 0x1) << 28)
 #define   G_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) >> 28) & 0x1)
 #define   C_SQ_TEX_WORD1_COORD_TYPE_X                                0xEFFFFFFF
+#define     V_SQ_TEX_WORD1_COORD_UNNORMALIZED                        0x00000000
+#define     V_SQ_TEX_WORD1_COORD_NORMALIZED                          0x00000001
 #define   S_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) & 0x1) << 29)
 #define   G_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) >> 29) & 0x1)
 #define   C_SQ_TEX_WORD1_COORD_TYPE_Y                                0xDFFFFFFF




More information about the mesa-commit mailing list