gallium: make pipe_sampler_view::reference non-atomic

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 <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34045>
This commit is contained in:
Mike Blumenkrantz 2025-03-13 06:47:15 -04:00 committed by Marge Bot
parent 91feef40db
commit 5ad5f1a93c
3 changed files with 38 additions and 7 deletions

View file

@ -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;
}

View file

@ -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,
};

View file

@ -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 */