freedreno/a6xx: limit LRZ state emit
authorRob Clark <robdclark@chromium.org>
Thu, 16 Apr 2020 21:52:29 +0000 (14:52 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 30 Apr 2020 20:03:17 +0000 (20:03 +0000)
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4813>

src/gallium/drivers/freedreno/a6xx/fd6_context.h
src/gallium/drivers/freedreno/a6xx/fd6_emit.c

index 876017e25704eb80f2f2d082093b19481b2d32fe..75a52d4828ae8a0ec608e72137fa7875aa659468 100644 (file)
@@ -105,6 +105,17 @@ struct fd6_context {
                uint32_t PC_UNKNOWN_9805;
                uint32_t SP_UNKNOWN_A0F8;
        } magic;
+
+
+       struct {
+               /* previous binning/draw lrz state, which is a function of multiple
+                * gallium stateobjs, but doesn't necessarily change as frequently:
+                */
+               struct {
+                       uint32_t gras_lrz_cntl;
+                       uint32_t rb_lrz_cntl;
+               } lrz[2];
+       } last;
 };
 
 static inline struct fd6_context *
index 48f8777d641efe0e31069340f786bf61151e9246..9d8ebbca446c95df06dbd7f20d82b6b6bbfdc6fb 100644 (file)
@@ -698,16 +698,14 @@ build_vbo_state(struct fd6_emit *emit, const struct ir3_shader_variant *vp)
 static struct fd_ringbuffer *
 build_lrz(struct fd6_emit *emit, bool binning_pass)
 {
-       struct fd6_blend_stateobj *blend = fd6_blend_stateobj(emit->ctx->blend);
-       struct fd6_zsa_stateobj *zsa = fd6_zsa_stateobj(emit->ctx->zsa);
-       struct pipe_framebuffer_state *pfb = &emit->ctx->batch->framebuffer;
+       struct fd_context *ctx = emit->ctx;
+       struct fd6_blend_stateobj *blend = fd6_blend_stateobj(ctx->blend);
+       struct fd6_zsa_stateobj *zsa = fd6_zsa_stateobj(ctx->zsa);
+       struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
        struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
        uint32_t gras_lrz_cntl = zsa->gras_lrz_cntl;
        uint32_t rb_lrz_cntl = zsa->rb_lrz_cntl;
 
-       struct fd_ringbuffer *ring = fd_submit_new_ringbuffer(emit->ctx->batch->submit,
-                       16, FD_RINGBUFFER_STREAMING);
-
        if (zsa->invalidate_lrz) {
                rsc->lrz_valid = false;
                gras_lrz_cntl = 0;
@@ -719,6 +717,18 @@ build_lrz(struct fd6_emit *emit, bool binning_pass)
                gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_LRZ_WRITE;
        }
 
+       struct fd6_context *fd6_ctx = fd6_context(ctx);
+       if ((fd6_ctx->last.lrz[binning_pass].gras_lrz_cntl == gras_lrz_cntl) &&
+                       (fd6_ctx->last.lrz[binning_pass].rb_lrz_cntl == rb_lrz_cntl) &&
+                       !ctx->last.dirty)
+               return NULL;
+
+       fd6_ctx->last.lrz[binning_pass].gras_lrz_cntl = gras_lrz_cntl;
+       fd6_ctx->last.lrz[binning_pass].rb_lrz_cntl = rb_lrz_cntl;
+
+       struct fd_ringbuffer *ring = fd_submit_new_ringbuffer(ctx->batch->submit,
+                       16, FD_RINGBUFFER_STREAMING);
+
        OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_CNTL, 1);
        OUT_RING(ring, gras_lrz_cntl);
 
@@ -970,11 +980,15 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
                struct fd_ringbuffer *state;
 
                state = build_lrz(emit, false);
-               fd6_emit_take_group(emit, state, FD6_GROUP_LRZ, ENABLE_DRAW);
+               if (state) {
+                       fd6_emit_take_group(emit, state, FD6_GROUP_LRZ, ENABLE_DRAW);
+               }
 
                state = build_lrz(emit, true);
-               fd6_emit_take_group(emit, state,
-                               FD6_GROUP_LRZ_BINNING, CP_SET_DRAW_STATE__0_BINNING);
+               if (state) {
+                       fd6_emit_take_group(emit, state,
+                                       FD6_GROUP_LRZ_BINNING, CP_SET_DRAW_STATE__0_BINNING);
+               }
        }
 
        if (dirty & FD_DIRTY_STENCIL_REF) {