etnaviv: Set SE.CLIP registers, add margins for scissor/clip registers

This fixes rendering of full-screen quads (and other screen-filling
geometry, e.g. ioquake3 walls up-close) on gc3000. It should be a no-op
on other hardware.

- It looks like SE_CLIP registers were not set at all.
  I'm amazed that rendering worked without them. Emit them to
  avoid issues on gc3000.

- Define constants
  ETNA_SE_SCISSOR_MARGIN_RIGHT (0x1119)
  ETNA_SE_SCISSOR_MARGIN_BOTTOM (0x1111)
  ETNA_SE_CLIP_MARGIN_RIGHT (0xffff)
  ETNA_SE_CLIP_MARGIN_BOTTOM (0xffff)

  These demarcate the margin (fixp16) between the computed sizes and the
  value sent to the chip. I have set these to the numbers used by the
  Vivante driver for gc2000. I am not sure whether any old hardware was
  relying on the old numbers, or whether those were just a guess. But if
  so, these need to be moved to the _specs structure.

CC: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com>
Acked-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
Wladimir J. van der Laan 2016-11-25 06:42:43 +00:00 committed by Christian Gmeiner
parent fe3bb8cdb5
commit 56314f5baf
3 changed files with 52 additions and 20 deletions

View File

@ -491,6 +491,23 @@ etna_emit_state(struct etna_context *ctx)
/*00C14*/ EMIT_STATE(SE_DEPTH_BIAS, rasterizer->SE_DEPTH_BIAS);
/*00C18*/ EMIT_STATE(SE_CONFIG, rasterizer->SE_CONFIG);
}
if (unlikely(dirty & (ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER |
ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT))) {
struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
uint32_t clip_right =
MIN2(ctx->framebuffer.SE_CLIP_RIGHT, ctx->viewport.SE_CLIP_RIGHT);
uint32_t clip_bottom =
MIN2(ctx->framebuffer.SE_CLIP_BOTTOM, ctx->viewport.SE_CLIP_BOTTOM);
if (rasterizer->scissor) {
clip_right = MIN2(ctx->scissor.SE_CLIP_RIGHT, clip_right);
clip_bottom = MIN2(ctx->scissor.SE_CLIP_BOTTOM, clip_bottom);
}
/*00C20*/ EMIT_STATE_FIXP(SE_CLIP_RIGHT, clip_right);
/*00C24*/ EMIT_STATE_FIXP(SE_CLIP_BOTTOM, clip_bottom);
}
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
/*00E00*/ EMIT_STATE(RA_CONTROL, ctx->shader_state.RA_CONTROL);
}

View File

@ -47,6 +47,17 @@
/* PE render targets must be aligned to 64 bytes */
#define ETNA_PE_ALIGNMENT (64)
/* These demarcate the margin (fixp16) between the computed sizes and the
value sent to the chip. These have been set to the numbers used by the
Vivante driver on gc2000. They used to be -1 for scissor right and bottom. I
am not sure whether older hardware was relying on these or they were just a
guess. But if so, these need to be moved to the _specs structure.
*/
#define ETNA_SE_SCISSOR_MARGIN_RIGHT (0x1119)
#define ETNA_SE_SCISSOR_MARGIN_BOTTOM (0x1111)
#define ETNA_SE_CLIP_MARGIN_RIGHT (0xffff)
#define ETNA_SE_CLIP_MARGIN_BOTTOM (0xffff)
/* GPU chip 3D specs */
struct etna_specs {
/* supports SUPERTILE (64x64) tiling? */
@ -128,6 +139,8 @@ struct compiled_scissor_state {
uint32_t SE_SCISSOR_TOP;
uint32_t SE_SCISSOR_RIGHT;
uint32_t SE_SCISSOR_BOTTOM;
uint32_t SE_CLIP_RIGHT;
uint32_t SE_CLIP_BOTTOM;
};
/* Compiled pipe_viewport_state */
@ -142,6 +155,8 @@ struct compiled_viewport_state {
uint32_t SE_SCISSOR_TOP;
uint32_t SE_SCISSOR_RIGHT;
uint32_t SE_SCISSOR_BOTTOM;
uint32_t SE_CLIP_RIGHT;
uint32_t SE_CLIP_BOTTOM;
uint32_t PE_DEPTH_NEAR;
uint32_t PE_DEPTH_FAR;
};
@ -164,6 +179,8 @@ struct compiled_framebuffer_state {
uint32_t SE_SCISSOR_TOP;
uint32_t SE_SCISSOR_RIGHT;
uint32_t SE_SCISSOR_BOTTOM;
uint32_t SE_CLIP_RIGHT;
uint32_t SE_CLIP_BOTTOM;
uint32_t RA_MULTISAMPLE_UNK00E04;
uint32_t RA_MULTISAMPLE_UNK00E10[VIVS_RA_MULTISAMPLE_UNK00E10__LEN];
uint32_t RA_CENTROID_TABLE[VIVS_RA_CENTROID_TABLE__LEN];

View File

@ -323,8 +323,10 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
/* Scissor setup */
cs->SE_SCISSOR_LEFT = 0; /* affected by rasterizer and scissor state as well */
cs->SE_SCISSOR_TOP = 0;
cs->SE_SCISSOR_RIGHT = (sv->width << 16) - 1;
cs->SE_SCISSOR_BOTTOM = (sv->height << 16) - 1;
cs->SE_SCISSOR_RIGHT = (sv->width << 16) + ETNA_SE_SCISSOR_MARGIN_RIGHT;
cs->SE_SCISSOR_BOTTOM = (sv->height << 16) + ETNA_SE_SCISSOR_MARGIN_BOTTOM;
cs->SE_CLIP_RIGHT = (sv->width << 16) + ETNA_SE_CLIP_MARGIN_RIGHT;
cs->SE_CLIP_BOTTOM = (sv->height << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM;
cs->TS_MEM_CONFIG = ts_mem_config;
@ -345,13 +347,17 @@ etna_set_scissor_states(struct pipe_context *pctx, unsigned start_slot,
{
struct etna_context *ctx = etna_context(pctx);
struct compiled_scissor_state *cs = &ctx->scissor;
assert(ss->minx <= ss->maxx);
assert(ss->miny <= ss->maxy);
/* note that this state is only used when rasterizer_state->scissor is on */
ctx->scissor_s = *ss;
cs->SE_SCISSOR_LEFT = (ss->minx << 16);
cs->SE_SCISSOR_TOP = (ss->miny << 16);
cs->SE_SCISSOR_RIGHT = (ss->maxx << 16) - 1;
cs->SE_SCISSOR_BOTTOM = (ss->maxy << 16) - 1;
cs->SE_SCISSOR_RIGHT = (ss->maxx << 16) + ETNA_SE_SCISSOR_MARGIN_RIGHT;
cs->SE_SCISSOR_BOTTOM = (ss->maxy << 16) + ETNA_SE_SCISSOR_MARGIN_BOTTOM;
cs->SE_CLIP_RIGHT = (ss->maxx << 16) + ETNA_SE_CLIP_MARGIN_RIGHT;
cs->SE_CLIP_BOTTOM = (ss->maxy << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM;
ctx->dirty |= ETNA_DIRTY_SCISSOR;
}
@ -387,22 +393,14 @@ etna_set_viewport_states(struct pipe_context *pctx, unsigned start_slot,
/* Compute scissor rectangle (fixp) from viewport.
* Make sure left is always < right and top always < bottom.
*/
cs->SE_SCISSOR_LEFT = etna_f32_to_fixp16(MAX2(vs->translate[0] - vs->scale[0], 0.0f));
cs->SE_SCISSOR_TOP = etna_f32_to_fixp16(MAX2(vs->translate[1] - vs->scale[1], 0.0f));
cs->SE_SCISSOR_RIGHT = etna_f32_to_fixp16(MAX2(vs->translate[0] + vs->scale[0], 0.0f));
cs->SE_SCISSOR_BOTTOM = etna_f32_to_fixp16(MAX2(vs->translate[1] + vs->scale[1], 0.0f));
if (cs->SE_SCISSOR_LEFT > cs->SE_SCISSOR_RIGHT) {
uint32_t tmp = cs->SE_SCISSOR_RIGHT;
cs->SE_SCISSOR_RIGHT = cs->SE_SCISSOR_LEFT;
cs->SE_SCISSOR_LEFT = tmp;
}
if (cs->SE_SCISSOR_TOP > cs->SE_SCISSOR_BOTTOM) {
uint32_t tmp = cs->SE_SCISSOR_BOTTOM;
cs->SE_SCISSOR_BOTTOM = cs->SE_SCISSOR_TOP;
cs->SE_SCISSOR_TOP = tmp;
}
cs->SE_SCISSOR_LEFT = etna_f32_to_fixp16(MAX2(vs->translate[0] - fabsf(vs->scale[0]), 0.0f));
cs->SE_SCISSOR_TOP = etna_f32_to_fixp16(MAX2(vs->translate[1] - fabsf(vs->scale[1]), 0.0f));
uint32_t right_fixp = etna_f32_to_fixp16(MAX2(vs->translate[0] + fabsf(vs->scale[0]), 0.0f));
uint32_t bottom_fixp = etna_f32_to_fixp16(MAX2(vs->translate[1] + fabsf(vs->scale[1]), 0.0f));
cs->SE_SCISSOR_RIGHT = right_fixp + ETNA_SE_SCISSOR_MARGIN_RIGHT;
cs->SE_SCISSOR_BOTTOM = bottom_fixp + ETNA_SE_SCISSOR_MARGIN_BOTTOM;
cs->SE_CLIP_RIGHT = right_fixp + ETNA_SE_CLIP_MARGIN_RIGHT;
cs->SE_CLIP_BOTTOM = bottom_fixp + ETNA_SE_CLIP_MARGIN_BOTTOM;
cs->PE_DEPTH_NEAR = fui(0.0); /* not affected if depth mode is Z (as in GL) */
cs->PE_DEPTH_FAR = fui(1.0);