Mesa (master): freedreno/a3xx: refactor/optimize emit

Rob Clark robclark at kemper.freedesktop.org
Wed Oct 15 19:52:02 UTC 2014


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Tue Oct 14 14:27:47 2014 -0400

freedreno/a3xx: refactor/optimize emit

Because we reuse various bits of emit code (for state/vertex/prog/etc)
for both regular draws and internal draws (gmem<->mem, clear, etc), the
number of parameters getting passed around has been growing.  Refactor
to group these into fd3_emit.  This simplifies fxn signatures, avoids
passing around shader key on the stack, etc.  It also gives us a nice
place to cache shader-variant lookup to avoid looking up shader variants
multiple times per draw (without having to *also* pass them around as
fxn args everywhere).

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

---

 src/gallium/drivers/freedreno/a3xx/fd3_draw.c    |   64 +++++++++++++---------
 src/gallium/drivers/freedreno/a3xx/fd3_emit.c    |   41 +++++++-------
 src/gallium/drivers/freedreno/a3xx/fd3_emit.h    |   40 ++++++++++++--
 src/gallium/drivers/freedreno/a3xx/fd3_gmem.c    |   30 +++++++---
 src/gallium/drivers/freedreno/a3xx/fd3_program.c |   21 +++----
 src/gallium/drivers/freedreno/a3xx/fd3_program.h |    7 +--
 src/gallium/drivers/freedreno/ir3/ir3_shader.h   |    5 --
 7 files changed, 125 insertions(+), 83 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index e333a80..ccedb39 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -44,20 +44,15 @@
 
 
 static void
-emit_vertexbufs(struct fd_context *ctx, struct fd_ringbuffer *ring,
-		struct ir3_shader_key key)
+draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
+		struct fd3_emit *emit)
 {
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->prog.vp, key), &ctx->vtx);
-}
+	const struct pipe_draw_info *info = emit->info;
 
-static void
-draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
-		struct fd_ringbuffer *ring, unsigned dirty, struct ir3_shader_key key)
-{
-	fd3_emit_state(ctx, ring, info, &ctx->prog, key, dirty);
+	fd3_emit_state(ctx, ring, emit);
 
-	if (dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
-		emit_vertexbufs(ctx, ring, key);
+	if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
+		fd3_emit_vertex_bufs(ring, emit);
 
 	OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1);
 	OUT_RING(ring, 0x0000000b);             /* PC_VERTEX_REUSE_BLOCK_CNTL */
@@ -73,7 +68,7 @@ draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
 			info->restart_index : 0xffffffff);
 
 	fd_draw_emit(ctx, ring,
-			key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
+			emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
 			info);
 }
 
@@ -117,7 +112,11 @@ static void
 fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
 {
 	struct fd3_context *fd3_ctx = fd3_context(ctx);
-	struct ir3_shader_key key = {
+	struct fd3_emit emit = {
+		.vtx  = &ctx->vtx,
+		.prog = &ctx->prog,
+		.info = info,
+		.key = {
 			/* do binning pass first: */
 			.binning_pass = true,
 			.color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
@@ -131,18 +130,22 @@ fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
 			.fsaturate_s = fd3_ctx->fsaturate_s,
 			.fsaturate_t = fd3_ctx->fsaturate_t,
 			.fsaturate_r = fd3_ctx->fsaturate_r,
+		},
+		.rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade,
 	};
 	unsigned dirty;
 
-	fixup_shader_state(ctx, &key);
+	fixup_shader_state(ctx, &emit.key);
 
 	dirty = ctx->dirty;
+	emit.dirty = dirty & ~(FD_DIRTY_BLEND);
+	draw_impl(ctx, ctx->binning_ring, &emit);
 
-	draw_impl(ctx, info, ctx->binning_ring,
-			dirty & ~(FD_DIRTY_BLEND), key);
 	/* and now regular (non-binning) pass: */
-	key.binning_pass = false;
-	draw_impl(ctx, info, ctx->ring, dirty, key);
+	emit.key.binning_pass = false;
+	emit.dirty = dirty;
+	emit.vp = NULL;   /* we changed key so need to refetch vp */
+	draw_impl(ctx, ctx->ring, &emit);
 }
 
 /* binning pass cmds for a clear:
@@ -158,15 +161,18 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
 {
 	struct fd3_context *fd3_ctx = fd3_context(ctx);
 	struct fd_ringbuffer *ring = ctx->binning_ring;
-	struct ir3_shader_key key = {
+	struct fd3_emit emit = {
+		.vtx  = &fd3_ctx->solid_vbuf_state,
+		.prog = &ctx->solid_prog,
+		.key = {
 			.binning_pass = true,
 			.half_precision = true,
+		},
+		.dirty = dirty,
 	};
 
-	fd3_emit_state(ctx, ring, NULL, &ctx->solid_prog, key, dirty);
-
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
-			&fd3_ctx->solid_vbuf_state);
+	fd3_emit_state(ctx, ring, &emit);
+	fd3_emit_vertex_bufs(ring, &emit);
 
 	OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
 	OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
@@ -195,17 +201,22 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
 	struct fd_ringbuffer *ring = ctx->ring;
 	unsigned dirty = ctx->dirty;
 	unsigned ce, i;
-	struct ir3_shader_key key = {
+	struct fd3_emit emit = {
+		.vtx  = &fd3_ctx->solid_vbuf_state,
+		.prog = &ctx->solid_prog,
+		.key = {
 			.half_precision = true,
+		},
 	};
 
 	dirty &= FD_DIRTY_VIEWPORT | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
 	dirty |= FD_DIRTY_PROG;
+	emit.dirty = dirty;
 
 	fd3_clear_binning(ctx, dirty);
 
 	/* emit generic state now: */
-	fd3_emit_state(ctx, ring, NULL, &ctx->solid_prog, key, dirty);
+	fd3_emit_state(ctx, ring, &emit);
 
 	OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
 	OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
@@ -296,8 +307,7 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
 	OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
 	OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
 
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
-			&fd3_ctx->solid_vbuf_state);
+	fd3_emit_vertex_bufs(ring, &emit);
 
 	fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index e0cbeba..050530e 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -330,11 +330,12 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
 }
 
 void
-fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
-		struct ir3_shader_variant *vp, struct fd_vertex_state *vtx)
+fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
 {
 	uint32_t i, j, last = 0;
 	uint32_t total_in = 0;
+	const struct fd_vertex_state *vtx = emit->vtx;
+	struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
 	unsigned n = MIN2(vtx->vtx->num_elements, vp->inputs_count);
 
 	/* hw doesn't like to be configured for zero vbo's, it seems: */
@@ -348,7 +349,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
 	for (i = 0, j = 0; i <= last; i++) {
 		if (vp->inputs[i].compmask) {
 			struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
-			struct pipe_vertex_buffer *vb =
+			const struct pipe_vertex_buffer *vb =
 					&vtx->vertexbuf.vb[elem->vertex_buffer_index];
 			struct fd_resource *rsc = fd_resource(vb->buffer);
 			enum pipe_format pfmt = elem->src_format;
@@ -395,14 +396,11 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
 
 void
 fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
-		const struct pipe_draw_info *info,  struct fd_program_stateobj *prog,
-		struct ir3_shader_key key, uint32_t dirty)
+		struct fd3_emit *emit)
 {
-	struct ir3_shader_variant *vp;
-	struct ir3_shader_variant *fp;
-
-	fp = fd3_shader_variant(prog->fp, key);
-	vp = fd3_shader_variant(prog->vp, key);
+	struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
+	struct ir3_shader_variant *fp = fd3_emit_get_fp(emit);
+	uint32_t dirty = emit->dirty;
 
 	emit_marker(ring, 5);
 
@@ -413,7 +411,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 				A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(ctx->sample_mask));
 	}
 
-	if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !key.binning_pass) {
+	if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !emit->key.binning_pass) {
 		uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control;
 
 		val |= COND(fp->frag_face, A3XX_RB_RENDER_CONTROL_FACENESS);
@@ -490,18 +488,19 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 	 * PRIM_VTX_CNTL.. either that or be more clever and detect
 	 * when it changes.
 	 */
-	if (info) {
+	if (emit->info) {
+		const struct pipe_draw_info *info = emit->info;
 		uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
 				->pc_prim_vtx_cntl;
 
-		if (!key.binning_pass) {
+		if (!emit->key.binning_pass) {
 			uint32_t stride_in_vpc = align(fp->total_in, 4) / 4;
 			if (stride_in_vpc > 0)
 				stride_in_vpc = MAX2(stride_in_vpc, 2);
 			val |= A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(stride_in_vpc);
 		}
 
-		if (info && info->indexed && info->primitive_restart) {
+		if (info->indexed && info->primitive_restart) {
 			val |= A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART;
 		}
 
@@ -537,10 +536,8 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 		OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2]));
 	}
 
-	if (dirty & FD_DIRTY_PROG) {
-		bool flat = ctx->rasterizer && ctx->rasterizer->flatshade;
-		fd3_program_emit(ring, prog, key, flat);
-	}
+	if (dirty & FD_DIRTY_PROG)
+		fd3_program_emit(ring, emit);
 
 	/* TODO we should not need this or fd_wfi() before emit_constants():
 	 */
@@ -549,15 +546,15 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 
 	if ((dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) &&
 			/* evil hack to deal sanely with clear path: */
-			(prog == &ctx->prog)) {
+			(emit->prog == &ctx->prog)) {
 		fd_wfi(ctx, ring);
 		emit_constants(ring,  SB_VERT_SHADER,
 				&ctx->constbuf[PIPE_SHADER_VERTEX],
-				(prog->dirty & FD_SHADER_DIRTY_VP) ? vp : NULL);
-		if (!key.binning_pass) {
+				(emit->prog->dirty & FD_SHADER_DIRTY_VP) ? vp : NULL);
+		if (!emit->key.binning_pass) {
 			emit_constants(ring, SB_FRAG_SHADER,
 					&ctx->constbuf[PIPE_SHADER_FRAGMENT],
-					(prog->dirty & FD_SHADER_DIRTY_FP) ? fp : NULL);
+					(emit->prog->dirty & FD_SHADER_DIRTY_FP) ? fp : NULL);
 		}
 	}
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
index 89e73cf..a397c87 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
@@ -33,6 +33,7 @@
 
 #include "freedreno_context.h"
 #include "fd3_util.h"
+#include "fd3_program.h"
 #include "ir3_shader.h"
 
 struct fd_ringbuffer;
@@ -46,12 +47,43 @@ void fd3_emit_constant(struct fd_ringbuffer *ring,
 void fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring,
 		struct pipe_surface *psurf);
 
-void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
-		struct ir3_shader_variant *vp, struct fd_vertex_state *vtx);
+/* grouped together emit-state for prog/vertex/state emit: */
+struct fd3_emit {
+	const struct fd_vertex_state *vtx;
+	const struct fd_program_stateobj *prog;
+	const struct pipe_draw_info *info;
+	struct ir3_shader_key key;
+	uint32_t dirty;
+	bool rasterflat;
+
+	/* cached to avoid repeated lookups of same variants: */
+	struct ir3_shader_variant *vp, *fp;
+};
+
+static inline struct ir3_shader_variant *
+fd3_emit_get_vp(struct fd3_emit *emit)
+{
+	if (!emit->vp) {
+		struct fd3_shader_stateobj *so = emit->prog->vp;
+		emit->vp = ir3_shader_variant(so->shader, emit->key);
+	}
+	return emit->vp;
+}
+
+static inline struct ir3_shader_variant *
+fd3_emit_get_fp(struct fd3_emit *emit)
+{
+	if (!emit->fp) {
+		struct fd3_shader_stateobj *so = emit->prog->fp;
+		emit->fp = ir3_shader_variant(so->shader, emit->key);
+	}
+	return emit->fp;
+}
+
+void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit);
 
 void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
-		const struct pipe_draw_info *info,  struct fd_program_stateobj *prog,
-		struct ir3_shader_key key, uint32_t dirty);
+		struct fd3_emit *emit);
 
 void fd3_emit_restore(struct fd_context *ctx);
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
index 172bd4c..219c9e0 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
@@ -158,6 +158,11 @@ emit_binning_workaround(struct fd_context *ctx)
 	struct fd3_context *fd3_ctx = fd3_context(ctx);
 	struct fd_gmem_stateobj *gmem = &ctx->gmem;
 	struct fd_ringbuffer *ring = ctx->ring;
+	struct fd3_emit emit = {
+			.vtx = &fd3_ctx->solid_vbuf_state,
+			.prog = &ctx->solid_prog,
+			.key = key,
+	};
 
 	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 2);
 	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
@@ -183,9 +188,8 @@ emit_binning_workaround(struct fd_context *ctx)
 			A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
 			A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
 
-	fd3_program_emit(ring, &ctx->solid_prog, key, false);
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
-			&fd3_ctx->solid_vbuf_state);
+	fd3_program_emit(ring, &emit);
+	fd3_emit_vertex_bufs(ring, &emit);
 
 	OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 4);
 	OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
@@ -332,6 +336,11 @@ fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
 	struct fd3_context *fd3_ctx = fd3_context(ctx);
 	struct fd_ringbuffer *ring = ctx->ring;
 	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+	struct fd3_emit emit = {
+			.vtx = &fd3_ctx->solid_vbuf_state,
+			.prog = &ctx->solid_prog,
+			.key = key,
+	};
 
 	OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
 	OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
@@ -404,9 +413,8 @@ fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
 	OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
 	OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
 
-	fd3_program_emit(ring, &ctx->solid_prog, key, false);
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
-			&fd3_ctx->solid_vbuf_state);
+	fd3_program_emit(ring, &emit);
+	fd3_emit_vertex_bufs(ring, &emit);
 
 	if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
 		uint32_t base = depth_base(ctx);
@@ -450,6 +458,11 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
 	struct fd_gmem_stateobj *gmem = &ctx->gmem;
 	struct fd_ringbuffer *ring = ctx->ring;
 	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+	struct fd3_emit emit = {
+			.vtx = &fd3_ctx->blit_vbuf_state,
+			.prog = &ctx->blit_prog,
+			.key = key,
+	};
 	float x0, y0, x1, y1;
 	unsigned bin_w = tile->bin_w;
 	unsigned bin_h = tile->bin_h;
@@ -544,9 +557,8 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
 	OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
 	OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
 
-	fd3_program_emit(ring, &ctx->blit_prog, key, false);
-	fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->blit_prog.vp, key),
-			&fd3_ctx->blit_vbuf_state);
+	fd3_program_emit(ring, &emit);
+	fd3_emit_vertex_bufs(ring, &emit);
 
 	/* for gmem pitch/base calculations, we need to use the non-
 	 * truncated tile sizes:
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 46a9398..8de0008 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -179,10 +179,7 @@ find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
 }
 
 void
-fd3_program_emit(struct fd_ringbuffer *ring,
-		struct fd_program_stateobj *prog,
-		struct ir3_shader_key key,
-		boolean rasterflat)
+fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit)
 {
 	const struct ir3_shader_variant *vp, *fp;
 	const struct ir3_info *vsi, *fsi;
@@ -191,14 +188,14 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 	uint32_t pos_regid, posz_regid, psize_regid, color_regid;
 	int i, j, k;
 
-	vp = fd3_shader_variant(prog->vp, key);
+	vp = fd3_emit_get_vp(emit);
 
-	if (key.binning_pass) {
+	if (emit->key.binning_pass) {
 		/* use dummy stateobj to simplify binning vs non-binning: */
 		static const struct ir3_shader_variant binning_fp = {};
 		fp = &binning_fp;
 	} else {
-		fp = fd3_shader_variant(prog->fp, key);
+		fp = fd3_emit_get_fp(emit);
 	}
 
 	vsi = &vp->info;
@@ -279,7 +276,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 
 	OUT_PKT0(ring, REG_A3XX_SP_SP_CTRL_REG, 1);
 	OUT_RING(ring, A3XX_SP_SP_CTRL_REG_CONSTMODE(0) |
-			COND(key.binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) |
+			COND(emit->key.binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) |
 			A3XX_SP_SP_CTRL_REG_SLEEPMODE(1) |
 			A3XX_SP_SP_CTRL_REG_L0MODE(0));
 
@@ -352,7 +349,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 			A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
 	OUT_RELOC(ring, vp->bo, 0, 0, 0);  /* SP_VS_OBJ_START_REG */
 
-	if (key.binning_pass) {
+	if (emit->key.binning_pass) {
 		OUT_PKT0(ring, REG_A3XX_SP_FS_LENGTH_REG, 1);
 		OUT_RING(ring, 0x00000000);
 
@@ -408,7 +405,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 	OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(0));
 	OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(0));
 
-	if (key.binning_pass) {
+	if (emit->key.binning_pass) {
 		OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2);
 		OUT_RING(ring, A3XX_VPC_ATTR_THRDASSIGN(1) |
 				A3XX_VPC_ATTR_LMSIZE(1) |
@@ -421,7 +418,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 		for (j = -1; (j = next_varying(fp, j)) < (int)fp->inputs_count; ) {
 			uint32_t interp = fp->inputs[j].interpolate;
 			if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
-					((interp == TGSI_INTERPOLATE_COLOR) && rasterflat)) {
+					((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) {
 				/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
 				 * instead.. rather than -8 everywhere else..
 				 */
@@ -474,7 +471,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 	OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
 	OUT_RING(ring, 0x00000000);        /* VFD_PERFCOUNTER0_SELECT */
 
-	if (!key.binning_pass) {
+	if (!emit->key.binning_pass) {
 		if (fpbuffer == BUFFER)
 			emit_shader(ring, fp);
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.h b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
index 0d50956..0313b77 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
@@ -37,10 +37,9 @@ struct fd3_shader_stateobj {
 	struct ir3_shader *shader;
 };
 
-void fd3_program_emit(struct fd_ringbuffer *ring,
-		struct fd_program_stateobj *prog,
-		struct ir3_shader_key key,
-		boolean rasterflat);
+struct fd3_emit;
+
+void fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit);
 
 void fd3_prog_init(struct pipe_context *pctx);
 
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
index 04a737e..c531ad7 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
@@ -52,11 +52,6 @@ static inline uint16_t sem2idx(ir3_semantic sem)
 /* Configuration key used to identify a shader variant.. different
  * shader variants can be used to implement features not supported
  * in hw (two sided color), binning-pass vertex shader, etc.
- *
- * TODO since shader key is starting to get larger (than 32bit)
- * we probably should pass it around by ptr rather than value more
- * of the places.. but watch out in ir3_shader_variant() where the
- * key gets normalized, we need to make a copy there.
  */
 struct ir3_shader_key {
 	/* bitmask of sampler which needs coords clamped for vertex




More information about the mesa-commit mailing list