freedreno/a6xx: fix LRZ logic
authorRob Clark <robdclark@chromium.org>
Fri, 6 Dec 2019 19:34:39 +0000 (11:34 -0800)
committerRob Clark <robdclark@gmail.com>
Tue, 10 Dec 2019 22:55:21 +0000 (22:55 +0000)
In particular, we need to invalidate the LRZ state when we cannot be
confident in what the Z state would be during rendering:

1) depth test modes not supported by LRZ
2) stencil test, which would require full rasterization and stencil
   test in the binning pass (whereas LRZ normally just needs to
   determine the min and max z value in an 8x8 quad)

Signed-off-by: Rob Clark <robdclark@chromium.org>
src/freedreno/registers/a6xx.xml
src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
src/gallium/drivers/freedreno/a6xx/fd6_zsa.c
src/gallium/drivers/freedreno/a6xx/fd6_zsa.h

index fe5b6adc37ba7fe11a0f3d8f159a929558f3faf0..480590a85f731af9358eb00d6d04c2d06d8cb418 100644 (file)
@@ -1975,10 +1975,9 @@ to upconvert to 32b float internally?
                <bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
                <doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
                <bitfield name="GREATER" pos="2" type="boolean"/>
-               <!-- set at end of batch that had LRZ enabled (to flush/disable it?) -->
                <bitfield name="UNK3" pos="3" type="boolean"/>
                <!-- set when depth-test + depth-write enabled -->
-               <bitfield name="UNK4" pos="4" type="boolean"/>
+               <bitfield name="Z_TEST_ENABLE" pos="4" type="boolean"/>
        </reg32>
        <reg32 offset="0x8101" name="GRAS_UNKNOWN_8101"/>
        <reg32 offset="0x8102" name="GRAS_2D_BLIT_INFO">
index a44aa3f224c6c92cebe2d1cbf431da1d76efbbe8..e878c0c1370cf1f66b2500e02ee79ca5d9614fce 100644 (file)
@@ -706,7 +706,11 @@ build_lrz(struct fd6_emit *emit, bool binning_pass)
        struct fd_ringbuffer *ring = fd_submit_new_ringbuffer(emit->ctx->batch->submit,
                        16, FD_RINGBUFFER_STREAMING);
 
-       if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) {
+       if (zsa->invalidate_lrz) {
+               rsc->lrz_valid = false;
+               gras_lrz_cntl = 0;
+               rb_lrz_cntl = 0;
+       } else if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) {
                gras_lrz_cntl = 0;
                rb_lrz_cntl = 0;
        } else if (binning_pass && blend->lrz_write && zsa->lrz_write) {
index 75c901f7507a4d2c3d05ccf9a86c10f977ce3d15..0176402ad87e7834efee9f64c2e1392d50ad5d2d 100644 (file)
@@ -284,7 +284,7 @@ use_hw_binning(struct fd_batch *batch)
 
        // TODO figure out hw limits for binning
 
-       return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2) &&
+       return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) >= 2) &&
                        (batch->num_draws > 0);
 }
 
index 290c8eb92969a045019c027979260e549f5c137b..9689de162d61e684e0263674248ecfd759556da5 100644 (file)
@@ -47,45 +47,61 @@ fd6_zsa_state_create(struct pipe_context *pctx,
 
        so->base = *cso;
 
-       switch (cso->depth.func) {
-       case PIPE_FUNC_LESS:
-       case PIPE_FUNC_LEQUAL:
-               so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE;
-               so->rb_lrz_cntl = A6XX_RB_LRZ_CNTL_ENABLE;
-               break;
-
-       case PIPE_FUNC_GREATER:
-       case PIPE_FUNC_GEQUAL:
-               so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER;
-               so->rb_lrz_cntl = A6XX_RB_LRZ_CNTL_ENABLE;
-               break;
-
-       default:
-               /* LRZ not enabled */
-               so->gras_lrz_cntl = 0;
-               break;
-       }
-
-       if (cso->depth.writemask) {
-               if (cso->depth.enabled)
-                       so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_UNK4;
-               so->lrz_write = true;
-       }
-
        so->rb_depth_cntl |=
                A6XX_RB_DEPTH_CNTL_ZFUNC(cso->depth.func); /* maps 1:1 */
 
-       if (cso->depth.enabled)
+       if (cso->depth.enabled) {
                so->rb_depth_cntl |=
                        A6XX_RB_DEPTH_CNTL_Z_ENABLE |
                        A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE;
 
+               so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_Z_TEST_ENABLE;
+
+               if (cso->depth.writemask) {
+                       so->lrz_write = true;
+               }
+
+               switch (cso->depth.func) {
+               case PIPE_FUNC_LESS:
+               case PIPE_FUNC_LEQUAL:
+                       so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE;
+                       so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+                       break;
+
+               case PIPE_FUNC_GREATER:
+               case PIPE_FUNC_GEQUAL:
+                       so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER;
+                       so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+                       break;
+
+               case PIPE_FUNC_NEVER:
+                       so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE;
+                       so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+                       so->lrz_write = false;
+                       break;
+
+               case PIPE_FUNC_EQUAL:
+               case PIPE_FUNC_NOTEQUAL:
+               case PIPE_FUNC_ALWAYS:
+                       so->lrz_write = false;
+                       so->invalidate_lrz = true;
+                       break;
+               }
+       }
+
        if (cso->depth.writemask)
                so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
 
        if (cso->stencil[0].enabled) {
                const struct pipe_stencil_state *s = &cso->stencil[0];
 
+               /* stencil test happens before depth test, so without performing
+                * stencil test we don't really know what the updates to the
+                * depth buffer will be.
+                */
+               so->lrz_write = false;
+               so->invalidate_lrz = true;
+
                so->rb_stencil_control |=
                        A6XX_RB_STENCIL_CONTROL_STENCIL_READ |
                        A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
index 996158c383950d817a39a8c0eaedd4945553372e..f1c4f6f29b6543610f4d2fe6948562682d1f121b 100644 (file)
@@ -45,6 +45,7 @@ struct fd6_zsa_stateobj {
        uint32_t gras_lrz_cntl;
        uint32_t rb_lrz_cntl;
        bool lrz_write;
+       bool invalidate_lrz;
 
        struct fd_ringbuffer *stateobj;
        struct fd_ringbuffer *stateobj_no_alpha;