etnaviv: rework clippling calculation to be a derived state
authorChristian Gmeiner <christian.gmeiner@gmail.com>
Sat, 21 Mar 2020 10:24:48 +0000 (11:24 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 30 Mar 2020 15:30:15 +0000 (15:30 +0000)
This moves the whole clipping calculation out of the emit function.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4278>

src/gallium/drivers/etnaviv/etnaviv_context.h
src/gallium/drivers/etnaviv/etnaviv_emit.c
src/gallium/drivers/etnaviv/etnaviv_state.c

index c45e604..1392072 100644 (file)
@@ -138,6 +138,7 @@ struct etna_context {
       ETNA_DIRTY_TS              = (1 << 17),
       ETNA_DIRTY_TEXTURE_CACHES  = (1 << 18),
       ETNA_DIRTY_DERIVE_TS       = (1 << 19),
+      ETNA_DIRTY_SCISSOR_CLIP    = (1 << 20),
    } dirty;
 
    uint32_t prim_hwsupport;
@@ -156,6 +157,7 @@ struct etna_context {
    struct pipe_depth_stencil_alpha_state *zsa;
    struct compiled_vertex_elements_state *vertex_elements;
    struct compiled_shader_state shader_state;
+   struct compiled_scissor_state clipping;
 
    /* to simplify the emit process we store pre compiled state objects,
     * which got 'compiled' during state change. */
index 74a295f..0900f11 100644 (file)
@@ -391,33 +391,11 @@ etna_emit_state(struct etna_context *ctx)
       /*00A38*/ EMIT_STATE(PA_WIDE_LINE_WIDTH0, rasterizer->PA_LINE_WIDTH);
       /*00A3C*/ EMIT_STATE(PA_WIDE_LINE_WIDTH1, rasterizer->PA_LINE_WIDTH);
    }
-   if (unlikely(dirty & (ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER |
-                         ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT))) {
-      /* this is a bit of a mess: rasterizer.scissor determines whether to use
-       * only the framebuffer scissor, or specific scissor state, and the
-       * viewport clips too so the logic spans four CSOs */
-      struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
-
-      uint32_t scissor_left =
-         MAX2(ctx->framebuffer.SE_SCISSOR_LEFT, ctx->viewport.SE_SCISSOR_LEFT);
-      uint32_t scissor_top =
-         MAX2(ctx->framebuffer.SE_SCISSOR_TOP, ctx->viewport.SE_SCISSOR_TOP);
-      uint32_t scissor_right =
-         MIN2(ctx->framebuffer.SE_SCISSOR_RIGHT, ctx->viewport.SE_SCISSOR_RIGHT);
-      uint32_t scissor_bottom =
-         MIN2(ctx->framebuffer.SE_SCISSOR_BOTTOM, ctx->viewport.SE_SCISSOR_BOTTOM);
-
-      if (rasterizer->scissor) {
-         scissor_left = MAX2(ctx->scissor.SE_SCISSOR_LEFT, scissor_left);
-         scissor_top = MAX2(ctx->scissor.SE_SCISSOR_TOP, scissor_top);
-         scissor_right = MIN2(ctx->scissor.SE_SCISSOR_RIGHT, scissor_right);
-         scissor_bottom = MIN2(ctx->scissor.SE_SCISSOR_BOTTOM, scissor_bottom);
-      }
-
-      /*00C00*/ EMIT_STATE_FIXP(SE_SCISSOR_LEFT, scissor_left);
-      /*00C04*/ EMIT_STATE_FIXP(SE_SCISSOR_TOP, scissor_top);
-      /*00C08*/ EMIT_STATE_FIXP(SE_SCISSOR_RIGHT, scissor_right + ETNA_SE_SCISSOR_MARGIN_RIGHT);
-      /*00C0C*/ EMIT_STATE_FIXP(SE_SCISSOR_BOTTOM, scissor_bottom + ETNA_SE_SCISSOR_MARGIN_BOTTOM);
+   if (unlikely(dirty & (ETNA_DIRTY_SCISSOR_CLIP))) {
+      /*00C00*/ EMIT_STATE_FIXP(SE_SCISSOR_LEFT, ctx->clipping.SE_SCISSOR_LEFT);
+      /*00C04*/ EMIT_STATE_FIXP(SE_SCISSOR_TOP, ctx->clipping.SE_SCISSOR_TOP);
+      /*00C08*/ EMIT_STATE_FIXP(SE_SCISSOR_RIGHT, ctx->clipping.SE_SCISSOR_RIGHT + ETNA_SE_SCISSOR_MARGIN_RIGHT);
+      /*00C0C*/ EMIT_STATE_FIXP(SE_SCISSOR_BOTTOM, ctx->clipping.SE_SCISSOR_BOTTOM + ETNA_SE_SCISSOR_MARGIN_BOTTOM);
    }
    if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) {
       struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
@@ -426,22 +404,9 @@ 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_SCISSOR_RIGHT, ctx->viewport.SE_SCISSOR_RIGHT);
-      uint32_t clip_bottom =
-         MIN2(ctx->framebuffer.SE_SCISSOR_BOTTOM, ctx->viewport.SE_SCISSOR_BOTTOM);
-
-      if (rasterizer->scissor) {
-         clip_right = MIN2(ctx->scissor.SE_SCISSOR_RIGHT, clip_right);
-         clip_bottom = MIN2(ctx->scissor.SE_SCISSOR_BOTTOM, clip_bottom);
-      }
-
-      /*00C20*/ EMIT_STATE_FIXP(SE_CLIP_RIGHT, clip_right + ETNA_SE_CLIP_MARGIN_RIGHT);
-      /*00C24*/ EMIT_STATE_FIXP(SE_CLIP_BOTTOM, clip_bottom + ETNA_SE_CLIP_MARGIN_BOTTOM);
+   if (unlikely(dirty & (ETNA_DIRTY_SCISSOR_CLIP))) {
+      /*00C20*/ EMIT_STATE_FIXP(SE_CLIP_RIGHT, ctx->clipping.SE_SCISSOR_RIGHT + ETNA_SE_CLIP_MARGIN_RIGHT);
+      /*00C24*/ EMIT_STATE_FIXP(SE_CLIP_BOTTOM, ctx->clipping.SE_SCISSOR_BOTTOM + ETNA_SE_CLIP_MARGIN_BOTTOM);
    }
    if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
       /*00E00*/ EMIT_STATE(RA_CONTROL, ctx->shader_state.RA_CONTROL);
index 9d97fe0..8280727 100644 (file)
@@ -33,6 +33,7 @@
 #include "etnaviv_clear_blit.h"
 #include "etnaviv_context.h"
 #include "etnaviv_format.h"
+#include "etnaviv_rasterizer.h"
 #include "etnaviv_screen.h"
 #include "etnaviv_shader.h"
 #include "etnaviv_surface.h"
@@ -659,6 +660,39 @@ etna_update_ts_config(struct etna_context *ctx)
    return true;
 }
 
+static bool
+etna_update_clipping(struct etna_context *ctx)
+{
+   const struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
+
+   /* clip framebuffer against viewport */
+   uint32_t scissor_left =
+      MAX2(ctx->framebuffer.SE_SCISSOR_LEFT, ctx->viewport.SE_SCISSOR_LEFT);
+   uint32_t scissor_top =
+      MAX2(ctx->framebuffer.SE_SCISSOR_TOP, ctx->viewport.SE_SCISSOR_TOP);
+   uint32_t scissor_right =
+      MIN2(ctx->framebuffer.SE_SCISSOR_RIGHT, ctx->viewport.SE_SCISSOR_RIGHT);
+   uint32_t scissor_bottom =
+      MIN2(ctx->framebuffer.SE_SCISSOR_BOTTOM, ctx->viewport.SE_SCISSOR_BOTTOM);
+
+   /* clip against scissor */
+   if (rasterizer->scissor) {
+      scissor_left = MAX2(ctx->scissor.SE_SCISSOR_LEFT, scissor_left);
+      scissor_top = MAX2(ctx->scissor.SE_SCISSOR_TOP, scissor_top);
+      scissor_right = MIN2(ctx->scissor.SE_SCISSOR_RIGHT, scissor_right);
+      scissor_bottom = MIN2(ctx->scissor.SE_SCISSOR_BOTTOM, scissor_bottom);
+   }
+
+   ctx->clipping.SE_SCISSOR_LEFT = scissor_left;
+   ctx->clipping.SE_SCISSOR_TOP = scissor_top;
+   ctx->clipping.SE_SCISSOR_RIGHT = scissor_right;
+   ctx->clipping.SE_SCISSOR_BOTTOM = scissor_bottom;
+
+   ctx->dirty |= ETNA_DIRTY_SCISSOR_CLIP;
+
+   return true;
+}
+
 struct etna_state_updater {
    bool (*update)(struct etna_context *ctx);
    uint32_t dirty;
@@ -679,6 +713,10 @@ static const struct etna_state_updater etna_state_updates[] = {
    },
    {
       etna_update_ts_config, ETNA_DIRTY_DERIVE_TS,
+   },
+   {
+      etna_update_clipping, ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER |
+                            ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT,
    }
 };