summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2018-10-02 12:38:09 -0400
committerRob Clark <robdclark@gmail.com>2018-10-17 12:44:48 -0400
commit2e9c08c0bce8df63979327f3b1c3c828fd1b98da (patch)
tree91abf80199d5a99a9b3687fe78e173be0878d910
parent8b1a3b5dde6405b4193eb0118e044a88b9b3accf (diff)
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 <robdclark@gmail.com>
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_draw.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.h9
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c8
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_draw.c6
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_emit.c4
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_emit.h9
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_program.c10
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_compute.c2
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_draw.c8
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.c8
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.h9
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_program.c10
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_draw.c8
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_emit.c8
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_emit.h9
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_program.c10
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_cmdline.c2
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c9
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.c33
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.h10
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 9f148e6179a..e6572d62457 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 b5e20e5a592..77b0339b59e 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 c827522445f..6a6db4791e4 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 9d5c7b661fd..1a7d3062cf3 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 029c6086f2d..d854ebc4a40 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 34f8ef1b306..49ce6353526 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 376523d45b8..4d27f7076ee 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 860f615e31d..dac96de10ed 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 66ed7a4af57..1e084fd4c3b 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 96ff1a35945..bbb12897b85 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 e3bf9e26ba4..c666b25f137 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 bed52d4e87f..69ea3fa06a4 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 2a6e3334aed..a30678d0477 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 d9e363575db..be13f5f6098 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 eb24fb96cfb..706386af9cb 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 005952750f8..c05b0a45c96 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 c6d062a3a9a..33f5962ad13 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 b41c32d3756..bf801953d00 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 9f6a06cf333..9474f75a9f7 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 ee063f84d73..9bf0a7f999c 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 6bc24f47d75..1c31061af47 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);