freedreno/a3xx: add support for point sprite coordinate replacement
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 17 Mar 2015 05:34:33 +0000 (01:34 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 28 Mar 2015 18:54:41 +0000 (14:54 -0400)
This does not (yet) support different coordinate origins, so the tests
still fail due to fbo flipping.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.h
src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
src/gallium/drivers/freedreno/a3xx/fd3_program.c

index 48dd8da782a1460d08752362a823b170c8b0d590..a3f954902a7ba317be974cbba7c084269b95542c 100644 (file)
@@ -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;
 
index 3aa77b6b12b55659476903a09cf11f085ed5f286..ce51c0c4968a5a643df75aa9895acd82a5ea961a 100644 (file)
@@ -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: */
index 9b4f31c4070d507da1f1d2855fcb1938a2d238a6..8ec28d92c34690376ba16259f7aaa89545bb99a9 100644 (file)
@@ -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),
                        },
index b6c448e865080fb2b26a14b28eb3777d790d9aa9..1250dffe29e929830859163422cc2e48d99b0a34 100644 (file)
@@ -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);
 }