From ee670c9efa471aa78563b14f47bcd89220b608dc Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Tue, 17 Mar 2015 01:34:33 -0400 Subject: [PATCH] freedreno/a3xx: add support for point sprite coordinate replacement This does not (yet) support different coordinate origins, so the tests still fail due to fbo flipping. Signed-off-by: Ilia Mirkin --- src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 1 + src/gallium/drivers/freedreno/a3xx/fd3_emit.h | 2 + src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 1 + .../drivers/freedreno/a3xx/fd3_program.c | 54 +++++++++---------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index 48dd8da782a..a3f954902a7 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -158,6 +158,7 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info) }, .format = pipe_surface_format(pfb->cbufs[0]), .rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade, + .sprite_coord_enable = ctx->rasterizer ? ctx->rasterizer->sprite_coord_enable : 0, }; unsigned dirty; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h index 3aa77b6b12b..ce51c0c4968 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h @@ -55,6 +55,8 @@ struct fd3_emit { struct ir3_shader_key key; enum pipe_format format; uint32_t dirty; + + uint32_t sprite_coord_enable; bool rasterflat; /* cached to avoid repeated lookups of same variants: */ diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index 9b4f31c4070..8ec28d92c34 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -468,6 +468,7 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) struct fd3_emit emit = { .vtx = &fd3_ctx->blit_vbuf_state, .prog = &ctx->blit_prog, + .sprite_coord_enable = 1, .key = { .half_precision = fd3_half_precision(format), }, diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c index b6c448e8650..1250dffe29e 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c @@ -365,31 +365,40 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit) COND(vp->writes_psize, A3XX_VPC_ATTR_PSIZE)); OUT_RING(ring, 0x00000000); } else { - uint32_t vinterp[4], flatshade[2]; + uint32_t vinterp[4], flatshade[2], vpsrepl[4]; memset(vinterp, 0, sizeof(vinterp)); memset(flatshade, 0, sizeof(flatshade)); + memset(vpsrepl, 0, sizeof(vpsrepl)); /* figure out VARYING_INTERP / FLAT_SHAD register values: */ for (j = -1; (j = ir3_next_varying(fp, j)) < (int)fp->inputs_count; ) { uint32_t interp = fp->inputs[j].interpolate; - if ((interp == TGSI_INTERPOLATE_CONSTANT) || - ((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) { - /* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG - * instead.. rather than -8 everywhere else.. - */ - uint32_t loc = fp->inputs[j].inloc - 8; - /* currently assuming varyings aligned to 4 (not - * packed): - */ - debug_assert((loc % 4) == 0); + /* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG + * instead.. rather than -8 everywhere else.. + */ + uint32_t inloc = fp->inputs[j].inloc - 8; + + /* currently assuming varyings aligned to 4 (not + * packed): + */ + debug_assert((inloc % 4) == 0); + if ((interp == TGSI_INTERPOLATE_CONSTANT) || + ((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) { + uint32_t loc = inloc; for (i = 0; i < 4; i++, loc++) { vinterp[loc / 16] |= FLAT << ((loc % 16) * 2); flatshade[loc / 32] |= 1 << (loc % 32); } } + + /* TODO: Figure out if there's a way to make it spit out 0's and + * 1's for the .z and .w components. + */ + if (emit->sprite_coord_enable & (1 << sem2idx(fp->inputs[j].semantic))) + vpsrepl[inloc / 16] |= 0x09 << ((inloc % 16) * 2); } OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2); @@ -407,10 +416,10 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit) OUT_RING(ring, vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */ OUT_PKT0(ring, REG_A3XX_VPC_VARYING_PS_REPL_MODE(0), 4); - OUT_RING(ring, fp->shader->vpsrepl[0]); /* VPC_VARYING_PS_REPL[0].MODE */ - OUT_RING(ring, fp->shader->vpsrepl[1]); /* VPC_VARYING_PS_REPL[1].MODE */ - OUT_RING(ring, fp->shader->vpsrepl[2]); /* VPC_VARYING_PS_REPL[2].MODE */ - OUT_RING(ring, fp->shader->vpsrepl[3]); /* VPC_VARYING_PS_REPL[3].MODE */ + OUT_RING(ring, vpsrepl[0]); /* VPC_VARYING_PS_REPL[0].MODE */ + OUT_RING(ring, vpsrepl[1]); /* VPC_VARYING_PS_REPL[1].MODE */ + OUT_RING(ring, vpsrepl[2]); /* VPC_VARYING_PS_REPL[2].MODE */ + OUT_RING(ring, vpsrepl[3]); /* VPC_VARYING_PS_REPL[3].MODE */ OUT_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2); OUT_RING(ring, flatshade[0]); /* SP_FS_FLAT_SHAD_MODE_REG_0 */ @@ -436,19 +445,6 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit) } } -/* hack.. until we figure out how to deal w/ vpsrepl properly.. */ -static void -fix_blit_fp(struct pipe_context *pctx) -{ - struct fd_context *ctx = fd_context(pctx); - struct fd3_shader_stateobj *so = ctx->blit_prog.fp; - - so->shader->vpsrepl[0] = 0x99999999; - so->shader->vpsrepl[1] = 0x99999999; - so->shader->vpsrepl[2] = 0x99999999; - so->shader->vpsrepl[3] = 0x99999999; -} - void fd3_prog_init(struct pipe_context *pctx) { @@ -459,6 +455,4 @@ fd3_prog_init(struct pipe_context *pctx) pctx->delete_vs_state = fd3_vp_state_delete; fd_prog_init(pctx); - - fix_blit_fp(pctx); } -- 2.30.2