Mesa (master): virgl: fix sync issue regarding discard/unsync transfers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 18 18:17:47 UTC 2019


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Mon Jun 17 09:53:48 2019 -0700

virgl: fix sync issue regarding discard/unsync transfers

GL_MAP_INVALIDATE_BUFFER_BIT cannot be treated as
GL_MAP_INVALIDATE_RANGE_BIT naively.  When we run into

  ptr = glMapBufferRange(buf, 0, size,
          GL_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
  memcpy(ptr, data1, size);
  glUnmapBuffer(buf);
  ptr = glMapBufferRange(buf, size, size,
          GL_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
  memcpy(ptr, data2, size);
  glUnmapBuffer(buf);

we never want data1 to be copy_transfer'ed.  Because that would mean
that data2 might overwrite valid data.

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Alexandros Frantzis alexandros.frantzis at collabora.com
Fixes: a22c5df0794 ("virgl: Use buffer copy transfers to avoid waiting when mapping")
Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

---

 src/gallium/drivers/virgl/virgl_resource.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
index 9b908afd852..4e585d72490 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -129,11 +129,21 @@ virgl_resource_transfer_prepare(struct virgl_context *vctx,
     */
    if (wait && (xfer->base.usage & (PIPE_TRANSFER_DISCARD_RANGE |
                                     PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE))) {
-      const bool can_realloc =
-         (xfer->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
-         virgl_can_rebind_resource(vctx, &res->u.b);
-      const bool can_staging = vctx->transfer_uploader &&
-                               !vctx->transfer_uploader_in_use;
+      bool can_realloc = false;
+      bool can_staging = false;
+
+      /* A PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE transfer may be followed by
+       * PIPE_TRANSFER_UNSYNCHRONIZED transfers to non-overlapping regions.
+       * It cannot be treated as a PIPE_TRANSFER_DISCARD_RANGE transfer,
+       * otherwise those following unsynchronized transfers may overwrite
+       * valid data.
+       */
+      if (xfer->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+         can_realloc = virgl_can_rebind_resource(vctx, &res->u.b);
+      } else {
+         can_staging = vctx->transfer_uploader &&
+                       !vctx->transfer_uploader_in_use;
+      }
 
       /* discard implies no readback */
       assert(!readback);




More information about the mesa-commit mailing list