Mesa (staging/21.3): freedreno/a6xx: Fix partial z/s clears with sysmem.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Nov 7 13:39:51 UTC 2021


Module: Mesa
Branch: staging/21.3
Commit: 0e03df23250bcdfd38014d1916718473051450aa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0e03df23250bcdfd38014d1916718473051450aa

Author: Emma Anholt <emma at anholt.net>
Date:   Wed Nov  3 09:51:26 2021 -0700

freedreno/a6xx: Fix partial z/s clears with sysmem.

We have to set 8c01 to say "leave these channels alone" when
clearing/storing just Z or S of z24s8.  Fixes the bypass path for
KHR-GLES3.packed_depth_stencil.verify_read_pixels.depth24_stencil8.

Cc: mesa-stable
Fixes: #5592
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13659>
(cherry picked from commit f0f5b8d47ca42ba76f90f0df2bcbe9d5e9eda66c)

---

 .pick_status.json                                |  2 +-
 src/freedreno/ci/freedreno-a630-fails.txt        |  2 --
 src/gallium/drivers/freedreno/a6xx/fd6_blitter.c | 19 +++++++-------
 src/gallium/drivers/freedreno/a6xx/fd6_blitter.h |  4 +--
 src/gallium/drivers/freedreno/a6xx/fd6_gmem.c    | 32 +++++++++++++++++++-----
 5 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 5065cc9b75a..ffda743456c 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -472,7 +472,7 @@
         "description": "freedreno/a6xx: Fix partial z/s clears with sysmem.",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/freedreno/ci/freedreno-a630-fails.txt b/src/freedreno/ci/freedreno-a630-fails.txt
index 82943da169f..4debb67db3f 100644
--- a/src/freedreno/ci/freedreno-a630-fails.txt
+++ b/src/freedreno/ci/freedreno-a630-fails.txt
@@ -622,8 +622,6 @@ spec@!opengl 2.1 at pbo,Fail
 spec@!opengl 2.1 at pbo@test_polygon_stip,Fail
 spec@!opengl 2.1 at polygon-stipple-fs,Fail
 spec@!opengl 3.0 at clearbuffer-depth-cs-probe,Timeout
-spec@!opengl 3.0 at clearbuffer-depth,Fail
-spec@!opengl 3.0 at clearbuffer-stencil,Fail
 spec@!opengl 3.1 at primitive-restart-xfb generated,Fail
 
 # "../src/gallium/drivers/freedreno/a6xx/fd6_gmem.c:976:emit_blit: Assertion `psurf->u.tex.first_layer == psurf->u.tex.last_layer' failed."
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
index 0750cb6ed49..6285f4683b8 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
@@ -250,7 +250,8 @@ emit_setup(struct fd_batch *batch)
 
 static void
 emit_blit_setup(struct fd_ringbuffer *ring, enum pipe_format pfmt,
-                bool scissor_enable, union pipe_color_union *color)
+                bool scissor_enable, union pipe_color_union *color,
+                uint32_t unknown_8c01)
 {
    enum a6xx_format fmt = fd6_color_format(pfmt, TILE6_LINEAR);
    bool is_srgb = util_format_is_srgb(pfmt);
@@ -290,7 +291,7 @@ emit_blit_setup(struct fd_ringbuffer *ring, enum pipe_format pfmt,
          A6XX_SP_2D_DST_FORMAT_MASK(0xf));
 
    OUT_PKT4(ring, REG_A6XX_RB_2D_UNKNOWN_8C01, 1);
-   OUT_RING(ring, 0);
+   OUT_RING(ring, unknown_8c01);
 }
 
 /* buffers need to be handled specially since x/width can exceed the bounds
@@ -345,7 +346,7 @@ emit_blit_buffer(struct fd_context *ctx, struct fd_ringbuffer *ring,
    sshift = sbox->x & 0x3f;
    dshift = dbox->x & 0x3f;
 
-   emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, NULL);
+   emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, NULL, 0);
 
    for (unsigned off = 0; off < sbox->width; off += (0x4000 - 0x40)) {
       unsigned soff, doff, w, p;
@@ -430,7 +431,7 @@ fd6_clear_ubwc(struct fd_batch *batch, struct fd_resource *rsc) assert_dt
    struct fd_ringbuffer *ring = fd_batch_get_prologue(batch);
    union pipe_color_union color = {};
 
-   emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, &color);
+   emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, &color, 0);
 
    OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13);
    OUT_RING(ring, 0x00000000);
@@ -669,7 +670,7 @@ emit_blit_texture(struct fd_context *ctx, struct fd_ringbuffer *ring,
                         A6XX_GRAS_2D_RESOLVE_CNTL_1_Y(info->scissor.maxy - 1));
    }
 
-   emit_blit_setup(ring, info->dst.format, info->scissor_enable, NULL);
+   emit_blit_setup(ring, info->dst.format, info->scissor_enable, NULL, 0);
 
    for (unsigned i = 0; i < info->dst.box.depth; i++) {
 
@@ -782,7 +783,7 @@ convert_color(enum pipe_format format, union pipe_color_union *pcolor)
 void
 fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
                   struct pipe_surface *psurf, uint32_t width, uint32_t height,
-                  union pipe_color_union *color)
+                  union pipe_color_union *color, uint32_t unknown_8c01)
 {
    if (DEBUG_BLIT) {
       fprintf(stderr, "surface clear:\ndst resource: ");
@@ -799,7 +800,7 @@ fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
    union pipe_color_union clear_color = convert_color(psurf->format, color);
 
    emit_clear_color(ring, psurf->format, &clear_color);
-   emit_blit_setup(ring, psurf->format, false, &clear_color);
+   emit_blit_setup(ring, psurf->format, false, &clear_color, unknown_8c01);
 
    for (unsigned i = psurf->u.tex.first_layer; i <= psurf->u.tex.last_layer;
         i++) {
@@ -827,7 +828,7 @@ fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
 
 void
 fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
-                 uint32_t base, struct pipe_surface *psurf)
+                 uint32_t base, struct pipe_surface *psurf, uint32_t unknown_8c01)
 {
    const struct fd_gmem_stateobj *gmem = batch->gmem_state;
    uint64_t gmem_base = batch->ctx->screen->gmem_base + base;
@@ -848,7 +849,7 @@ fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
    /* Enable scissor bit, which will take into account the window scissor
     * which is set per-tile
     */
-   emit_blit_setup(ring, psurf->format, true, NULL);
+   emit_blit_setup(ring, psurf->format, true, NULL, unknown_8c01);
 
    /* We shouldn't be using GMEM in the layered rendering case: */
    assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
index dd423cf37f2..a354dd6a6a6 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
@@ -43,8 +43,8 @@ unsigned fd6_tile_mode(const struct pipe_resource *tmpl);
 void fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        struct pipe_surface *psurf, uint32_t width,
                        uint32_t height,
-                       union pipe_color_union *color) assert_dt;
+                       union pipe_color_union *color, uint32_t unknown_8c01) assert_dt;
 void fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
-                      uint32_t base, struct pipe_surface *psurf) assert_dt;
+                      uint32_t base, struct pipe_surface *psurf, uint32_t unknown_8c01) assert_dt;
 
 #endif /* FD6_BLIT_H_ */
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
index 49107398943..e99c199f579 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
@@ -1299,6 +1299,22 @@ needs_resolve(struct pipe_surface *psurf)
           (psurf->nr_samples != psurf->texture->nr_samples);
 }
 
+/**
+ * Returns the UNKNOWN_8C01 value for handling partial depth/stencil
+ * clear/stores to Z24S8.
+ */
+static uint32_t
+fd6_unknown_8c01(enum pipe_format format, unsigned buffers)
+{
+   if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
+      if (buffers == FD_BUFFER_DEPTH)
+         return 0x08000041;
+      else if (buffers == FD_BUFFER_STENCIL)
+         return 0x00084001;
+   }
+   return 0;
+}
+
 static void
 emit_resolve_blit(struct fd_batch *batch, struct fd_ringbuffer *ring,
                   uint32_t base, struct pipe_surface *psurf,
@@ -1318,7 +1334,12 @@ emit_resolve_blit(struct fd_batch *batch, struct fd_ringbuffer *ring,
     */
    if (needs_resolve(psurf) && !blit_can_resolve(psurf->format) &&
        (buffer != FD_BUFFER_STENCIL)) {
-      fd6_resolve_tile(batch, ring, base, psurf);
+      /* We could potentially use fd6_unknown_8c01() to handle partial z/s
+       * resolve to packed z/s, but we would need a corresponding ability in the
+       * !resolve case below, so batch_draw_tracking_for_dirty_bits() has us
+       * just do a restore of the other channel for partial packed z/s writes.
+       */
+      fd6_resolve_tile(batch, ring, base, psurf, 0);
       return;
    }
 
@@ -1477,7 +1498,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
             continue;
 
          fd6_clear_surface(ctx, ring, pfb->cbufs[i], pfb->width, pfb->height,
-                           &color);
+                           &color, 0);
       }
    }
    if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
@@ -1489,12 +1510,11 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
             ? &fd_resource(pfb->zsbuf->texture)->stencil->b.b
             : NULL;
 
-      if ((has_depth && (buffers & PIPE_CLEAR_DEPTH)) ||
-          (!separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
+      if ((buffers & PIPE_CLEAR_DEPTH) || (!separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
          value.f[0] = batch->clear_depth;
          value.ui[1] = batch->clear_stencil;
          fd6_clear_surface(ctx, ring, pfb->zsbuf, pfb->width, pfb->height,
-                           &value);
+                           &value, fd6_unknown_8c01(pfb->zsbuf->format, buffers));
       }
 
       if (separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) {
@@ -1505,7 +1525,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
          stencil_surf.texture = separate_stencil;
 
          fd6_clear_surface(ctx, ring, &stencil_surf, pfb->width, pfb->height,
-                           &value);
+                           &value, 0);
       }
    }
 



More information about the mesa-commit mailing list