Mesa (main): llvmpipe: unmap display target of shader image/sampler

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 9 16:17:35 UTC 2021


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

Author: Heinrich Fink <hfink at snap.com>
Date:   Wed Jun 30 13:28:17 2021 +0200

llvmpipe: unmap display target of shader image/sampler

Revive hooks for cleaning up shader sampler and image data and when
finalizing llvmpipe_draw_vbo. In cleanup routines, for any sampler or
image that was set up with displaytarget_map, call displaytarget_unmap.

This fixes leaks of mmap calls of the underlying displaytarget
resources.

v2 (Daniel Stone):
    - Use a single cleanup function for sampler/image to simplify patchset

v3 (Emil Velikov):
    - use llvmpipe_resource_[un]map instead of open-coding through
    winsys

v4:
    - check tex/image for NULL before calling into
    llvmpipe_resource_unmap (fixes dEQP crash of llvmpipe runner)

Signed-off-by: Heinrich Fink <hfink at snap.com>
Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11741>

---

 src/gallium/drivers/llvmpipe/lp_draw_arrays.c   | 10 ++++
 src/gallium/drivers/llvmpipe/lp_state.h         |  7 +++
 src/gallium/drivers/llvmpipe/lp_state_sampler.c | 64 +++++++++++++++++++------
 3 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index a5c5f606ddd..33ab84f9507 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -166,6 +166,16 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
       }
    }
 
+   llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_VERTEX);
+   llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_GEOMETRY);
+   llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_TESS_CTRL);
+   llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_TESS_EVAL);
+
+   llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_VERTEX);
+   llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_GEOMETRY);
+   llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_TESS_CTRL);
+   llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_TESS_EVAL);
+
    /*
     * TODO: Flush only when a user vertex/index buffer is present
     * (or even better, modify draw module to do this
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index ccb5af2eb5e..6887d98487d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -174,6 +174,9 @@ void
 llvmpipe_prepare_tess_eval_sampling(struct llvmpipe_context *ctx,
                                     unsigned num,
                                     struct pipe_sampler_view **views);
+void
+llvmpipe_cleanup_stage_sampling(struct llvmpipe_context *ctx,
+                                enum pipe_shader_type stage);
 
 void
 llvmpipe_prepare_vertex_images(struct llvmpipe_context *lp,
@@ -195,4 +198,8 @@ llvmpipe_prepare_tess_eval_images(struct llvmpipe_context *lp,
                                   unsigned num,
                                   struct pipe_image_view *views);
 
+void
+llvmpipe_cleanup_stage_images(struct llvmpipe_context *ctx,
+                              enum pipe_shader_type stage);
+
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 613e5286a2a..c631d1148e7 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -341,13 +341,7 @@ prepare_shader_sampling(
          }
          else {
             /* display target texture/surface */
-            /*
-             * XXX: Where should this be unmapped?
-             */
-            struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
-            struct sw_winsys *winsys = screen->winsys;
-            addr = winsys->displaytarget_map(winsys, lp_tex->dt,
-                                                PIPE_MAP_READ);
+            addr = llvmpipe_resource_map(tex, 0, 0, LP_TEX_USAGE_READ);
             row_stride[0] = lp_tex->row_stride[0];
             img_stride[0] = lp_tex->img_stride[0];
             mip_offsets[0] = 0;
@@ -411,6 +405,30 @@ llvmpipe_prepare_tess_eval_sampling(struct llvmpipe_context *lp,
    prepare_shader_sampling(lp, num, views, PIPE_SHADER_TESS_EVAL);
 }
 
+void
+llvmpipe_cleanup_stage_sampling(struct llvmpipe_context *ctx,
+                                enum pipe_shader_type stage)
+{
+   unsigned num, i;
+   struct pipe_sampler_view **views;
+   assert(ctx);
+   assert(stage < ARRAY_SIZE(ctx->num_sampler_views));
+   assert(stage < ARRAY_SIZE(ctx->sampler_views));
+
+   num = ctx->num_sampler_views[stage];
+   views = ctx->sampler_views[stage];
+
+   assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
+
+   for (i = 0; i < num; i++) {
+      struct pipe_sampler_view *view = views[i];
+      assert(view);
+      struct pipe_resource *tex = view->texture;
+      if (tex)
+         llvmpipe_resource_unmap(tex, 0, 0);
+   }
+}
+
 static void
 prepare_shader_images(
    struct llvmpipe_context *lp,
@@ -482,13 +500,7 @@ prepare_shader_images(
          }
          else {
             /* display target texture/surface */
-            /*
-             * XXX: Where should this be unmapped?
-             */
-            struct llvmpipe_screen *screen = llvmpipe_screen(img->screen);
-            struct sw_winsys *winsys = screen->winsys;
-            addr = winsys->displaytarget_map(winsys, lp_img->dt,
-                                                PIPE_MAP_READ);
+            addr = llvmpipe_resource_map(img, 0, 0, LP_TEX_USAGE_READ);
             row_stride = lp_img->row_stride[0];
             img_stride = lp_img->img_stride[0];
             sample_stride = 0;
@@ -551,6 +563,30 @@ llvmpipe_prepare_tess_eval_images(struct llvmpipe_context *lp,
    prepare_shader_images(lp, num, views, PIPE_SHADER_TESS_EVAL);
 }
 
+void
+llvmpipe_cleanup_stage_images(struct llvmpipe_context *ctx,
+                              enum pipe_shader_type stage)
+{
+   unsigned num, i;
+   struct pipe_image_view *views;
+   assert(ctx);
+   assert(stage < ARRAY_SIZE(ctx->num_images));
+   assert(stage < ARRAY_SIZE(ctx->images));
+
+   num = ctx->num_images[stage];
+   views = ctx->images[stage];
+
+   assert(num <= LP_MAX_TGSI_SHADER_IMAGES);
+
+   for (i = 0; i < num; i++) {
+      struct pipe_image_view *view = &views[i];
+      assert(view);
+      struct pipe_resource *img = view->resource;
+      if (img)
+         llvmpipe_resource_unmap(img, 0, 0);
+   }
+}
+
 void
 llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
 {



More information about the mesa-commit mailing list