From eb0fa78b686b144882ee0f773b814ca3b7bb7768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 13 Jun 2021 12:13:50 -0400 Subject: [PATCH] gallium/u_threaded: merge draws faster by merging indexbuf unreferencing Instead of N times decrementing the index buffer refcount by 1, decrement it by N once. Reviewed-by: Rob Clark Reviewed-By: Mike Blumenkrantz Part-of: --- src/gallium/auxiliary/util/u_inlines.h | 14 ++++++++++++++ src/gallium/auxiliary/util/u_threaded_context.c | 10 +++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index a8d79a2a79b..958b117ddc3 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -163,6 +163,20 @@ pipe_resource_reference(struct pipe_resource **dst, struct pipe_resource *src) *dst = src; } +/** + * Subtract the given number of references. + */ +static inline void +pipe_drop_resource_references(struct pipe_resource *dst, int num_refs) +{ + int count = p_atomic_add_return(&dst->reference.count, -num_refs); + + assert(count >= 0); + /* Underflows shouldn't happen, but let's be safe. */ + if (count <= 0) + pipe_resource_destroy(dst); +} + /** * Same as pipe_surface_release, but used when pipe_context doesn't exist * anymore. diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index b77929ad5a3..a8c712a4370 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -2969,9 +2969,6 @@ tc_call_draw_single(struct pipe_context *pipe, void *call, uint64_t *last_ptr) multi[1].count = next->info.max_index; multi[1].index_bias = next->index_bias; - if (next->info.index_size) - tc_drop_resource_reference(next->info.index.resource); - /* Find how many other draws can be merged. */ next = get_next_call(next, tc_draw_single); for (; next != last && is_next_call_a_mergeable_draw(first, next); @@ -2981,15 +2978,14 @@ tc_call_draw_single(struct pipe_context *pipe, void *call, uint64_t *last_ptr) multi[num_draws].count = next->info.max_index; multi[num_draws].index_bias = next->index_bias; index_bias_varies |= first->index_bias != next->index_bias; - - if (next->info.index_size) - tc_drop_resource_reference(next->info.index.resource); } first->info.index_bias_varies = index_bias_varies; pipe->draw_vbo(pipe, &first->info, 0, NULL, multi, num_draws); + + /* Since all draws use the same index buffer, drop all references at once. */ if (first->info.index_size) - tc_drop_resource_reference(first->info.index.resource); + pipe_drop_resource_references(first->info.index.resource, num_draws); return call_size(tc_draw_single) * num_draws; }