Mesa (main): llvmpipe: make last_fence a screen/rast object not a context one.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 02:11:52 UTC 2022


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Jul 22 11:12:58 2022 +1000

llvmpipe: make last_fence a screen/rast object not a context one.

When a flush happens the per-context setup is used to hold the fence
for the last scene sent to the rasterizer. However when multiple
contexts are in use, this fence won't get returned to be blocked on.

Instead move the last fence to the rasterizer object, and return
that instead as it should be valid across contexts.

Fixes gtk4 bugs on llvmpipe since overlapping vertex/fragment.

Fixes: 6bbbe15a783a ("Reinstate: llvmpipe: allow vertex processing and fragment processing in parallel")
Acked-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17702>

---

 src/gallium/drivers/llvmpipe/lp_flush.c         | 12 +++++++++---
 src/gallium/drivers/llvmpipe/lp_rast.c          | 14 +++++++++++++-
 src/gallium/drivers/llvmpipe/lp_rast.h          |  3 ++-
 src/gallium/drivers/llvmpipe/lp_rast_priv.h     |  2 ++
 src/gallium/drivers/llvmpipe/lp_setup.c         | 20 ++++----------------
 src/gallium/drivers/llvmpipe/lp_setup.h         |  1 -
 src/gallium/drivers/llvmpipe/lp_setup_context.h |  1 -
 7 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index c231f334eaf..c72944232e7 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -38,7 +38,9 @@
 #include "lp_flush.h"
 #include "lp_context.h"
 #include "lp_setup.h"
-
+#include "lp_fence.h"
+#include "lp_screen.h"
+#include "lp_rast.h"
 
 /**
  * \param fence  if non-null, returns pointer to a fence which can be waited on
@@ -49,11 +51,15 @@ llvmpipe_flush( struct pipe_context *pipe,
                 const char *reason)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
-
+   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
    draw_flush(llvmpipe->draw);
 
    /* ask the setup module to flush */
-   lp_setup_flush(llvmpipe->setup, fence, reason);
+   lp_setup_flush(llvmpipe->setup, reason);
+
+   lp_rast_fence(screen->rast, (struct lp_fence **)fence);
+   if (fence && (!*fence))
+      *fence = (struct pipe_fence_handle *)lp_fence_create(0);
 
    /* Enable to dump BMPs of the color/depth buffers each frame */
    if (0) {
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index f0d56e8a0d7..b92863f3c6e 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -47,6 +47,7 @@
 #include "gallivm/lp_bld_format.h"
 #include "gallivm/lp_bld_debug.h"
 #include "lp_scene.h"
+#include "lp_screen.h"
 #include "lp_tex_sample.h"
 
 
@@ -1100,6 +1101,10 @@ lp_rast_queue_scene(struct lp_rasterizer *rast,
 {
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
+   lp_fence_reference(&rast->last_fence, scene->fence);
+   if (rast->last_fence)
+      rast->last_fence->issued = TRUE;
+
    if (rast->num_threads == 0) {
       /* no threading */
       unsigned fpstate = util_fpstate_get();
@@ -1350,6 +1355,8 @@ lp_rast_destroy(struct lp_rasterizer *rast)
       align_free(rast->tasks[i].thread_data.cache);
    }
 
+   lp_fence_reference(&rast->last_fence, NULL);
+
    /* for synchronizing rasterization threads */
    if (rast->num_threads > 0) {
       util_barrier_destroy(&rast->barrier);
@@ -1360,4 +1367,9 @@ lp_rast_destroy(struct lp_rasterizer *rast)
    FREE(rast);
 }
 
-
+void lp_rast_fence(struct lp_rasterizer *rast,
+                   struct lp_fence **fence)
+{
+   if (fence)
+      lp_fence_reference((struct lp_fence **)fence, rast->last_fence);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 5051b251721..4fbc93a0f0f 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -431,5 +431,6 @@ lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene );
 void
 lp_debug_draw_bins_by_coverage( struct lp_scene *scene );
 
-
+void lp_rast_fence(struct lp_rasterizer *rast,
+                   struct lp_fence **fence);
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index a7718fbe355..3af94338f11 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -129,6 +129,8 @@ struct lp_rasterizer
 
    /** For synchronizing the rasterization threads */
    util_barrier barrier;
+
+   struct lp_fence *last_fence;
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 8808abf5bb7..4adfa705914 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -212,11 +212,6 @@ lp_setup_rasterize_scene(struct lp_setup_context *setup)
 
    lp_scene_end_binning(scene);
 
-   lp_fence_reference(&setup->last_fence, scene->fence);
-
-   if (setup->last_fence)
-      setup->last_fence->issued = TRUE;
-
    mtx_lock(&screen->rast_mutex);
    lp_rast_queue_scene(screen->rast, scene);
    mtx_unlock(&screen->rast_mutex);
@@ -393,16 +388,9 @@ fail:
 
 void
 lp_setup_flush(struct lp_setup_context *setup,
-               struct pipe_fence_handle **fence,
                const char *reason)
 {
    set_scene_state(setup, SETUP_FLUSHED, reason);
-
-   if (fence) {
-      lp_fence_reference((struct lp_fence **)fence, setup->last_fence);
-      if (!*fence)
-         *fence = (struct pipe_fence_handle *)lp_fence_create(0);
-   }
 }
 
 
@@ -571,7 +559,7 @@ lp_setup_clear(struct lp_setup_context *setup,
    if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
       unsigned flagszs = flags & PIPE_CLEAR_DEPTHSTENCIL;
       if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs)) {
-         lp_setup_flush(setup, NULL, __FUNCTION__);
+         set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
 
          if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs))
             assert(0);
@@ -583,7 +571,7 @@ lp_setup_clear(struct lp_setup_context *setup,
       for (unsigned i = 0; i < setup->fb.nr_cbufs; i++) {
          if ((flags & (1 << (2 + i))) && setup->fb.cbufs[i]) {
             if (!lp_setup_try_clear_color_buffer(setup, color, i)) {
-               lp_setup_flush(setup, NULL, __FUNCTION__);
+               set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
 
                if (!lp_setup_try_clear_color_buffer(setup, color, i))
                   assert(0);
@@ -1561,7 +1549,6 @@ lp_setup_destroy(struct lp_setup_context *setup)
 
    LP_DBG(DEBUG_SETUP, "number of scenes used: %d\n", setup->num_active_scenes);
    slab_destroy(&setup->scene_slab);
-   lp_fence_reference(&setup->last_fence, NULL);
 
    FREE(setup);
 }
@@ -1726,7 +1713,8 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
       }
    }
    else {
-      lp_fence_reference(&pq->fence, setup->last_fence);
+      struct llvmpipe_screen *screen = llvmpipe_screen(setup->pipe->screen);
+      lp_rast_fence(screen->rast, &pq->fence);
    }
 
 fail:
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 2e46ab838a7..7ca2b3023bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -64,7 +64,6 @@ lp_setup_clear(struct lp_setup_context *setup,
 
 void
 lp_setup_flush( struct lp_setup_context *setup,
-                struct pipe_fence_handle **fence,
                 const char *reason);
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 1528b6791cb..d07495f9c30 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -96,7 +96,6 @@ struct lp_setup_context
    struct lp_scene *scenes[MAX_SCENES];  /**< all the scenes */
    struct lp_scene *scene;               /**< current scene being built */
 
-   struct lp_fence *last_fence;
    struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
    unsigned active_binned_queries;
 



More information about the mesa-commit mailing list