Mesa (master): freedreno/a3xx: 3d/array textures

Rob Clark robclark at kemper.freedesktop.org
Sat Sep 13 19:33:45 UTC 2014


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sat Sep 13 08:25:51 2014 -0400

freedreno/a3xx: 3d/array textures

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/fd3_texture.c   |   19 +++++++-
 src/gallium/drivers/freedreno/freedreno_context.h  |    2 +-
 src/gallium/drivers/freedreno/freedreno_resource.c |   41 ++++++++++++++++-
 src/gallium/drivers/freedreno/ir3/ir3_compiler.c   |   47 ++++++++++++++++++--
 4 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
index b0e5efb..8a5140f 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
@@ -175,7 +175,24 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 	/* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */
 	so->texconst2 =
 			A3XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp);
-	so->texconst3 = 0x00000000;  /* ??? */
+	switch (prsc->target) {
+	case PIPE_TEXTURE_1D_ARRAY:
+	case PIPE_TEXTURE_2D_ARRAY:
+		so->texconst3 =
+				A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->array_size, lvl)) |
+				A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) |
+				A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0);
+		break;
+	case PIPE_TEXTURE_3D:
+		so->texconst3 =
+				A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) |
+				A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) |
+				A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0);
+		break;
+	default:
+		so->texconst3 = 0x00000000;
+		break;
+	}
 
 	return &so->base;
 }
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 2c9c3a8..c59390a 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -226,7 +226,7 @@ struct fd_context {
 	 * tiling commands, we need to make sure we need to leave enough
 	 * room at the end to append the tiling commands when we flush.
 	 * 0x7000 dwords should be a couple times more than we ever need
-	 * so should be a nice concervative threshold.
+	 * so should be a nice conservative threshold.
 	 */
 #define FD_TILING_COMMANDS_DWORDS 0x7000
 
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 034e4b4..1b39c33 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -215,6 +215,36 @@ setup_slices(struct fd_resource *rsc)
 	return size;
 }
 
+/* 2d array and 3d textures seem to want their layers aligned to
+ * page boundaries
+ */
+static uint32_t
+setup_slices_array(struct fd_resource *rsc)
+{
+	struct pipe_resource *prsc = &rsc->base.b;
+	uint32_t level, size = 0;
+	uint32_t width = prsc->width0;
+	uint32_t height = prsc->height0;
+	uint32_t depth = prsc->depth0;
+
+	for (level = 0; level <= prsc->last_level; level++) {
+		struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
+		uint32_t aligned_width = align(width, 32);
+
+		slice->pitch = aligned_width;
+		slice->offset = size;
+		slice->size0 = align(slice->pitch * height * rsc->cpp, 4096);
+
+		size += slice->size0 * depth * prsc->array_size;
+
+		width = u_minify(width, 1);
+		height = u_minify(height, 1);
+		depth = u_minify(depth, 1);
+	}
+
+	return size;
+}
+
 /**
  * Create a new texture object, using the given template info.
  */
@@ -246,7 +276,16 @@ fd_resource_create(struct pipe_screen *pscreen,
 
 	assert(rsc->cpp);
 
-	size = setup_slices(rsc);
+	switch (tmpl->target) {
+	case PIPE_TEXTURE_3D:
+	case PIPE_TEXTURE_1D_ARRAY:
+	case PIPE_TEXTURE_2D_ARRAY:
+		size = setup_slices_array(rsc);
+		break;
+	default:
+		size = setup_slices(rsc);
+		break;
+	}
 
 	realloc_bo(rsc, size);
 	if (!rsc->bo)
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index 33a737b..5d96187 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -1094,6 +1094,11 @@ get_tex_info(struct ir3_compile_context *ctx,
 		.src_wrmask = TGSI_WRITEMASK_XYZ,
 		.flags = IR3_INSTR_S,
 	};
+	static const struct tex_info tex1da = {
+		.order = { 0, -1,  2, -1 },  /* coord.xz */
+		.src_wrmask = TGSI_WRITEMASK_XYZ,
+		.flags = IR3_INSTR_A,
+	};
 	static const struct tex_info tex2d = {
 		.order = { 0,  1, -1, -1 },  /* coord.xy */
 		.src_wrmask = TGSI_WRITEMASK_XY,
@@ -1104,6 +1109,11 @@ get_tex_info(struct ir3_compile_context *ctx,
 		.src_wrmask = TGSI_WRITEMASK_XYZ,
 		.flags = IR3_INSTR_S,
 	};
+	static const struct tex_info tex2da = {
+		.order = { 0,  1,  2, -1 },  /* coord.xyz */
+		.src_wrmask = TGSI_WRITEMASK_XYZ,
+		.flags = IR3_INSTR_A,
+	};
 	static const struct tex_info tex3d = {
 		.order = { 0,  1,  2, -1 },  /* coord.xyz */
 		.src_wrmask = TGSI_WRITEMASK_XYZ,
@@ -1124,6 +1134,11 @@ get_tex_info(struct ir3_compile_context *ctx,
 		.src_wrmask = TGSI_WRITEMASK_XYZW,
 		.flags = IR3_INSTR_P | IR3_INSTR_S,
 	};
+	static const struct tex_info txp1da = {
+		.order = { 0, -1,  2,  3 },  /* coord.xzw */
+		.src_wrmask = TGSI_WRITEMASK_XYZW,
+		.flags = IR3_INSTR_P | IR3_INSTR_A,
+	};
 	static const struct tex_info txp2d = {
 		.order = { 0,  1,  3, -1 },  /* coord.xyw */
 		.src_wrmask = TGSI_WRITEMASK_XYZ,
@@ -1134,6 +1149,11 @@ get_tex_info(struct ir3_compile_context *ctx,
 		.src_wrmask = TGSI_WRITEMASK_XYZW,
 		.flags = IR3_INSTR_P | IR3_INSTR_S,
 	};
+	static const struct tex_info txp2da = {
+		.order = { 0,  1,  2,  3 },  /* coord.xyzw */
+		.src_wrmask = TGSI_WRITEMASK_XYZW,
+		.flags = IR3_INSTR_P | IR3_INSTR_A,
+	};
 	static const struct tex_info txp3d = {
 		.order = { 0,  1,  2,  3 },  /* coord.xyzw */
 		.src_wrmask = TGSI_WRITEMASK_XYZW,
@@ -1151,12 +1171,16 @@ get_tex_info(struct ir3_compile_context *ctx,
 			return &tex1d;
 		case TGSI_TEXTURE_SHADOW1D:
 			return &tex1ds;
+		case TGSI_TEXTURE_1D_ARRAY:
+			return &tex1da;
 		case TGSI_TEXTURE_2D:
 		case TGSI_TEXTURE_RECT:
 			return &tex2d;
 		case TGSI_TEXTURE_SHADOW2D:
 		case TGSI_TEXTURE_SHADOWRECT:
 			return &tex2ds;
+		case TGSI_TEXTURE_2D_ARRAY:
+			return &tex2da;
 		case TGSI_TEXTURE_3D:
 		case TGSI_TEXTURE_CUBE:
 			return &tex3d;
@@ -1174,12 +1198,16 @@ get_tex_info(struct ir3_compile_context *ctx,
 			return &txp1d;
 		case TGSI_TEXTURE_SHADOW1D:
 			return &txp1ds;
+		case TGSI_TEXTURE_1D_ARRAY:
+			return &txp1da;
 		case TGSI_TEXTURE_2D:
 		case TGSI_TEXTURE_RECT:
 			return &txp2d;
 		case TGSI_TEXTURE_SHADOW2D:
 		case TGSI_TEXTURE_SHADOWRECT:
 			return &txp2ds;
+		case TGSI_TEXTURE_2D_ARRAY:
+			return &txp2da;
 		case TGSI_TEXTURE_3D:
 		case TGSI_TEXTURE_CUBE:
 			return &txp3d;
@@ -1203,6 +1231,18 @@ static bool check_swiz(struct tgsi_src_register *src, const int8_t order[4])
 	return true;
 }
 
+static bool is_1d(unsigned tex)
+{
+	switch (tex) {
+	case TGSI_TEXTURE_1D:
+	case TGSI_TEXTURE_SHADOW1D:
+	case TGSI_TEXTURE_1D_ARRAY:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static struct tgsi_src_register *
 get_tex_coord(struct ir3_compile_context *ctx,
 		struct tgsi_full_instruction *inst,
@@ -1217,8 +1257,8 @@ get_tex_coord(struct ir3_compile_context *ctx,
 	if (is_rel_or_const(coord))
 		needs_mov = true;
 
-	/* 1D textures we fix up w/ 0.0 as 2nd coord: */
-	if ((tex == TGSI_TEXTURE_1D) || (tex == TGSI_TEXTURE_SHADOW1D))
+	/* 1D textures we fix up w/ 0.5 as 2nd coord: */
+	if (is_1d(tex))
 		needs_mov = true;
 
 	/* The texture sample instructions need to coord in successive
@@ -1252,8 +1292,7 @@ get_tex_coord(struct ir3_compile_context *ctx,
 		}
 
 		/* fix up .y coord: */
-		if ((tex == TGSI_TEXTURE_1D) ||
-				(tex == TGSI_TEXTURE_SHADOW1D)) {
+		if (is_1d(tex)) {
 			instr = instr_create(ctx, 1, 0);  /* mov */
 			instr->cat1.src_type = type_mov;
 			instr->cat1.dst_type = type_mov;




More information about the mesa-commit mailing list