freedreno/ir3: move binning_pass out of shader variant key
authorRob Clark <robdclark@gmail.com>
Tue, 2 Oct 2018 16:38:09 +0000 (12:38 -0400)
committerRob Clark <robdclark@gmail.com>
Wed, 17 Oct 2018 16:44:48 +0000 (12:44 -0400)
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 <robdclark@gmail.com>
21 files changed:
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.h
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.h
src/gallium/drivers/freedreno/a4xx/fd4_program.c
src/gallium/drivers/freedreno/a5xx/fd5_compute.c
src/gallium/drivers/freedreno/a5xx/fd5_draw.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.h
src/gallium/drivers/freedreno/a5xx/fd5_program.c
src/gallium/drivers/freedreno/a6xx/fd6_draw.c
src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/a6xx/fd6_emit.h
src/gallium/drivers/freedreno/a6xx/fd6_program.c
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c
src/gallium/drivers/freedreno/ir3/ir3_shader.h

index 9f148e6179a4bbca0a563414c214d8ae0aa6c468..e6572d624576da689c0d5e2e369e11e057b3308f 100644 (file)
@@ -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;
index b5e20e5a592bc73b71de0e59e972052fbc28bc6b..77b0339b59e7f22b53a0cba151efbc7f8e11895e 100644 (file)
@@ -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);
        }
 
index c827522445f14111eb35ddc0a0a19660bedbca7d..6a6db4791e4c70cb942f94a3125accb738635c8e 100644 (file)
@@ -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;
index 9d5c7b661fdb741f6cdd12ab2b2ca60f99f148ab..1a7d3062cf372fe920e4738051e64edacaa398e5 100644 (file)
@@ -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);
 
index 029c6086f2deaaee45b945bdf5add07d30ed7be8..d854ebc4a40c907ca5f8ea2a219ad7f4c677a934 100644 (file)
@@ -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;
index 34f8ef1b3061d96916917f9a72bcfc9570835d70..49ce6353526b171256e54c0996fe94c7f83c16d4 100644 (file)
@@ -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);
        }
 
index 376523d45b8114e6a3f46a4036c372540cbd8bda..4d27f7076ee7c942e5de20be45390f487d2cbbe1 100644 (file)
@@ -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;
index 860f615e31d78a9630e2335c6543d755cc8cf2d3..dac96de10ed2d4b26a45f8e1ca40ab2c757fbd96 100644 (file)
@@ -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);
 }
index 66ed7a4af57f00ac7b440e2daa90d26dc7564f93..1e084fd4c3b1188bcab1cb0de58fffb0b1cf6e53 100644 (file)
@@ -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;
 
index 96ff1a359450c41680cca58eebe39c677d01b36c..bbb12897b85f7f9807e85f6987a8cbc1e7c7bda9 100644 (file)
@@ -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;
index e3bf9e26ba4b9eba76e4c7acbe4a688e578f5e48..c666b25f137f9050e9721c4f0093d3ab055d3ffe 100644 (file)
@@ -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;
index bed52d4e87fffc2753d4d03f51b8628e5a1a0662..69ea3fa06a4a162a82747ca445dcbf9726154bdb 100644 (file)
@@ -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;
index 2a6e3334aed7e77feaa12efa21f6a0c185cfaad8..a30678d0477dcbdb32eb02612d2a3bb76caa5bb5 100644 (file)
@@ -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);
 
index d9e363575db2db143cf7645fd83a3975d317f5c7..be13f5f609833f59c1b432a60356e300a9c3926f 100644 (file)
@@ -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;
index eb24fb96cfba89e185ab0a4298dea4879bd453cc..706386af9cb2bc84a0dacfb70f7f393218c862a0 100644 (file)
@@ -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);
index 005952750f8dd57879bbcf8c618263f789900457..c05b0a45c96b889a356a5bfc819ed53a5b1bc854 100644 (file)
@@ -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;
index c6d062a3a9a9c92d97badca37199c4e91e0a2062..33f5962ad13bef9d5b5d446b0eed134d2e050fe5 100644 (file)
@@ -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);
 
index b41c32d3756b09036cce81be3d43c28bfd64b263..bf801953d008dc9c787a1f41c0de9ff5b1a09267 100644 (file)
@@ -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;
                }
index 9f6a06cf33326e982005e602fd781ec084b3f5d8..9474f75a9f7c39012928a5c753bd27aec533f5fe 100644 (file)
@@ -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;
 
index ee063f84d73088fd7649db4dc1f051aa1f3267f3..9bf0a7f999c6d67d3da52e34e4a3b37d42bf3c27 100644 (file)
@@ -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;
index 6bc24f47d75e870ba09a8437b0a111660dc1f31b..1c31061af47b112c65559f6c3da8de5d8cf62aca 100644 (file)
@@ -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);