diff options
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_state.c | 29 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_util.h | 12 |
4 files changed, 57 insertions, 7 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 4697b2f6b9a..70b93340e77 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -677,12 +677,6 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) OUT_RING(ring, A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(scissor->maxx - 1) | A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(scissor->maxy - 1)); - OUT_PKT4(ring, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2); - OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->minx) | - A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->miny)); - OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->maxx - 1) | - A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->maxy - 1)); - ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx); ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny); ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx); @@ -690,7 +684,8 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) } if (dirty & FD_DIRTY_VIEWPORT) { - fd_wfi(ctx->batch, ring); + struct pipe_scissor_state *scissor = &ctx->viewport_scissor; + OUT_PKT4(ring, REG_A6XX_GRAS_CL_VPORT_XOFFSET_0, 6); OUT_RING(ring, A6XX_GRAS_CL_VPORT_XOFFSET_0(ctx->viewport.translate[0])); OUT_RING(ring, A6XX_GRAS_CL_VPORT_XSCALE_0(ctx->viewport.scale[0])); @@ -698,6 +693,19 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) OUT_RING(ring, A6XX_GRAS_CL_VPORT_YSCALE_0(ctx->viewport.scale[1])); OUT_RING(ring, A6XX_GRAS_CL_VPORT_ZOFFSET_0(ctx->viewport.translate[2])); OUT_RING(ring, A6XX_GRAS_CL_VPORT_ZSCALE_0(ctx->viewport.scale[2])); + + OUT_PKT4(ring, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2); + OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->minx) | + A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->miny)); + OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->maxx - 1) | + A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->maxy - 1)); + + unsigned guardband_x = fd_calc_guardband(scissor->maxx - scissor->minx); + unsigned guardband_y = fd_calc_guardband(scissor->maxy - scissor->miny); + + OUT_PKT4(ring, REG_A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ, 1); + OUT_RING(ring, A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_HORZ(guardband_x) | + A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_VERT(guardband_y)); } if (dirty & FD_DIRTY_PROG) { diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 8914489d8be..3a03845b4ab 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -289,6 +289,7 @@ struct fd_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple stipple; struct pipe_viewport_state viewport; + struct pipe_scissor_state viewport_scissor; struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES]; struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES]; struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES]; diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 76b54a56044..1b67cc35f14 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -288,7 +288,36 @@ fd_set_viewport_states(struct pipe_context *pctx, const struct pipe_viewport_state *viewport) { struct fd_context *ctx = fd_context(pctx); + struct pipe_scissor_state *scissor = &ctx->viewport_scissor; + float minx, miny, maxx, maxy; + ctx->viewport = *viewport; + + /* see si_get_scissor_from_viewport(): */ + + /* Convert (-1, -1) and (1, 1) from clip space into window space. */ + minx = -viewport->scale[0] + viewport->translate[0]; + miny = -viewport->scale[1] + viewport->translate[1]; + maxx = viewport->scale[0] + viewport->translate[0]; + maxy = viewport->scale[1] + viewport->translate[1]; + + /* Handle inverted viewports. */ + if (minx > maxx) { + swap(minx, maxx); + } + if (miny > maxy) { + swap(miny, maxy); + } + + debug_assert(miny >= 0); + debug_assert(maxy >= 0); + + /* Convert to integer and round up the max bounds. */ + scissor->minx = minx; + scissor->miny = miny; + scissor->maxx = ceilf(maxx); + scissor->maxy = ceilf(maxy); + ctx->dirty |= FD_DIRTY_VIEWPORT; } diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index e03f37dd627..125ad83523c 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -194,6 +194,18 @@ fd_half_precision(struct pipe_framebuffer_state *pfb) return true; } +/* Note sure if this is same on all gens, but seems to be same on the later + * gen's + */ +static inline unsigned +fd_calc_guardband(unsigned x) +{ + float l = log2(x); + if (l <= 8) + return 511; + return 511 - ((l - 8) * 65); +} + #define LOG_DWORDS 0 static inline void emit_marker(struct fd_ringbuffer *ring, int scratch_idx); |