summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/freedreno
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_emit.c22
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.c29
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.h12
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);