From 2e9c08c0bce8df63979327f3b1c3c828fd1b98da Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 2 Oct 2018 12:38:09 -0400 Subject: [PATCH] freedreno/ir3: move binning_pass out of shader variant key Prep work for a following patch, that introduces a cache to map from program state (all shader stages) plus variant key to pre-baked hw state (which could be emit'd via CP_SET_DRAW_STATE, for example). To do that, we really want the variant key to be immutable, and to treat the binning pass shader as an extra shader stage, rather than as a VS variant. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 6 ++-- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 6 ++-- src/gallium/drivers/freedreno/a3xx/fd3_emit.h | 9 ++++-- src/gallium/drivers/freedreno/a3xx/fd3_program.c | 8 +++--- src/gallium/drivers/freedreno/a4xx/fd4_draw.c | 6 ++-- src/gallium/drivers/freedreno/a4xx/fd4_emit.c | 4 +-- src/gallium/drivers/freedreno/a4xx/fd4_emit.h | 9 ++++-- src/gallium/drivers/freedreno/a4xx/fd4_program.c | 10 +++---- src/gallium/drivers/freedreno/a5xx/fd5_compute.c | 2 +- src/gallium/drivers/freedreno/a5xx/fd5_draw.c | 8 +++--- src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 8 +++--- src/gallium/drivers/freedreno/a5xx/fd5_emit.h | 9 ++++-- src/gallium/drivers/freedreno/a5xx/fd5_program.c | 10 +++---- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 8 +++--- src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 8 +++--- src/gallium/drivers/freedreno/a6xx/fd6_emit.h | 9 ++++-- src/gallium/drivers/freedreno/a6xx/fd6_program.c | 10 +++---- src/gallium/drivers/freedreno/ir3/ir3_cmdline.c | 2 +- .../drivers/freedreno/ir3/ir3_compiler_nir.c | 9 +++--- src/gallium/drivers/freedreno/ir3/ir3_shader.c | 33 ++++++++++++++++------ src/gallium/drivers/freedreno/ir3/ir3_shader.h | 10 +++++-- 21 files changed, 109 insertions(+), 75 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index 9f148e6..e6572d6 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -83,7 +83,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, primtype = DI_PT_POINTLIST_PSIZE; fd_draw_emit(ctx->batch, ring, primtype, - emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, + emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, info, index_offset); } @@ -158,12 +158,12 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, ctx->stats.vs_regs += ir3_shader_halfregs(vp); ctx->stats.fs_regs += ir3_shader_halfregs(fp); - emit.key.binning_pass = false; + emit.binning_pass = false; emit.dirty = dirty; draw_impl(ctx, ctx->batch->draw, &emit, index_offset); /* and now binning pass: */ - emit.key.binning_pass = true; + emit.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index b5e20e5..77b0339 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -509,7 +509,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, } if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG | FD_DIRTY_BLEND_DUAL)) && - !emit->key.binning_pass) { + !emit->binning_pass) { uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control | fd3_blend_stateobj(ctx->blend)->rb_render_control; @@ -622,7 +622,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer) ->pc_prim_vtx_cntl; - if (!emit->key.binning_pass) { + if (!emit->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); @@ -721,7 +721,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */ ir3_emit_vs_consts(vp, ring, ctx, emit->info); - if (!emit->key.binning_pass) + if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h index c827522..6a6db47 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h @@ -45,6 +45,7 @@ struct fd3_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; @@ -61,7 +62,8 @@ fd3_emit_get_vp(struct fd3_emit *emit) { if (!emit->vp) { struct ir3_shader *shader = emit->prog->vp; - emit->vp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->vp = ir3_shader_variant(shader, emit->key, + emit->binning_pass, emit->debug); } return emit->vp; } @@ -70,13 +72,14 @@ static inline const struct ir3_shader_variant * fd3_emit_get_fp(struct fd3_emit *emit) { if (!emit->fp) { - if (emit->key.binning_pass) { + if (emit->binning_pass) { /* use dummy stateobj to simplify binning vs non-binning: */ static const struct ir3_shader_variant binning_fp = {}; emit->fp = &binning_fp; } else { struct ir3_shader *shader = emit->prog->fp; - emit->fp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->fp = ir3_shader_variant(shader, emit->key, + false, emit->debug); } } return emit->fp; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c index 9d5c7b6..1a7d306 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c @@ -249,7 +249,7 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, OUT_PKT0(ring, REG_A3XX_SP_SP_CTRL_REG, 1); OUT_RING(ring, A3XX_SP_SP_CTRL_REG_CONSTMODE(constmode) | - COND(emit->key.binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) | + COND(emit->binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) | A3XX_SP_SP_CTRL_REG_SLEEPMODE(1) | A3XX_SP_SP_CTRL_REG_L0MODE(0)); @@ -309,7 +309,7 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0)); OUT_RELOC(ring, vp->bo, 0, 0, 0); /* SP_VS_OBJ_START_REG */ - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT0(ring, REG_A3XX_SP_FS_LENGTH_REG, 1); OUT_RING(ring, 0x00000000); @@ -367,7 +367,7 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, OUT_RING(ring, mrt_reg); } - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2); OUT_RING(ring, A3XX_VPC_ATTR_THRDASSIGN(1) | A3XX_VPC_ATTR_LMSIZE(1) | @@ -472,7 +472,7 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1); OUT_RING(ring, 0x00000000); /* VFD_PERFCOUNTER0_SELECT */ - if (!emit->key.binning_pass) { + if (!emit->binning_pass) { if (fpbuffer == BUFFER) emit_shader(ring, fp); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c index 029c608..d854ebc 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c @@ -67,7 +67,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, primtype = DI_PT_POINTLIST_PSIZE; fd4_draw_emit(ctx->batch, ring, primtype, - emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, + emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, info, index_offset); } @@ -144,7 +144,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, ctx->stats.vs_regs += ir3_shader_halfregs(vp); ctx->stats.fs_regs += ir3_shader_halfregs(fp); - emit.key.binning_pass = false; + emit.binning_pass = false; emit.dirty = dirty; struct fd_ringbuffer *ring = ctx->batch->draw; @@ -168,7 +168,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, } /* and now binning pass: */ - emit.key.binning_pass = true; + emit.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 34f8ef1..49ce635 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -510,7 +510,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, emit_marker(ring, 5); - if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->key.binning_pass) { + if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->binning_pass) { struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer; unsigned char mrt_comp[A4XX_MAX_RENDER_TARGETS] = {0}; @@ -686,7 +686,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */ ir3_emit_vs_consts(vp, ring, ctx, emit->info); - if (!emit->key.binning_pass) + if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h index 376523d..4d27f70 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h @@ -45,6 +45,7 @@ struct fd4_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; @@ -70,7 +71,8 @@ fd4_emit_get_vp(struct fd4_emit *emit) { if (!emit->vp) { struct ir3_shader *shader = emit->prog->vp; - emit->vp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->vp = ir3_shader_variant(shader, emit->key, + emit->binning_pass, emit->debug); } return emit->vp; } @@ -79,13 +81,14 @@ static inline const struct ir3_shader_variant * fd4_emit_get_fp(struct fd4_emit *emit) { if (!emit->fp) { - if (emit->key.binning_pass) { + if (emit->binning_pass) { /* use dummy stateobj to simplify binning vs non-binning: */ static const struct ir3_shader_variant binning_fp = {}; emit->fp = &binning_fp; } else { struct ir3_shader *shader = emit->prog->fp; - emit->fp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->fp = ir3_shader_variant(shader, emit->key, + false, emit->debug); } } return emit->fp; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_program.c b/src/gallium/drivers/freedreno/a4xx/fd4_program.c index 860f615..dac96de 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_program.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_program.c @@ -207,7 +207,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit, debug_assert(nr <= ARRAY_SIZE(color_regid)); - if (emit->key.binning_pass) + if (emit->binning_pass) nr = 0; setup_stages(emit, s); @@ -299,7 +299,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit, OUT_PKT0(ring, REG_A4XX_SP_SP_CTRL_REG, 1); OUT_RING(ring, 0x140010 | /* XXX */ - COND(emit->key.binning_pass, A4XX_SP_SP_CTRL_REG_BINNING_PASS)); + COND(emit->binning_pass, A4XX_SP_SP_CTRL_REG_BINNING_PASS)); OUT_PKT0(ring, REG_A4XX_SP_INSTR_CACHE_CTRL, 1); OUT_RING(ring, 0x7f | /* XXX */ @@ -362,7 +362,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit, A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[VS].instroff)); OUT_RELOC(ring, s[VS].v->bo, 0, 0, 0); /* SP_VS_OBJ_START_REG */ - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT0(ring, REG_A4XX_SP_FS_LENGTH_REG, 1); OUT_RING(ring, 0x00000000); /* SP_FS_LENGTH_REG */ @@ -452,7 +452,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit, A4XX_SP_FS_MRT_REG_HALF_PRECISION)); } - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT0(ring, REG_A4XX_VPC_ATTR, 2); OUT_RING(ring, A4XX_VPC_ATTR_THRDASSIGN(1) | 0x40000000 | /* XXX */ @@ -561,7 +561,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit, if (s[VS].instrlen) emit_shader(ring, s[VS].v); - if (!emit->key.binning_pass) + if (!emit->binning_pass) if (s[FS].instrlen) emit_shader(ring, s[FS].v); } diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_compute.c b/src/gallium/drivers/freedreno/a5xx/fd5_compute.c index 66ed7a4..1e084fd 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_compute.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_compute.c @@ -188,7 +188,7 @@ fd5_launch_grid(struct fd_context *ctx, const struct pipe_grid_info *info) emit_setup(ctx); - v = ir3_shader_variant(so->shader, key, &ctx->debug); + v = ir3_shader_variant(so->shader, key, false, &ctx->debug); if (!v) return; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index 96ff1a3..bbb1289 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -60,9 +60,9 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */ info->restart_index : 0xffffffff); - fd5_emit_render_cntl(ctx, false, emit->key.binning_pass); + fd5_emit_render_cntl(ctx, false, emit->binning_pass); fd5_draw_emit(ctx->batch, ring, primtype, - emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, + emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, info, index_offset); } @@ -144,13 +144,13 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, */ emit.no_lrz_write = fp->writes_pos || fp->has_kill; - emit.key.binning_pass = false; + emit.binning_pass = false; emit.dirty = dirty; draw_impl(ctx, ctx->batch->draw, &emit, index_offset); /* and now binning pass: */ - emit.key.binning_pass = true; + emit.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index e3bf9e2..c666b25 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -524,7 +524,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, emit_marker5(ring, 5); - if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->key.binning_pass) { + if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->binning_pass) { unsigned char mrt_comp[A5XX_MAX_RENDER_TARGETS] = {0}; for (unsigned i = 0; i < A5XX_MAX_RENDER_TARGETS; i++) { @@ -566,7 +566,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) gras_lrz_cntl = 0; - else if (emit->key.binning_pass && blend->lrz_write && zsa->lrz_write) + else if (emit->binning_pass && blend->lrz_write && zsa->lrz_write) gras_lrz_cntl |= A5XX_GRAS_LRZ_CNTL_LRZ_WRITE; OUT_PKT4(ring, REG_A5XX_GRAS_LRZ_CNTL, 1); @@ -685,7 +685,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, uint32_t posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH); unsigned nr = pfb->nr_cbufs; - if (emit->key.binning_pass) + if (emit->binning_pass) nr = 0; else if (ctx->rasterizer->rasterizer_discard) nr = 0; @@ -701,7 +701,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, } ir3_emit_vs_consts(vp, ring, ctx, emit->info); - if (!emit->key.binning_pass) + if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); struct pipe_stream_output_info *info = &vp->shader->stream_output; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h index bed52d4..69ea3fa 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h @@ -44,6 +44,7 @@ struct fd5_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; @@ -77,7 +78,8 @@ fd5_emit_get_vp(struct fd5_emit *emit) { if (!emit->vp) { struct ir3_shader *shader = emit->prog->vp; - emit->vp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->vp = ir3_shader_variant(shader, emit->key, + emit->binning_pass, emit->debug); } return emit->vp; } @@ -86,13 +88,14 @@ static inline const struct ir3_shader_variant * fd5_emit_get_fp(struct fd5_emit *emit) { if (!emit->fp) { - if (emit->key.binning_pass) { + if (emit->binning_pass) { /* use dummy stateobj to simplify binning vs non-binning: */ static const struct ir3_shader_variant binning_fp = {}; emit->fp = &binning_fp; } else { struct ir3_shader *shader = emit->prog->fp; - emit->fp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->fp = ir3_shader_variant(shader, emit->key, + false, emit->debug); } } return emit->fp; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.c b/src/gallium/drivers/freedreno/a5xx/fd5_program.c index 2a6e333..a30678d 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.c @@ -448,7 +448,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, ir3_link_shaders(&l, s[VS].v, s[FS].v); if ((s[VS].v->shader->stream_output.num_outputs > 0) && - !emit->key.binning_pass) + !emit->binning_pass) link_stream_out(&l, s[VS].v); BITSET_DECLARE(varbs, 128) = {0}; @@ -474,7 +474,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, } if ((s[VS].v->shader->stream_output.num_outputs > 0) && - !emit->key.binning_pass) { + !emit->binning_pass) { emit_stream_out(ring, s[VS].v, &l); OUT_PKT4(ring, REG_A5XX_VPC_SO_OVERRIDE, 1); @@ -534,7 +534,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, fd5_context(ctx)->max_loc = l.max_loc; - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT4(ring, REG_A5XX_SP_FS_OBJ_START_LO, 2); OUT_RING(ring, 0x00000000); /* SP_FS_OBJ_START_LO */ OUT_RING(ring, 0x00000000); /* SP_FS_OBJ_START_HI */ @@ -613,7 +613,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, A5XX_VPC_PACK_NUMNONPOSVAR(s[FS].v->total_in) | A5XX_VPC_PACK_PSIZELOC(psize_loc)); - if (!emit->key.binning_pass) { + if (!emit->binning_pass) { uint32_t vinterp[8], vpsrepl[8]; memset(vinterp, 0, sizeof(vinterp)); @@ -704,7 +704,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, vpsrepl[i]); /* VPC_VARYING_PS_REPL[i] */ } - if (!emit->key.binning_pass) + if (!emit->binning_pass) if (s[FS].instrlen) fd5_emit_shader(ring, s[FS].v); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index d9e3635..be13f5f 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -156,11 +156,11 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, if (info->indirect) { draw_emit_indirect(ctx->batch, ring, primtype, - emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, + emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, info, index_offset); } else { draw_emit(ctx->batch, ring, primtype, - emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, + emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, info, index_offset); } @@ -248,13 +248,13 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, */ emit.no_lrz_write = fp->writes_pos || fp->has_kill; - emit.key.binning_pass = false; + emit.binning_pass = false; emit.dirty = dirty; draw_impl(ctx, ctx->batch->draw, &emit, index_offset); /* and now binning pass: */ - emit.key.binning_pass = true; + emit.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index eb24fb9..706386a 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -595,7 +595,7 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, emit_marker6(ring, 5); - if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->key.binning_pass) { + if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->binning_pass) { unsigned char mrt_comp[A6XX_MAX_RENDER_TARGETS] = {0}; for (unsigned i = 0; i < pfb->nr_cbufs; i++) { @@ -649,7 +649,7 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) { gras_lrz_cntl = 0; rb_lrz_cntl = 0; - } else if (emit->key.binning_pass && zsa->lrz_write) { + } else if (emit->binning_pass && zsa->lrz_write) { gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_LRZ_WRITE; } @@ -783,7 +783,7 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, uint32_t posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH); unsigned nr = pfb->nr_cbufs; - if (emit->key.binning_pass) + if (emit->binning_pass) nr = 0; else if (ctx->rasterizer->rasterizer_discard) nr = 0; @@ -812,7 +812,7 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, } if ((ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & DIRTY_CONST) && - !emit->key.binning_pass) { + !emit->binning_pass) { struct fd_ringbuffer *fsconstobj = fd_ringbuffer_new_flags(ctx->pipe, 0x1000, FD_RINGBUFFER_OBJECT | FD_RINGBUFFER_STREAMING); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h index 0059527..c05b0a4 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h @@ -61,6 +61,7 @@ struct fd6_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; @@ -90,7 +91,8 @@ fd6_emit_get_vp(struct fd6_emit *emit) { if (!emit->vp) { struct ir3_shader *shader = emit->prog->vp; - emit->vp = ir3_shader_variant(shader, emit->key, emit->debug); + emit->vp = ir3_shader_variant(shader, emit->key, + emit->binning_pass, emit->debug); } return emit->vp; } @@ -99,13 +101,14 @@ static inline const struct ir3_shader_variant * fd6_emit_get_fp(struct fd6_emit *emit) { if (!emit->fp) { - if (emit->key.binning_pass) { + if (emit->binning_pass) { /* use dummy stateobj to simplify binning vs non-binning: */ static const struct ir3_shader_variant binning_fp = {}; emit->fp = &binning_fp; } else { struct ir3_shader *shader = emit->prog->fp; - emit->fp = ir3_shader_variant(shader, emit->key,emit->debug); + emit->fp = ir3_shader_variant(shader, emit->key, + false, emit->debug); } } return emit->fp; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index c6d062a..33f5962 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -393,7 +393,7 @@ fd6_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, ir3_link_shaders(&l, s[VS].v, s[FS].v); if ((s[VS].v->shader->stream_output.num_outputs > 0) && - !emit->key.binning_pass) + !emit->binning_pass) link_stream_out(&l, s[VS].v); BITSET_DECLARE(varbs, 128) = {0}; @@ -419,7 +419,7 @@ fd6_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, } if ((s[VS].v->shader->stream_output.num_outputs > 0) && - !emit->key.binning_pass) { + !emit->binning_pass) { setup_stream_out(ctx, s[VS].v, &l); } @@ -478,7 +478,7 @@ fd6_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, A6XX_PC_PRIMITIVE_CNTL_1_STRIDE_IN_VPC(l.max_loc) | COND(psize_regid != regid(63,0), 0x100)); - if (emit->key.binning_pass) { + if (emit->binning_pass) { OUT_PKT4(ring, REG_A6XX_SP_FS_OBJ_START_LO, 2); OUT_RING(ring, 0x00000000); /* SP_FS_OBJ_START_LO */ OUT_RING(ring, 0x00000000); /* SP_FS_OBJ_START_HI */ @@ -559,7 +559,7 @@ fd6_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, A6XX_VPC_PACK_PSIZELOC(psize_loc) | A6XX_VPC_PACK_STRIDE_IN_VPC(l.max_loc)); - if (!emit->key.binning_pass) { + if (!emit->binning_pass) { uint32_t vinterp[8], vpsrepl[8]; memset(vinterp, 0, sizeof(vinterp)); @@ -650,7 +650,7 @@ fd6_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, vpsrepl[i]); /* VPC_VARYING_PS_REPL[i] */ } - if (!emit->key.binning_pass) + if (!emit->binning_pass) if (s[FS].instrlen) fd6_emit_shader(ring, s[FS].v); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index b41c32d..bf80195 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -289,7 +289,7 @@ int main(int argc, char **argv) if (!strcmp(argv[n], "--binning-pass")) { debug_printf(" %s", argv[n]); - key.binning_pass = true; + v.binning_pass = true; n++; continue; } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index 9f6a06c..9474f75 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -182,10 +182,9 @@ compile_init(struct ir3_compiler *compiler, NIR_PASS_V(ctx->s, nir_convert_from_ssa, true); if (fd_mesa_debug & FD_DBG_DISASM) { - DBG("dump nir%dv%d: type=%d, k={bp=%u,cts=%u,hp=%u}", + DBG("dump nir%dv%d: type=%d, k={cts=%u,hp=%u}", so->shader->id, so->id, so->type, - so->key.binning_pass, so->key.color_two_side, - so->key.half_precision); + so->key.color_two_side, so->key.half_precision); nir_print_shader(ctx->s, stdout); } @@ -3197,7 +3196,7 @@ emit_function(struct ir3_context *ctx, nir_function_impl *impl) */ if ((ctx->compiler->gpu_id < 500) && (ctx->so->shader->stream_output.num_outputs > 0) && - !ctx->so->key.binning_pass) { + !ctx->so->binning_pass) { debug_assert(ctx->so->type == SHADER_VERTEX); emit_stream_out(ctx); } @@ -3600,7 +3599,7 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler, fixup_frag_inputs(ctx); /* at this point, for binning pass, throw away unneeded outputs: */ - if (so->key.binning_pass) { + if (so->binning_pass) { for (i = 0, j = 0; i < so->outputs_count; i++) { unsigned slot = so->outputs[i].slot; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index ee063f8..9bf0a7f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -146,7 +146,7 @@ assemble_variant(struct ir3_shader_variant *v) if (fd_mesa_debug & FD_DBG_DISASM) { struct ir3_shader_key key = v->key; printf("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type, - key.binning_pass, key.color_two_side, key.half_precision); + v->binning_pass, key.color_two_side, key.half_precision); ir3_shader_disasm(v, bin, stdout); } @@ -194,7 +194,8 @@ dump_shader_info(struct ir3_shader_variant *v, struct pipe_debug_callback *debug } static struct ir3_shader_variant * -create_variant(struct ir3_shader *shader, struct ir3_shader_key key) +create_variant(struct ir3_shader *shader, struct ir3_shader_key key, + bool binning_pass) { struct ir3_shader_variant *v = CALLOC_STRUCT(ir3_shader_variant); int ret; @@ -204,6 +205,7 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key) v->id = ++shader->variant_count; v->shader = shader; + v->binning_pass = binning_pass; v->key = key; v->type = shader->type; @@ -226,8 +228,8 @@ fail: return NULL; } -struct ir3_shader_variant * -ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, +static inline struct ir3_shader_variant * +shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, struct pipe_debug_callback *debug) { struct ir3_shader_variant *v; @@ -238,7 +240,6 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, */ switch (shader->type) { case SHADER_FRAGMENT: - key.binning_pass = false; if (key.has_per_samp) { key.vsaturate_s = 0; key.vsaturate_t = 0; @@ -269,7 +270,7 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, return v; /* compile new variant if it doesn't exist already: */ - v = create_variant(shader, key); + v = create_variant(shader, key, false); if (v) { v->next = shader->variants; shader->variants = v; @@ -280,6 +281,22 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, } +struct ir3_shader_variant * +ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, + bool binning_pass, struct pipe_debug_callback *debug) +{ + struct ir3_shader_variant *v = + shader_variant(shader, key, debug); + + if (binning_pass) { + if (!v->binning) + v->binning = create_variant(shader, key, true); + return v->binning; + } + + return v; +} + void ir3_shader_destroy(struct ir3_shader *shader) { @@ -332,7 +349,7 @@ ir3_shader_create(struct ir3_compiler *compiler, */ static struct ir3_shader_key key; memset(&key, 0, sizeof(key)); - ir3_shader_variant(shader, key, debug); + ir3_shader_variant(shader, key, false, debug); } return shader; } @@ -755,7 +772,7 @@ max_tf_vtx(struct fd_context *ctx, const struct ir3_shader_variant *v) if (ctx->screen->gpu_id >= 500) return 0; - if (v->key.binning_pass) + if (v->binning_pass) return 0; if (v->shader->stream_output.num_outputs == 0) return 0; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h index 6bc24f4..1c31061 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h @@ -114,7 +114,6 @@ struct ir3_shader_key { /* * Vertex shader variant parameters: */ - unsigned binning_pass : 1; unsigned vclamp_color : 1; /* @@ -218,6 +217,12 @@ struct ir3_shader_variant { struct ir3_shader_key key; + /* vertex shaders can have an extra version for hwbinning pass, + * which is pointed to by so->binning: + */ + bool binning_pass; + struct ir3_shader_variant *binning; + struct ir3_driver_const_layout const_layout; struct ir3_info info; struct ir3 *ir; @@ -373,7 +378,8 @@ ir3_shader_create_compute(struct ir3_compiler *compiler, struct pipe_debug_callback *debug); void ir3_shader_destroy(struct ir3_shader *shader); struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader, - struct ir3_shader_key key, struct pipe_debug_callback *debug); + struct ir3_shader_key key, bool binning_pass, + struct pipe_debug_callback *debug); void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin, FILE *out); uint64_t ir3_shader_outputs(const struct ir3_shader *so); -- 2.7.4