From 5ad5f1a93c768b9c02eaed547bc49e549fb778aa Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 13 Mar 2025 06:47:15 -0400 Subject: [PATCH] gallium: make pipe_sampler_view::reference non-atomic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this object is per-context with refcounting performed exclusively in-driver, so there is no longer a danger of false sharing Reviewed-by: Marek Olšák Part-of: --- src/gallium/auxiliary/util/u_inlines.h | 39 +++++++++++++++++-- .../frontends/rusticl/mesa/pipe/resource.rs | 2 +- src/gallium/include/pipe/p_state.h | 4 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index d45eab0eb1f..3319541724b 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -96,6 +96,37 @@ pipe_reference_described(struct pipe_reference *dst, return false; } +/** + * Update reference counting. + * The old thing pointed to, if any, will be unreferenced. + * Both 'dst' and 'src' may be NULL. + * \return TRUE if the object's refcount hits zero and should be destroyed. + */ +static inline bool +pipe_reference_described_nonatomic(struct pipe_reference *dst, + struct pipe_reference *src, + debug_reference_descriptor get_desc) +{ + if (dst != src) { + /* bump the src.count first */ + if (src) { + ASSERTED int64_t count = ++src->count; + assert(count != 1); /* src had to be referenced */ + debug_reference(src, get_desc, 1); + } + + if (dst) { + int64_t count = --dst->count; + assert(count != -1); /* dst had to be referenced */ + debug_reference(dst, get_desc, -1); + if (!count) + return true; + } + } + + return false; +} + static inline bool pipe_reference(struct pipe_reference *dst, struct pipe_reference *src) { @@ -210,10 +241,10 @@ pipe_sampler_view_reference(struct pipe_sampler_view **dst, { struct pipe_sampler_view *old_dst = *dst; - if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, - src ? &src->reference : NULL, - (debug_reference_descriptor) - debug_describe_sampler_view)) + if (pipe_reference_described_nonatomic(old_dst ? &old_dst->reference : NULL, + src ? &src->reference : NULL, + (debug_reference_descriptor) + debug_describe_sampler_view)) old_dst->context->sampler_view_destroy(old_dst->context, old_dst); *dst = src; } diff --git a/src/gallium/frontends/rusticl/mesa/pipe/resource.rs b/src/gallium/frontends/rusticl/mesa/pipe/resource.rs index 33bbb96a80f..a6841a7f2cc 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/resource.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/resource.rs @@ -237,7 +237,7 @@ impl PipeResource { // write the entire union field because u_sampler_view_default_template might have left it // in an undefined state. - res.u.buf = pipe_sampler_view__bindgen_ty_2__bindgen_ty_2 { + res.u.buf = pipe_sampler_view__bindgen_ty_1__bindgen_ty_2 { offset: 0, size: size, }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 7dde135b526..4937df62e40 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -498,8 +498,8 @@ struct pipe_tex2d_from_buf { */ struct pipe_sampler_view { - /* Put the refcount on its own cache line to prevent "False sharing". */ - EXCLUSIVE_CACHELINE(struct pipe_reference reference); + /* this refcount is non-atomic */ + struct pipe_reference reference; enum pipe_format format:12; /**< typed PIPE_FORMAT_x */ unsigned astc_decode_format:2; /**< intermediate format used for ASTC textures */