summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-10-14 14:27:47 -0400
committerRob Clark <[email protected]>2014-10-15 15:49:48 -0400
commitd595987ea3d1706fecb9f6416031ec8b27c95a9e (patch)
treeb82b1dc6c693884db8bdc3c43b2f9939b6a7a472
parentd5d80b37392c7f15c4fb39b6b1826230239930fd (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_draw.c64
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c41
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.h40
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_gmem.c30
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c21
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.h7
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.h5
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 e333a80879f..ccedb391fed 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 e0cbebaeaf7..050530e2267 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 89e73cf2cc1..a397c8705a3 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 172bd4c9d20..219c9e06a2d 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 46a9398a7b4..8de0008d343 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 0d50956cc14..0313b774a08 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 04a737ef19d..c531ad704cc 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