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);
}
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;
}
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;
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);
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);
}
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;
{
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;
}
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;
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));
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);
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) |
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);
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);
}
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;
}
/* 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;
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};
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);
}
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;
{
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;
}
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;
debug_assert(nr <= ARRAY_SIZE(color_regid));
- if (emit->key.binning_pass)
+ if (emit->binning_pass)
nr = 0;
setup_stages(emit, s);
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 */
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 */
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 */
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);
}
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;
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);
}
*/
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;
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++) {
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);
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;
}
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;
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;
{
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;
}
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;
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};
}
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);
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 */
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));
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);
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);
}
*/
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;
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++) {
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;
}
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;
}
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);
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;
{
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;
}
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;
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};
}
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);
}
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 */
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));
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);
if (!strcmp(argv[n], "--binning-pass")) {
debug_printf(" %s", argv[n]);
- key.binning_pass = true;
+ v.binning_pass = true;
n++;
continue;
}
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);
}
*/
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);
}
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;
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);
}
}
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;
v->id = ++shader->variant_count;
v->shader = shader;
+ v->binning_pass = binning_pass;
v->key = key;
v->type = shader->type;
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;
*/
switch (shader->type) {
case SHADER_FRAGMENT:
- key.binning_pass = false;
if (key.has_per_samp) {
key.vsaturate_s = 0;
key.vsaturate_t = 0;
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;
}
+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)
{
*/
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;
}
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;
/*
* Vertex shader variant parameters:
*/
- unsigned binning_pass : 1;
unsigned vclamp_color : 1;
/*
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;
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);