Mesa (master): freedreno/ir3/nir: handle txs and query_levels tex ops

Rob Clark robclark at kemper.freedesktop.org
Sat Apr 11 16:59:09 UTC 2015


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Thu Apr  9 20:32:14 2015 -0400

freedreno/ir3/nir: handle txs and query_levels tex ops

These correspond to the tgsi TXQ opcode

(plus sneak in a fix for two-sided color)

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

---

 .../drivers/freedreno/ir3/ir3_compiler_nir.c       |   85 +++++++++++++++++++-
 1 file changed, 81 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index d044c1a..f6f44e0 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -99,6 +99,10 @@ struct ir3_compile {
 	 */
 	bool flat_bypass;
 
+	/* on a3xx, we need to add one to # of array levels:
+	 */
+	bool levels_add_one;
+
 	/* for looking up which system value is which */
 	unsigned sysval_semantics[8];
 
@@ -216,9 +220,11 @@ compile_init(struct ir3_shader_variant *so,
 	} else if (ir3_shader_gpuid(so->shader) >= 400) {
 		/* need special handling for "flat" */
 		ctx->flat_bypass = true;
+		ctx->levels_add_one = false;
 	} else {
 		/* no special handling for "flat" */
 		ctx->flat_bypass = false;
+		ctx->levels_add_one = true;
 	}
 
 	switch (so->type) {
@@ -1375,6 +1381,63 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
 	split_dest(b, dst, sam);
 }
 
+static void
+emit_tex_query_levels(struct ir3_compile *ctx, nir_tex_instr *tex)
+{
+	struct ir3_block *b = ctx->block;
+	struct ir3_instruction **dst, *sam;
+
+	dst = get_dst(ctx, &tex->dest, 1);
+
+	sam = ir3_SAM(b, OPC_GETINFO, TYPE_U32, TGSI_WRITEMASK_Z, 0,
+			tex->sampler_index, tex->sampler_index, NULL, NULL);
+
+	/* even though there is only one component, since it ends
+	 * up in .z rather than .x, we need a split_dest()
+	 */
+	split_dest(b, dst, sam);
+
+	/* The # of levels comes from getinfo.z. We need to add 1 to it, since
+	 * the value in TEX_CONST_0 is zero-based.
+	 */
+	if (ctx->levels_add_one)
+		dst[0] = ir3_ADD_U(b, dst[0], 0, create_immed(b, 1), 0);
+}
+
+static void
+emit_tex_txs(struct ir3_compile *ctx, nir_tex_instr *tex)
+{
+	struct ir3_block *b = ctx->block;
+	struct ir3_instruction **dst, *sam, *lod;
+	unsigned flags, coords;
+
+	tex_info(tex, &flags, &coords);
+
+	dst = get_dst(ctx, &tex->dest, 4);
+
+	compile_assert(ctx, tex->num_srcs == 1);
+	compile_assert(ctx, tex->src[0].src_type == nir_tex_src_lod);
+
+	lod = get_src(ctx, &tex->src[0].src)[0];
+
+	sam = ir3_SAM(b, OPC_GETSIZE, TYPE_U32, TGSI_WRITEMASK_XYZW, flags,
+			tex->sampler_index, tex->sampler_index, lod, NULL);
+
+	split_dest(b, dst, sam);
+
+	/* Array size actually ends up in .w rather than .z. This doesn't
+	 * matter for miplevel 0, but for higher mips the value in z is
+	 * minified whereas w stays. Also, the value in TEX_CONST_3_DEPTH is
+	 * returned, which means that we have to add 1 to it for arrays.
+	 */
+	if (tex->is_array) {
+		if (ctx->levels_add_one) {
+			dst[coords] = ir3_ADD_U(b, dst[3], 0, create_immed(b, 1), 0);
+		} else {
+			dst[coords] = ir3_MOV(b, dst[3], TYPE_U32);
+		}
+	}
+}
 
 static void
 emit_instr(struct ir3_compile *ctx, nir_instr *instr)
@@ -1392,10 +1455,23 @@ emit_instr(struct ir3_compile *ctx, nir_instr *instr)
 	case nir_instr_type_ssa_undef:
 		emit_undef(ctx, nir_instr_as_ssa_undef(instr));
 		break;
-	case nir_instr_type_tex:
-		emit_tex(ctx, nir_instr_as_tex(instr));
+	case nir_instr_type_tex: {
+		nir_tex_instr *tex = nir_instr_as_tex(instr);
+		/* couple tex instructions get special-cased:
+		 */
+		switch (tex->op) {
+		case nir_texop_txs:
+			emit_tex_txs(ctx, tex);
+			break;
+		case nir_texop_query_levels:
+			emit_tex_query_levels(ctx, tex);
+			break;
+		default:
+			emit_tex(ctx, tex);
+			break;
+		}
 		break;
-
+	}
 	case nir_instr_type_call:
 	case nir_instr_type_jump:
 	case nir_instr_type_phi:
@@ -1490,7 +1566,8 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
 				/* with NIR, we need to infer TGSI_INTERPOLATE_COLOR
 				 * from the semantic name:
 				 */
-				if (semantic_name == TGSI_SEMANTIC_COLOR)
+				if ((semantic_name == TGSI_SEMANTIC_COLOR) ||
+						(semantic_name == TGSI_SEMANTIC_BCOLOR))
 					so->inputs[n].interpolate = TGSI_INTERPOLATE_COLOR;
 
 				if (ctx->flat_bypass) {




More information about the mesa-commit mailing list