Mesa (master): gallium/swr: Fix glVertexPointer race condition.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 8 15:42:09 UTC 2020


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

Author: Krzysztof Raszkowski <krzysztof.raszkowski at intel.com>
Date:   Wed Jan  8 15:42:03 2020 +0000

gallium/swr: Fix glVertexPointer race condition.

Sometimes using user buffer (not VBO) e.g. glVertexPointer
one thread could free memory before other thread used it.
Instead of copying this memory to driver simplier thing is
to block until draw finish.

Reviewed-by: Jan Zielinski <jan.zielinski at intel.com>

---

 src/gallium/drivers/swr/swr_context.h |  2 +-
 src/gallium/drivers/swr/swr_draw.cpp  |  4 ++--
 src/gallium/drivers/swr/swr_state.cpp | 41 +++++++++++------------------------
 3 files changed, 16 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/swr/swr_context.h b/src/gallium/drivers/swr/swr_context.h
index 82e6a6692f7..465357cc519 100644
--- a/src/gallium/drivers/swr/swr_context.h
+++ b/src/gallium/drivers/swr/swr_context.h
@@ -53,7 +53,7 @@
 #define SWR_NEW_FRAMEBUFFER (1 << 15)
 #define SWR_NEW_CLIP (1 << 16)
 #define SWR_NEW_SO (1 << 17)
-#define SWR_LARGE_CLIENT_DRAW (1<<18) // Indicates client draw will block
+#define SWR_BLOCK_CLIENT_DRAW ( 1 << 18) // Indicates client draw will block
 
 namespace std
 {
diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp
index 0377861b7a4..b7f354cd2a2 100644
--- a/src/gallium/drivers/swr/swr_draw.cpp
+++ b/src/gallium/drivers/swr/swr_draw.cpp
@@ -236,10 +236,10 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                                    info->start,
                                    info->start_instance);
 
-   /* On large client-buffer draw, we used client buffer directly, without
+   /* On client-buffer draw, we used client buffer directly, without
     * copy.  Block until draw is finished.
     * VMD is an example application that benefits from this. */
-   if (ctx->dirty & SWR_LARGE_CLIENT_DRAW) {
+   if (ctx->dirty & SWR_BLOCK_CLIENT_DRAW) {
       struct swr_screen *screen = swr_screen(pipe->screen);
       swr_fence_submit(ctx, screen->flush_fence);
       swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
index 3a007db4c1c..cd55e68b8d4 100644
--- a/src/gallium/drivers/swr/swr_state.cpp
+++ b/src/gallium/drivers/swr/swr_state.cpp
@@ -1307,20 +1307,12 @@ swr_update_derived(struct pipe_context *pipe,
             partial_inbounds = 0;
             min_vertex_index = info.min_index + info.index_bias;
 
-            size = AlignUp(size, 4);
-            /* If size of client memory copy is too large, don't copy. The
-             * draw will access user-buffer directly and then block.  This is
-             * faster than queuing many large client draws. */
-            if (size >= screen->client_copy_limit) {
-               post_update_dirty_flags |= SWR_LARGE_CLIENT_DRAW;
-               p_data = (const uint8_t *) vb->buffer.user;
-            } else {
-               /* Copy only needed vertices to scratch space */
-               const void *ptr = (const uint8_t *) vb->buffer.user + base;
-               ptr = (uint8_t *)swr_copy_to_scratch_space(
-                     ctx, &ctx->scratch->vertex_buffer, ptr, size);
-               p_data = (const uint8_t *)ptr - base;
-            }
+            /* Use user memory directly. The draw will access user-buffer
+             * directly and then block. It's easier and usually
+             * faster than copying.
+             */
+            post_update_dirty_flags |= SWR_BLOCK_CLIENT_DRAW;
+            p_data = (const uint8_t *) vb->buffer.user;
          } else if (vb->buffer.resource) {
             /* VBO */
             if (!pitch) {
@@ -1380,20 +1372,13 @@ swr_update_derived(struct pipe_context *pipe,
             post_update_dirty_flags |= SWR_NEW_VERTEX;
 
             size = info.count * pitch;
-            size = AlignUp(size, 4);
-            /* If size of client memory copy is too large, don't copy. The
-             * draw will access user-buffer directly and then block.  This is
-             * faster than queuing many large client draws. */
-            if (size >= screen->client_copy_limit) {
-               post_update_dirty_flags |= SWR_LARGE_CLIENT_DRAW;
-               p_data = (const uint8_t *) info.index.user;
-            } else {
-               /* Copy indices to scratch space */
-               const void *ptr = info.index.user;
-               ptr = swr_copy_to_scratch_space(
-                     ctx, &ctx->scratch->index_buffer, ptr, size);
-               p_data = (const uint8_t *)ptr;
-            }
+
+            /* Use user memory directly. The draw will access user-buffer
+             * directly and then block. It's easier and usually
+             * faster than copying.
+             */
+            post_update_dirty_flags |= SWR_BLOCK_CLIENT_DRAW;
+            p_data = (const uint8_t *) info.index.user;
          }
 
          SWR_INDEX_BUFFER_STATE swrIndexBuffer;




More information about the mesa-commit mailing list