Mesa (master): nv50,nvc0: serialize between before/after using a zeta surface as color

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 11 20:13:56 UTC 2021


Module: Mesa
Branch: master
Commit: ec668e2fd142db27dfa9ea1084005db328889721
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ec668e2fd142db27dfa9ea1084005db328889721

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Fri Jan  8 01:37:35 2021 -0500

nv50,nvc0: serialize between before/after using a zeta surface as color

This happens during "3d" blit operations, where we must reinterpret it
as color in order to support stencil/depth masking. However the hardware
isn't necessarily amused by this, esp when multiple draws are queued up.
Throw in serialize calls in order to get it to flush out previous draws.

This was noticeable in the test
dEQP-GLES3.functional.fbo.invalidate.sub.unbind_blit_msaa_stencil,
although 3d blit operation had to be forced on nvc0 where it's much
rarer.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Reviewed-by: Karol Herbst <kherbst at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8396>

---

 src/gallium/drivers/nouveau/nv50/nv50_surface.c | 16 ++++++++++++++++
 src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 15 +++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 2b39c2592e0..b133997641a 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -1373,6 +1373,16 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
 
    nv50_state_validate_3d(nv50, ~0);
 
+   /* When flipping a surface from zeta <-> color "mode", we have to wait for
+    * the GPU to flush its current draws.
+    */
+   struct nv50_miptree *mt = nv50_miptree(dst);
+   bool serialize = util_format_is_depth_or_stencil(info->dst.format);
+   if (serialize && mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
+      BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+      PUSH_DATA (push, 0);
+   }
+
    x_range = (float)info->src.box.width / (float)info->dst.box.width;
    y_range = (float)info->src.box.height / (float)info->dst.box.height;
 
@@ -1475,6 +1485,12 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
    PUSH_DATA (push, 1);
 
+   /* mark the surface as reading, which will force a serialize next time it's
+    * used for writing.
+    */
+   if (serialize)
+      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
    nv50_blitctx_post_blit(blit);
 }
 
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 725e391d4f7..e0b81b679a2 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -1239,9 +1239,19 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
       }
    }
 
+   bool serialize = false;
+   struct nv50_miptree *mt = nv50_miptree(dst);
    if (screen->eng3d->oclass >= TU102_3D_CLASS) {
       IMMED_NVC0(push, SUBC_3D(TU102_3D_SET_COLOR_RENDER_TO_ZETA_SURFACE),
                  util_format_is_depth_or_stencil(info->dst.format));
+   } else {
+      /* When flipping a surface from zeta <-> color "mode", we have to wait for
+       * the GPU to flush its current draws.
+       */
+      serialize = util_format_is_depth_or_stencil(info->dst.format);
+      if (serialize && mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
+         IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+      }
    }
 
    IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
@@ -1386,6 +1396,11 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
    IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
    if (screen->eng3d->oclass >= TU102_3D_CLASS)
       IMMED_NVC0(push, SUBC_3D(TU102_3D_SET_COLOR_RENDER_TO_ZETA_SURFACE), 0);
+   else if (serialize)
+      /* mark the surface as reading, which will force a serialize next time
+       * it's used for writing.
+       */
+      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
 }
 
 static void



More information about the mesa-commit mailing list