summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-09-09 11:20:40 -0400
committerRob Clark <[email protected]>2014-09-09 19:42:18 -0400
commit720cfb6fe9a3dafadf3bc034008f7c5c15973866 (patch)
tree8bd078f92ca20bebe5f41f2e735965a91686c562 /src/gallium/drivers/freedreno/a3xx
parent564183f39c24c1674fd71df42c83a2e34d1c7291 (diff)
freedreno/a3xx: enable hw primitive-restart
Since software primitive-restart emulation is going to be removed (and anyways, mostly seemed to be crash prone in combination with u_primconvert and oddball scenarios (like PIPE_PRIM_POLYGON with only a single vertex), might as well do it in hardware (which fortunately didn't turn out to be too hard to figure out). Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_draw.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c15
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.h4
3 files changed, 17 insertions, 8 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index 89af740c07c..394277cf6b9 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -72,7 +72,7 @@ static void
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
struct fd_ringbuffer *ring, unsigned dirty, struct ir3_shader_key key)
{
- fd3_emit_state(ctx, ring, &ctx->prog, dirty, key);
+ fd3_emit_state(ctx, ring, info, &ctx->prog, key, dirty);
if (dirty & FD_DIRTY_VTXBUF)
emit_vertexbufs(ctx, ring, key);
@@ -132,7 +132,7 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
.half_precision = true,
};
- fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, key);
+ fd3_emit_state(ctx, ring, NULL, &ctx->solid_prog, key, dirty);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
(struct fd3_vertex_buf[]) {{
@@ -178,7 +178,7 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
fd3_clear_binning(ctx, dirty);
/* emit generic state now: */
- fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, key);
+ fd3_emit_state(ctx, ring, NULL, &ctx->solid_prog, key, dirty);
OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index aae8ff13d19..f5bdea2d00b 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -354,8 +354,8 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
void
fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog, uint32_t dirty,
- struct ir3_shader_key key)
+ const struct pipe_draw_info *info, struct fd_program_stateobj *prog,
+ struct ir3_shader_key key, uint32_t dirty)
{
struct ir3_shader_variant *vp;
struct ir3_shader_variant *fp;
@@ -444,7 +444,12 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, val);
}
- if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
+ /* NOTE: since primitive_restart is not actually part of any
+ * state object, we need to make sure that we always emit
+ * PRIM_VTX_CNTL.. either that or be more clever and detect
+ * when it changes.
+ */
+ if (info) {
uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
->pc_prim_vtx_cntl;
@@ -455,6 +460,10 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
val |= A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(stride_in_vpc);
}
+ if (info && info->indexed && info->primitive_restart) {
+ val |= A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART;
+ }
+
val |= COND(vp->writes_psize, A3XX_PC_PRIM_VTX_CNTL_PSIZE);
OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
index 5735c9f873d..81ff06275bc 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
@@ -59,8 +59,8 @@ void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
struct ir3_shader_variant *vp,
struct fd3_vertex_buf *vbufs, uint32_t n);
void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog, uint32_t dirty,
- struct ir3_shader_key key);
+ const struct pipe_draw_info *info, struct fd_program_stateobj *prog,
+ struct ir3_shader_key key, uint32_t dirty);
void fd3_emit_restore(struct fd_context *ctx);
#endif /* FD3_EMIT_H */