Mesa (main): st/mesa: add a mechanism to bypass atomics when binding sampler views

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jun 27 13:07:33 UTC 2021


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

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sun Jun  6 06:08:07 2021 -0400

st/mesa: add a mechanism to bypass atomics when binding sampler views

This is the same mechanism we already use for buffers. The code is mostly
copied from there. See the big comment for explanation.

This will be very effective when take_ownership is added into pipe_context
::set_sampler_views because that and this commit together will eliminate
atomics for sample views almost entirely.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11428>

---

 src/mesa/state_tracker/st_sampler_view.c | 36 ++++++++++++++++++++++++++------
 src/mesa/state_tracker/st_texture.h      | 18 ++++++++++++++++
 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c
index 8a41eafd2fd..e4add1bd2c6 100644
--- a/src/mesa/state_tracker/st_sampler_view.c
+++ b/src/mesa/state_tracker/st_sampler_view.c
@@ -41,15 +41,35 @@
 #include "st_cb_bufferobjects.h"
 #include "st_cb_texture.h"
 
+/* Subtract remaining private references. Typically used before
+ * destruction. See the header file for explanation.
+ */
+static void
+st_remove_private_references(struct st_sampler_view *sv)
+{
+   if (sv->private_refcount) {
+      assert(sv->private_refcount > 0);
+      p_atomic_add(&sv->view->reference.count, -sv->private_refcount);
+      sv->private_refcount = 0;
+   }
+}
+
 /* Return a sampler view while incrementing the refcount by 1. */
 static struct pipe_sampler_view *
 get_sampler_view_reference(struct st_sampler_view *sv,
                            struct pipe_sampler_view *view)
 {
-   struct pipe_sampler_view *ret = NULL;
+   if (unlikely(sv->private_refcount <= 0)) {
+      assert(sv->private_refcount == 0);
 
-   pipe_sampler_view_reference(&ret, view);
-   return ret;
+      /* This is the number of atomic increments we will skip. */
+      sv->private_refcount = 100000000;
+      p_atomic_add(&view->reference.count, sv->private_refcount);
+   }
+
+   /* Return a reference while decrementing the private refcount. */
+   sv->private_refcount--;
+   return view;
 }
 
 /**
@@ -85,6 +105,7 @@ st_texture_set_sampler_view(struct st_context *st,
       if (sv->view) {
          /* check if the context matches */
          if (sv->view->context == st->pipe) {
+            st_remove_private_references(sv);
             pipe_sampler_view_reference(&sv->view, NULL);
             goto found;
          }
@@ -208,10 +229,11 @@ st_texture_release_context_sampler_view(struct st_context *st,
    simple_mtx_lock(&stObj->validate_mutex);
    struct st_sampler_views *views = stObj->sampler_views;
    for (i = 0; i < views->count; ++i) {
-      struct pipe_sampler_view **sv = &views->views[i].view;
+      struct st_sampler_view *sv = &views->views[i];
 
-      if (*sv && (*sv)->context == st->pipe) {
-         pipe_sampler_view_reference(sv, NULL);
+      if (sv->view && sv->view->context == st->pipe) {
+         st_remove_private_references(sv);
+         pipe_sampler_view_reference(&sv->view, NULL);
          break;
       }
    }
@@ -240,6 +262,8 @@ st_texture_release_all_sampler_views(struct st_context *st,
    for (unsigned i = 0; i < views->count; ++i) {
       struct st_sampler_view *stsv = &views->views[i];
       if (stsv->view) {
+         st_remove_private_references(stsv);
+
          if (stsv->st && stsv->st != st) {
             /* Transfer this reference to the zombie list.  It will
              * likely be freed when the zombie list is freed.
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 9bf0661c8c1..824ef4b14d0 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -64,6 +64,24 @@ struct st_sampler_view
    bool glsl130_or_later;
    /** Derived from the sampler's sRGBDecode state during validation */
    bool srgb_skip_decode;
+
+   /* This mechanism allows passing sampler view references to the driver
+    * without using atomics to increase the reference count.
+    *
+    * This private refcount can be decremented without atomics but only one
+    * context (st above) can use this counter (so that it's only used by
+    * 1 thread).
+    *
+    * This number is atomically added to view->reference.count at
+    * initialization. If it's never used, the same number is atomically
+    * subtracted from view->reference.count before destruction. If this
+    * number is decremented, we can pass one reference to the driver without
+    * touching reference.count with atomics. At destruction we only subtract
+    * the number of references we have not returned. This can possibly turn
+    * a million atomic increments into 1 add and 1 subtract atomic op over
+    * the whole lifetime of an app.
+    */
+   int private_refcount;
 };
 
 



More information about the mesa-commit mailing list