Mesa (master): freedreno/ir3: switch fragcoord to sysval

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 30 00:03:16 UTC 2019


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Fri Apr 26 14:40:17 2019 -0700

freedreno/ir3: switch fragcoord to sysval

Because who are we kidding... it is a sysval.

Signed-off-by: Rob Clark <robdclark at chromium.org>

---

 src/freedreno/ir3/ir3_compiler_nir.c             | 92 ++++++++++++------------
 src/gallium/drivers/freedreno/freedreno_screen.c |  1 +
 2 files changed, 45 insertions(+), 48 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index 34fb7b0969d..4e139dc136e 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1176,6 +1176,46 @@ get_barycentric_pixel(struct ir3_context *ctx)
 	return ctx->ij_pixel;
 }
 
+static struct ir3_instruction *
+get_frag_coord(struct ir3_context *ctx)
+{
+	if (!ctx->frag_coord) {
+		struct ir3_block *b = ctx->block;
+		struct ir3_instruction *xyzw[4];
+		struct ir3_instruction *hw_frag_coord;
+
+		hw_frag_coord = create_input_compmask(ctx, 0, 0xf);
+		ir3_split_dest(ctx->block, xyzw, hw_frag_coord, 0, 4);
+
+		/* for frag_coord.xy, we get unsigned values.. we need
+		 * to subtract (integer) 8 and divide by 16 (right-
+		 * shift by 4) then convert to float:
+		 *
+		 *    sub.s tmp, src, 8
+		 *    shr.b tmp, tmp, 4
+		 *    mov.u32f32 dst, tmp
+		 *
+		 */
+		for (int i = 0; i < 2; i++) {
+			xyzw[i] = ir3_SUB_S(b, xyzw[i], 0,
+					create_immed(b, 8), 0);
+			xyzw[i] = ir3_SHR_B(b, xyzw[i], 0,
+					create_immed(b, 4), 0);
+			xyzw[i] = ir3_COV(b, xyzw[i], TYPE_U32, TYPE_F32);
+		}
+
+		ctx->frag_coord = ir3_create_collect(ctx, xyzw, 4);
+
+		add_sysval_input_compmask(ctx,
+				SYSTEM_VALUE_FRAG_COORD,
+				0xf, hw_frag_coord);
+
+		ctx->so->frag_coord = true;
+	}
+
+	return ctx->frag_coord;
+}
+
 static void
 emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
 {
@@ -1217,6 +1257,9 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
 	case nir_intrinsic_load_ubo:
 		emit_intrinsic_load_ubo(ctx, intr, dst);
 		break;
+	case nir_intrinsic_load_frag_coord:
+		ir3_split_dest(b, dst, get_frag_coord(ctx), 0, 4);
+		break;
 	case nir_intrinsic_load_sample_pos_from_id: {
 		/* NOTE: blob seems to always use TYPE_F16 and then cov.f16f32,
 		 * but that doesn't seem necessary.
@@ -2298,46 +2341,6 @@ emit_function(struct ir3_context *ctx, nir_function_impl *impl)
 	ir3_END(ctx->block);
 }
 
-static struct ir3_instruction *
-create_frag_coord(struct ir3_context *ctx, unsigned comp)
-{
-	struct ir3_block *block = ctx->block;
-	struct ir3_instruction *instr;
-
-	if (!ctx->frag_coord) {
-		ctx->frag_coord = create_input_compmask(ctx, 0, 0xf);
-		/* defer add_sysval_input() until after all inputs created */
-	}
-
-	ir3_split_dest(block, &instr, ctx->frag_coord, comp, 1);
-
-	switch (comp) {
-	case 0: /* .x */
-	case 1: /* .y */
-		/* for frag_coord, we get unsigned values.. we need
-		 * to subtract (integer) 8 and divide by 16 (right-
-		 * shift by 4) then convert to float:
-		 *
-		 *    sub.s tmp, src, 8
-		 *    shr.b tmp, tmp, 4
-		 *    mov.u32f32 dst, tmp
-		 *
-		 */
-		instr = ir3_SUB_S(block, instr, 0,
-				create_immed(block, 8), 0);
-		instr = ir3_SHR_B(block, instr, 0,
-				create_immed(block, 4), 0);
-		instr = ir3_COV(block, instr, TYPE_U32, TYPE_F32);
-
-		return instr;
-	case 2: /* .z */
-	case 3: /* .w */
-	default:
-		/* seems that we can use these as-is: */
-		return instr;
-	}
-}
-
 static void
 setup_input(struct ir3_context *ctx, nir_variable *in)
 {
@@ -2371,9 +2374,7 @@ setup_input(struct ir3_context *ctx, nir_variable *in)
 			unsigned idx = (n * 4) + i + frac;
 
 			if (slot == VARYING_SLOT_POS) {
-				so->inputs[n].bary = false;
-				so->frag_coord = true;
-				instr = create_frag_coord(ctx, i);
+				ir3_context_error(ctx, "fragcoord should be a sysval!\n");
 			} else if (slot == VARYING_SLOT_PNTC) {
 				/* see for example st_nir_fixup_varying_slots().. this is
 				 * maybe a bit mesa/st specific.  But we need things to line
@@ -2678,11 +2679,6 @@ emit_instructions(struct ir3_context *ctx)
 				0x3, vcoord);
 	}
 
-	if (ctx->frag_coord) {
-		add_sysval_input_compmask(ctx, SYSTEM_VALUE_FRAG_COORD,
-				0xf, ctx->frag_coord);
-	}
-
 	/* Setup outputs: */
 	nir_foreach_variable(var, &ctx->s->outputs) {
 		setup_output(ctx, var);
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index d1edf82592c..a437afb0d4e 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -355,6 +355,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 		return 0;
 	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
 	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+	case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
 		if (is_ir3(screen))
 			return 1;
 		return 0;




More information about the mesa-commit mailing list