freedreno/a6xx: set guardband clip

On older gens, the CLIP_ADJ bitfields were actually 3.6 fixed point.
Which might make more sense.  Although this formula comes up with values
pretty close to what blob does for various viewport sizes (for at least
a5xx and a6xx), and seems to work.

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2018-11-19 10:24:40 -05:00
parent 2773919f06
commit d47d77d49d
4 changed files with 57 additions and 7 deletions

View file

@ -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) {

View file

@ -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];

View file

@ -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;
}

View file

@ -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);