[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1015039: gtk4 memorytexture test-case regresses with Mesa 22.1



Control: tags -1 + patch

On Tue, 19 Jul 2022 at 11:56:43 +0100, Simon McVittie wrote:
> A straightforward revert of 6bbbe15a applies cleanly to 22.1.x and
> appears to solve this.

Alternatively, upstream merge request
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17702 is waiting
for review, and a backport of it to 22.1.3 also appears to solve this
(see attached).

Because this is a RC bug (it caused FTBFS in gtk4, and apparently also
cases rendering errors in real-world use of gtk4 on llvmpipe), Mesa 22.1
will not migrate to testing until this is solved somehow or downgraded.

Please consider either reverting 6bbbe15a (the conservative approach)
or applying !17702.

Thanks,
    smcv
>From 235c8f728eef3fc2bbc97cfe0be007dda0b0d96d Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Fri, 22 Jul 2022 11:12:58 +1000
Subject: [PATCH 1/3] 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")
Origin: 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       | 26 +++++--------------
 src/gallium/drivers/llvmpipe/lp_setup.h       |  1 -
 .../drivers/llvmpipe/lp_setup_context.h       |  1 -
 7 files changed, 33 insertions(+), 26 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 e27d78a3432..6cdaa51b62d 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"
 
 
@@ -1128,6 +1129,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();
@@ -1384,6 +1389,8 @@ void 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 );
@@ -1394,4 +1401,9 @@ void 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 14a2710f7f5..1756345737f 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -388,5 +388,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 c4da9cca2ff..8b28893aa22 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;
 };
 
 void
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index ce681792683..ad92e2557c2 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -207,11 +207,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);
@@ -387,17 +382,10 @@ fail:
 
 
 void
-lp_setup_flush( struct lp_setup_context *setup,
-                struct pipe_fence_handle **fence,
-                const char *reason)
+lp_setup_flush(struct lp_setup_context *setup,
+               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);
-   }
+   set_scene_state(setup, SETUP_FLUSHED, reason);
 }
 
 
@@ -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 (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);
@@ -1589,7 +1577,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 );
 }
@@ -1758,7 +1745,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 5ecef123417..fe360be63ca 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 420b78e2f52..fac84fb56ec 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;
 
-- 
2.36.1

>From 3b960772b4a32a5a5e86c6b9d617f4327f935dd8 Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Mon, 25 Jul 2022 13:28:08 +1000
Subject: [PATCH 2/3] llvmpipe: keep context list and use to track resource
 usage.

Just check across all contexts if a resource is referenced.

Origin: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17702
---
 src/gallium/drivers/llvmpipe/lp_context.c | 12 ++++++++++--
 src/gallium/drivers/llvmpipe/lp_context.h |  1 +
 src/gallium/drivers/llvmpipe/lp_flush.c   | 10 ++++++----
 src/gallium/drivers/llvmpipe/lp_screen.c  |  2 ++
 src/gallium/drivers/llvmpipe/lp_screen.h  |  4 ++++
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index 8038e219015..3cce460f213 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -57,8 +57,12 @@
 static void llvmpipe_destroy( struct pipe_context *pipe )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+   struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
    uint i;
 
+   mtx_lock(&lp_screen->ctx_mutex);
+   list_del(&llvmpipe->list);
+   mtx_unlock(&lp_screen->ctx_mutex);
    lp_print_counters();
 
    if (llvmpipe->csctx) {
@@ -189,8 +193,9 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv,
                         unsigned flags)
 {
    struct llvmpipe_context *llvmpipe;
+   struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen);
 
-   if (!llvmpipe_screen_late_init(llvmpipe_screen(screen)))
+   if (!llvmpipe_screen_late_init(lp_screen))
       return NULL;
 
    llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16);
@@ -254,7 +259,7 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv,
       goto fail;
 
    draw_set_disk_cache_callbacks(llvmpipe->draw,
-                                 llvmpipe_screen(screen),
+                                 lp_screen,
                                  lp_draw_disk_cache_find_shader,
                                  lp_draw_disk_cache_insert_shader);
 
@@ -307,6 +312,9 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv,
     */
    llvmpipe->dirty |= LP_NEW_SCISSOR;
 
+   mtx_lock(&lp_screen->ctx_mutex);
+   list_addtail(&llvmpipe->list, &lp_screen->ctx_list);
+   mtx_unlock(&lp_screen->ctx_mutex);
    return &llvmpipe->pipe;
 
  fail:
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 1cabf98177f..a61c8e0a569 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -58,6 +58,7 @@ struct lp_velems_state;
 struct llvmpipe_context {
    struct pipe_context pipe;  /**< base class */
 
+   struct list_head list;
    /** Constant state objects */
    const struct pipe_blend_state *blend;
    struct pipe_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index c72944232e7..c49836432a9 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -111,10 +111,12 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
                         boolean do_not_block,
                         const char *reason)
 {
-   unsigned referenced;
-
-   referenced = llvmpipe_is_resource_referenced(pipe, resource, level);
-
+   unsigned referenced = 0;
+   struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
+   mtx_lock(&lp_screen->ctx_mutex);
+   list_for_each_entry(struct llvmpipe_context, ctx, &lp_screen->ctx_list, list)
+      referenced |= llvmpipe_is_resource_referenced((struct pipe_context *)ctx, resource, level);
+   mtx_unlock(&lp_screen->ctx_mutex);
    if ((referenced & LP_REFERENCED_FOR_WRITE) ||
        ((referenced & LP_REFERENCED_FOR_READ) && !read_only)) {
 
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 359c200279f..9c67d874c5f 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -1085,6 +1085,8 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
 
    snprintf(screen->renderer_string, sizeof(screen->renderer_string), "llvmpipe (LLVM " MESA_LLVM_VERSION_STRING ", %u bits)", lp_native_vector_width );
 
+   list_inithead(&screen->ctx_list);
+   (void) mtx_init(&screen->ctx_mutex, mtx_plain);
    (void) mtx_init(&screen->cs_mutex, mtx_plain);
    (void) mtx_init(&screen->rast_mutex, mtx_plain);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index c72bf838acb..18635c687bc 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -37,6 +37,7 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_defines.h"
 #include "os/os_thread.h"
+#include "util/list.h"
 #include "gallivm/lp_bld.h"
 #include "gallivm/lp_bld_misc.h"
 
@@ -67,6 +68,9 @@ struct llvmpipe_screen
    mtx_t late_mutex;
    bool late_init_done;
 
+   mtx_t ctx_mutex;
+   struct list_head ctx_list;
+
    char renderer_string[100];
 
    struct disk_cache *disk_shader_cache;
-- 
2.36.1

>From c4242bf0eee467fa822fa443bee5d4998ab03761 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@debian.org>
Date: Tue, 26 Jul 2022 00:06:43 +0100
Subject: [PATCH 3/3] llvmpipe: Add missing list.h

This seems to be necessary to backport mesa/mesa!17702 to 22.1.3.
---
 src/gallium/drivers/llvmpipe/lp_context.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index a61c8e0a569..4c28043220d 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -34,6 +34,7 @@
 #include "pipe/p_context.h"
 
 #include "draw/draw_vertex.h"
+#include "util/list.h"
 #include "util/u_blitter.h"
 
 #include "lp_tex_sample.h"
-- 
2.36.1


Reply to: