Mesa (main): aux/tc: pass rebind count and rebind bitmask with replace_buffer_storage func

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jun 14 21:06:26 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Jun  2 15:43:43 2021 -0400

aux/tc: pass rebind count and rebind bitmask with replace_buffer_storage func

tc already calculates all the rebinding that needs to be done on a given
context, so (some of) this info can be passed on to drivers to enable
optimizations

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11245>

---

 src/gallium/auxiliary/driver_trace/tr_screen.c     |  6 +-
 src/gallium/auxiliary/util/u_threaded_context.c    | 93 +++++++++++++---------
 src/gallium/auxiliary/util/u_threaded_context.h    | 31 ++++++++
 src/gallium/drivers/freedreno/freedreno_resource.c |  3 +-
 src/gallium/drivers/freedreno/freedreno_resource.h |  2 +
 src/gallium/drivers/iris/iris_resource.c           |  2 +
 src/gallium/drivers/iris/iris_resource.h           |  2 +
 src/gallium/drivers/radeonsi/si_buffer.c           |  3 +-
 src/gallium/drivers/radeonsi/si_pipe.h             |  3 +-
 src/gallium/drivers/radeonsi/si_texture.c          |  2 +-
 src/gallium/drivers/zink/zink_context.c            |  3 +-
 11 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c
index b8517606fb8..eb2618bfcf9 100644
--- a/src/gallium/auxiliary/driver_trace/tr_screen.c
+++ b/src/gallium/auxiliary/driver_trace/tr_screen.c
@@ -268,6 +268,8 @@ static void
 trace_context_replace_buffer_storage(struct pipe_context *_pipe,
                                      struct pipe_resource *dst,
                                      struct pipe_resource *src,
+                                     unsigned num_rebinds,
+                                     uint32_t rebind_mask,
                                      unsigned delete_buffer_id)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
@@ -278,10 +280,12 @@ trace_context_replace_buffer_storage(struct pipe_context *_pipe,
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, dst);
    trace_dump_arg(ptr, src);
+   trace_dump_arg(uint, num_rebinds);
+   trace_dump_arg(uint, rebind_mask);
    trace_dump_arg(uint, delete_buffer_id);
    trace_dump_call_end();
 
-   tr_ctx->replace_buffer_storage(pipe, dst, src, delete_buffer_id);
+   tr_ctx->replace_buffer_storage(pipe, dst, src, num_rebinds, rebind_mask, delete_buffer_id);
 }
 
 static struct pipe_fence_handle *
diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 0351c9a0b10..3cb14d3565e 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -430,15 +430,15 @@ static bool
 tc_rebind_bindings(uint32_t old_id, uint32_t new_id, uint32_t *bindings,
                    unsigned count)
 {
-   bool rebound = false;
+   unsigned rebind_count = 0;
 
    for (unsigned i = 0; i < count; i++) {
       if (bindings[i] == old_id) {
          bindings[i] = new_id;
-         rebound = true;
+         rebind_count++;
       }
    }
-   return rebound;
+   return rebind_count;
 }
 
 static void
@@ -462,27 +462,35 @@ tc_add_shader_bindings_to_buffer_list(struct threaded_context *tc,
    }
 }
 
-static bool
+static unsigned
 tc_rebind_shader_bindings(struct threaded_context *tc, uint32_t old_id,
-                          uint32_t new_id, enum pipe_shader_type shader)
+                          uint32_t new_id, enum pipe_shader_type shader, uint32_t *rebind_mask)
 {
-   bool rebound = false;
+   unsigned ubo = 0, ssbo = 0, img = 0, sampler = 0;
 
-   rebound |= tc_rebind_bindings(old_id, new_id, tc->const_buffers[shader],
-                                 tc->max_const_buffers);
+   ubo = tc_rebind_bindings(old_id, new_id, tc->const_buffers[shader],
+                            tc->max_const_buffers);
+   if (ubo)
+      *rebind_mask |= BITFIELD_BIT(TC_BINDING_UBO_VS) << shader;
    if (tc->seen_shader_buffers[shader]) {
-      rebound |= tc_rebind_bindings(old_id, new_id, tc->shader_buffers[shader],
-                                    tc->max_shader_buffers);
+      ssbo = tc_rebind_bindings(old_id, new_id, tc->shader_buffers[shader],
+                                tc->max_shader_buffers);
+      if (ssbo)
+         *rebind_mask |= BITFIELD_BIT(TC_BINDING_SSBO_VS) << shader;
    }
    if (tc->seen_image_buffers[shader]) {
-      rebound |= tc_rebind_bindings(old_id, new_id, tc->image_buffers[shader],
-                                    tc->max_images);
+      img = tc_rebind_bindings(old_id, new_id, tc->image_buffers[shader],
+                               tc->max_images);
+      if (img)
+         *rebind_mask |= BITFIELD_BIT(TC_BINDING_IMAGE_VS) << shader;
    }
    if (tc->seen_sampler_buffers[shader]) {
-      rebound |= tc_rebind_bindings(old_id, new_id, tc->sampler_buffers[shader],
-                                    tc->max_samplers);
+      sampler = tc_rebind_bindings(old_id, new_id, tc->sampler_buffers[shader],
+                                   tc->max_samplers);
+      if (sampler)
+         *rebind_mask |= BITFIELD_BIT(TC_BINDING_SAMPLERVIEW_VS) << shader;
    }
-   return rebound;
+   return ubo + ssbo + img + sampler;
 }
 
 /* Add all bound buffers used by VS/TCS/TES/GS/FS to the buffer list.
@@ -524,32 +532,39 @@ tc_add_all_compute_bindings_to_buffer_list(struct threaded_context *tc)
    tc->add_all_compute_bindings_to_buffer_list = false;
 }
 
-static void
-tc_rebind_buffer(struct threaded_context *tc, uint32_t old_id, uint32_t new_id)
+static unsigned
+tc_rebind_buffer(struct threaded_context *tc, uint32_t old_id, uint32_t new_id, uint32_t *rebind_mask)
 {
-   bool rebound = false;
+   unsigned vbo = 0, so = 0;
+
+   vbo = tc_rebind_bindings(old_id, new_id, tc->vertex_buffers,
+                            tc->max_vertex_buffers);
+   if (vbo)
+      *rebind_mask |= BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER);
 
-   rebound |= tc_rebind_bindings(old_id, new_id, tc->vertex_buffers,
-                                 tc->max_vertex_buffers);
    if (tc->seen_streamout_buffers) {
-      rebound |= tc_rebind_bindings(old_id, new_id, tc->streamout_buffers,
-                                    PIPE_MAX_SO_BUFFERS);
+      so = tc_rebind_bindings(old_id, new_id, tc->streamout_buffers,
+                              PIPE_MAX_SO_BUFFERS);
+      if (so)
+         *rebind_mask |= BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER);
    }
+   unsigned rebound = vbo + so;
 
-   rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_VERTEX);
-   rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_FRAGMENT);
+   rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_VERTEX, rebind_mask);
+   rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_FRAGMENT, rebind_mask);
 
    if (tc->seen_tcs)
-      rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_CTRL);
+      rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_CTRL, rebind_mask);
    if (tc->seen_tes)
-      rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_EVAL);
+      rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_EVAL, rebind_mask);
    if (tc->seen_gs)
-      rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_GEOMETRY);
+      rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_GEOMETRY, rebind_mask);
 
-   rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_COMPUTE);
+   rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_COMPUTE, rebind_mask);
 
    if (rebound)
       BITSET_SET(tc->buffer_lists[tc->next_buf_list].buffer_list, new_id & TC_BUFFER_ID_MASK);
+   return rebound;
 }
 
 static bool
@@ -1813,6 +1828,8 @@ tc_make_image_handle_resident(struct pipe_context *_pipe, uint64_t handle,
 
 struct tc_replace_buffer_storage {
    struct tc_call_base base;
+   uint16_t num_rebinds;
+   uint32_t rebind_mask;
    uint32_t delete_buffer_id;
    struct pipe_resource *dst;
    struct pipe_resource *src;
@@ -1824,7 +1841,7 @@ tc_call_replace_buffer_storage(struct pipe_context *pipe, void *call, uint64_t *
 {
    struct tc_replace_buffer_storage *p = to_call(call, tc_replace_buffer_storage);
 
-   p->func(pipe, p->dst, p->src, p->delete_buffer_id);
+   p->func(pipe, p->dst, p->src, p->num_rebinds, p->rebind_mask, p->delete_buffer_id);
 
    tc_drop_resource_reference(p->dst);
    tc_drop_resource_reference(p->src);
@@ -1859,14 +1876,7 @@ tc_invalidate_buffer(struct threaded_context *tc,
 
    tbuf->latest = new_buf;
 
-   /* Treat the current buffer as the new buffer. */
-   tc_rebind_buffer(tc, tbuf->buffer_id_unique,
-                    threaded_resource(new_buf)->buffer_id_unique);
-   util_range_set_empty(&tbuf->valid_buffer_range);
-
    uint32_t delete_buffer_id = tbuf->buffer_id_unique;
-   tbuf->buffer_id_unique = threaded_resource(new_buf)->buffer_id_unique;
-   threaded_resource(new_buf)->buffer_id_unique = 0;
 
    /* Enqueue storage replacement of the original buffer. */
    struct tc_replace_buffer_storage *p =
@@ -1877,6 +1887,17 @@ tc_invalidate_buffer(struct threaded_context *tc,
    tc_set_resource_reference(&p->dst, &tbuf->b);
    tc_set_resource_reference(&p->src, new_buf);
    p->delete_buffer_id = delete_buffer_id;
+   p->rebind_mask = 0;
+
+   /* Treat the current buffer as the new buffer. */
+   p->num_rebinds = tc_rebind_buffer(tc, tbuf->buffer_id_unique,
+                                     threaded_resource(new_buf)->buffer_id_unique,
+                                     &p->rebind_mask);
+   util_range_set_empty(&tbuf->valid_buffer_range);
+
+   tbuf->buffer_id_unique = threaded_resource(new_buf)->buffer_id_unique;
+   threaded_resource(new_buf)->buffer_id_unique = 0;
+
    return true;
 }
 
diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h
index 7da11b07351..565236a0b01 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.h
+++ b/src/gallium/auxiliary/util/u_threaded_context.h
@@ -258,9 +258,40 @@ struct tc_unflushed_batch_token;
  */
 #define TC_MAX_SUBDATA_BYTES        320
 
+enum tc_binding_type {
+   TC_BINDING_VERTEX_BUFFER,
+   TC_BINDING_STREAMOUT_BUFFER,
+   TC_BINDING_UBO_VS,
+   TC_BINDING_UBO_FS,
+   TC_BINDING_UBO_GS,
+   TC_BINDING_UBO_TCS,
+   TC_BINDING_UBO_TES,
+   TC_BINDING_UBO_CS,
+   TC_BINDING_SAMPLERVIEW_VS,
+   TC_BINDING_SAMPLERVIEW_FS,
+   TC_BINDING_SAMPLERVIEW_GS,
+   TC_BINDING_SAMPLERVIEW_TCS,
+   TC_BINDING_SAMPLERVIEW_TES,
+   TC_BINDING_SAMPLERVIEW_CS,
+   TC_BINDING_SSBO_VS,
+   TC_BINDING_SSBO_FS,
+   TC_BINDING_SSBO_GS,
+   TC_BINDING_SSBO_TCS,
+   TC_BINDING_SSBO_TES,
+   TC_BINDING_SSBO_CS,
+   TC_BINDING_IMAGE_VS,
+   TC_BINDING_IMAGE_FS,
+   TC_BINDING_IMAGE_GS,
+   TC_BINDING_IMAGE_TCS,
+   TC_BINDING_IMAGE_TES,
+   TC_BINDING_IMAGE_CS,
+};
+
 typedef void (*tc_replace_buffer_storage_func)(struct pipe_context *ctx,
                                                struct pipe_resource *dst,
                                                struct pipe_resource *src,
+                                               unsigned num_rebinds,
+                                               uint32_t rebind_mask,
                                                uint32_t delete_buffer_id);
 typedef struct pipe_fence_handle *(*tc_create_fence_func)(struct pipe_context *ctx,
                                                           struct tc_unflushed_batch_token *token);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 39766630029..92b349e36d5 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -248,7 +248,8 @@ do_blit(struct fd_context *ctx, const struct pipe_blit_info *blit,
  */
 void
 fd_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *pdst,
-                          struct pipe_resource *psrc, uint32_t delete_buffer_id)
+                          struct pipe_resource *psrc, unsigned num_rebinds, uint32_t rebind_mask,
+                          uint32_t delete_buffer_id)
 {
    struct fd_context *ctx = fd_context(pctx);
    struct fd_resource *dst = fd_resource(pdst);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 5047417cdd6..e4939d199f1 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -345,6 +345,8 @@ void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz);
 void fd_replace_buffer_storage(struct pipe_context *ctx,
                                struct pipe_resource *dst,
                                struct pipe_resource *src,
+                               unsigned num_rebinds,
+                               uint32_t rebind_mask,
                                uint32_t delete_buffer_id) in_dt;
 bool fd_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *prsc,
                       unsigned usage);
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index f4bdc59d25a..d60a95529f9 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -1481,6 +1481,8 @@ void
 iris_replace_buffer_storage(struct pipe_context *ctx,
                             struct pipe_resource *p_dst,
                             struct pipe_resource *p_src,
+                            unsigned num_rebinds,
+                            uint32_t rebind_mask,
                             uint32_t delete_buffer_id)
 {
    struct iris_screen *screen = (void *) ctx->screen;
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index a313666a07e..90105c40d55 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -330,6 +330,8 @@ iris_resource_get_clear_color(const struct iris_resource *res,
 void iris_replace_buffer_storage(struct pipe_context *ctx,
                                  struct pipe_resource *dst,
                                  struct pipe_resource *src,
+                                 unsigned num_rebinds,
+                                 uint32_t rebind_mask,
                                  uint32_t delete_buffer_id);
 
 
diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c
index 7396234c994..c62ddcc7e99 100644
--- a/src/gallium/drivers/radeonsi/si_buffer.c
+++ b/src/gallium/drivers/radeonsi/si_buffer.c
@@ -285,7 +285,8 @@ static bool si_invalidate_buffer(struct si_context *sctx, struct si_resource *bu
 
 /* Replace the storage of dst with src. */
 void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst,
-                               struct pipe_resource *src, uint32_t delete_buffer_id)
+                               struct pipe_resource *src, unsigned num_rebinds, uint32_t rebind_mask,
+                               uint32_t delete_buffer_id)
 {
    struct si_context *sctx = (struct si_context *)ctx;
    struct si_resource *sdst = si_resource(dst);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 8bf45fb2bf4..728b92e2a71 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -1335,7 +1335,8 @@ struct pipe_resource *pipe_aligned_buffer_create(struct pipe_screen *screen, uns
 struct si_resource *si_aligned_buffer_create(struct pipe_screen *screen, unsigned flags,
                                              unsigned usage, unsigned size, unsigned alignment);
 void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst,
-                               struct pipe_resource *src, uint32_t delete_buffer_id);
+                               struct pipe_resource *src, unsigned num_rebinds,
+                               uint32_t rebind_mask, uint32_t delete_buffer_id);
 void si_init_screen_buffer_functions(struct si_screen *sscreen);
 void si_init_buffer_functions(struct si_context *sctx);
 
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 6e23c1b828a..7d916cfcde9 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -749,7 +749,7 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
          sctx->b.resource_copy_region(&sctx->b, newb, 0, 0, 0, 0, &res->b.b, 0, &box);
          flush = true;
          /* Move the new buffer storage to the old pipe_resource. */
-         si_replace_buffer_storage(&sctx->b, &res->b.b, newb, 0);
+         si_replace_buffer_storage(&sctx->b, &res->b.b, newb, 0, 0, 0);
          pipe_resource_reference(&newb, NULL);
 
          assert(res->b.b.bind & PIPE_BIND_SHARED);
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 62159a5a84e..f4b9706e454 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3255,7 +3255,8 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
 
 static void
 zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *dst,
-                                    struct pipe_resource *src, uint32_t delete_buffer_id)
+                                    struct pipe_resource *src, unsigned num_rebinds,
+                                    uint32_t rebind_mask, uint32_t delete_buffer_id)
 {
    struct zink_resource *d = zink_resource(dst);
    struct zink_resource *s = zink_resource(src);



More information about the mesa-commit mailing list