summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-09-26 10:33:11 -0400
committerRob Clark <[email protected]>2014-09-27 13:34:07 -0400
commited48f91275f52f26b513fc2970233063bfa023af (patch)
tree6c845930cbfdca79d8a5c4eafc98b8037b1a505a /src/gallium/drivers/freedreno/a3xx
parentdf2f0c6d5595280150281409b4a9aadb9311bfdc (diff)
freedreno/a3xx: add flat interpolation mode
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c3
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_gmem.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c44
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.h4
4 files changed, 43 insertions, 14 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 73a28dda5e6..624155b0ade 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -525,7 +525,8 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
}
if (dirty & FD_DIRTY_PROG) {
- fd3_program_emit(ring, prog, key);
+ bool flat = ctx->rasterizer && ctx->rasterizer->flatshade;
+ fd3_program_emit(ring, prog, key, flat);
}
/* TODO we should not need this or fd_wfi() before emit_constants():
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
index ec5f28e5664..c43121993c0 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
@@ -183,7 +183,7 @@ emit_binning_workaround(struct fd_context *ctx)
A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
- fd3_program_emit(ring, &ctx->solid_prog, key);
+ fd3_program_emit(ring, &ctx->solid_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
(struct fd3_vertex_buf[]) {{
.prsc = fd3_ctx->solid_vbuf,
@@ -408,7 +408,7 @@ fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
- fd3_program_emit(ring, &ctx->solid_prog, key);
+ fd3_program_emit(ring, &ctx->solid_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
(struct fd3_vertex_buf[]) {{
.prsc = fd3_ctx->solid_vbuf,
@@ -552,7 +552,7 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
- fd3_program_emit(ring, &ctx->blit_prog, key);
+ fd3_program_emit(ring, &ctx->blit_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->blit_prog.vp, key),
(struct fd3_vertex_buf[]) {{
.prsc = fd3_ctx->blit_texcoord_vbuf,
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 1cf95a722a6..d7fe42ec4df 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -173,7 +173,9 @@ find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
void
fd3_program_emit(struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog, struct ir3_shader_key key)
+ struct fd_program_stateobj *prog,
+ struct ir3_shader_key key,
+ boolean rasterflat)
{
const struct ir3_shader_variant *vp, *fp;
const struct ir3_info *vsi, *fsi;
@@ -334,10 +336,6 @@ fd3_program_emit(struct fd_ringbuffer *ring,
OUT_RELOC(ring, fp->bo, 0, 0, 0); /* SP_FS_OBJ_START_REG */
}
- OUT_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2);
- OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_0 */
- OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_1 */
-
OUT_PKT0(ring, REG_A3XX_SP_FS_OUTPUT_REG, 1);
if (fp->writes_pos) {
OUT_RING(ring, A3XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE |
@@ -360,6 +358,30 @@ fd3_program_emit(struct fd_ringbuffer *ring,
COND(vp->writes_psize, A3XX_VPC_ATTR_PSIZE));
OUT_RING(ring, 0x00000000);
} else {
+ uint32_t vinterp[4] = {0}, flatshade[2] = {0};
+
+ /* figure out VARYING_INTERP / FLAT_SHAD register values: */
+ for (j = -1; (j = next_varying(fp, j)) < (int)fp->inputs_count; ) {
+ uint32_t interp = fp->inputs[j].interpolate;
+ if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
+ ((interp == TGSI_INTERPOLATE_COLOR) && 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);
+
+ for (i = 0; i < 4; i++, loc++) {
+ vinterp[loc / 16] |= FLAT << ((loc % 16) * 2);
+ flatshade[loc / 32] |= 1 << (loc % 32);
+ }
+ }
+ }
+
OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2);
OUT_RING(ring, A3XX_VPC_ATTR_TOTALATTR(fp->total_in) |
A3XX_VPC_ATTR_THRDASSIGN(1) |
@@ -369,16 +391,20 @@ fd3_program_emit(struct fd_ringbuffer *ring,
A3XX_VPC_PACK_NUMNONPOSVSVAR(fp->total_in));
OUT_PKT0(ring, REG_A3XX_VPC_VARYING_INTERP_MODE(0), 4);
- OUT_RING(ring, fp->shader->vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
- OUT_RING(ring, fp->shader->vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
- OUT_RING(ring, fp->shader->vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
- OUT_RING(ring, fp->shader->vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */
+ OUT_RING(ring, vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
+ OUT_RING(ring, vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
+ OUT_RING(ring, vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
+ 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_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2);
+ OUT_RING(ring, flatshade[0]); /* SP_FS_FLAT_SHAD_MODE_REG_0 */
+ OUT_RING(ring, flatshade[1]); /* SP_FS_FLAT_SHAD_MODE_REG_1 */
}
OUT_PKT0(ring, REG_A3XX_VFD_VS_THREADING_THRESHOLD, 1);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.h b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
index cebaeecc5bc..0d50956cc14 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
@@ -38,7 +38,9 @@ struct fd3_shader_stateobj {
};
void fd3_program_emit(struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog, struct ir3_shader_key key);
+ struct fd_program_stateobj *prog,
+ struct ir3_shader_key key,
+ boolean rasterflat);
void fd3_prog_init(struct pipe_context *pctx);