From 58e24b4761ec8c348bf6825c2355a6e047599306 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Mon, 24 Aug 2015 23:31:00 -0400 Subject: [PATCH] freedreno/a3xx: add basic clip plane support The hardware is capable of dealing with GL1-style user clip planes. No clip vertex, no clip distances. Fixes a number of ucp tests, as well as neverball. Signed-off-by: Ilia Mirkin Cc: "11.0" --- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 19 +++++++++++++++++++ src/gallium/drivers/freedreno/freedreno_context.h | 2 ++ src/gallium/drivers/freedreno/freedreno_state.c | 4 +++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index 752e7f88cb9..6f514ed05df 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -563,10 +563,29 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, val |= COND(fp->writes_pos, A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE); val |= COND(fp->frag_coord, A3XX_GRAS_CL_CLIP_CNTL_ZCOORD | A3XX_GRAS_CL_CLIP_CNTL_WCOORD); + /* TODO only use if prog doesn't use clipvertex/clipdist */ + val |= MIN2(util_bitcount(ctx->rasterizer->clip_plane_enable), 6) << 26; OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); OUT_RING(ring, val); } + if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_UCP)) { + uint32_t planes = ctx->rasterizer->clip_plane_enable; + int count = 0; + + while (planes && count < 6) { + int i = ffs(planes) - 1; + + planes &= ~(1U << i); + fd_wfi(ctx, ring); + OUT_PKT0(ring, REG_A3XX_GRAS_CL_USER_PLANE(count++), 4); + OUT_RING(ring, fui(ctx->ucp.ucp[i][0])); + OUT_RING(ring, fui(ctx->ucp.ucp[i][1])); + OUT_RING(ring, fui(ctx->ucp.ucp[i][2])); + OUT_RING(ring, fui(ctx->ucp.ucp[i][3])); + } + } + /* 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 diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 509a90fdf23..3486c2fd1b7 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -334,6 +334,7 @@ struct fd_context { FD_DIRTY_INDEXBUF = (1 << 16), FD_DIRTY_SCISSOR = (1 << 17), FD_DIRTY_STREAMOUT = (1 << 18), + FD_DIRTY_UCP = (1 << 19), } dirty; struct pipe_blend_state *blend; @@ -355,6 +356,7 @@ struct fd_context { struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES]; struct pipe_index_buffer indexbuf; struct fd_streamout_stateobj streamout; + struct pipe_clip_state ucp; /* GMEM/tile handling fxns: */ void (*emit_tile_init)(struct fd_context *ctx); diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 7bf8bdb4507..e75865a9387 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -65,7 +65,9 @@ static void fd_set_clip_state(struct pipe_context *pctx, const struct pipe_clip_state *clip) { - DBG("TODO: "); + struct fd_context *ctx = fd_context(pctx); + ctx->ucp = *clip; + ctx->dirty |= FD_DIRTY_UCP; } static void -- 2.11.0