Mesa (master): gallium,u_threaded: add pipe_draw_info::take_index_buffer_ownership
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jan 28 00:13:26 UTC 2021
Module: Mesa
Branch: master
Commit: e6da78e4ccf00ecd97ae83e799c20242f92b4c1b
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e6da78e4ccf00ecd97ae83e799c20242f92b4c1b
Author: Marek Olšák <marek.olsak at amd.com>
Date: Sat Jan 2 17:52:04 2021 -0500
gallium,u_threaded: add pipe_draw_info::take_index_buffer_ownership
to skip atomics in u_threaded_context. This will decrease CPU overhead.
Reviewed-by: Zoltán Böszörményi <zboszor at gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8298>
---
src/gallium/auxiliary/cso_cache/cso_context.c | 9 ++++++--
src/gallium/auxiliary/util/u_threaded_context.c | 10 ++++++---
src/gallium/auxiliary/util/u_vbuf.c | 29 ++++++++++++++++---------
src/gallium/include/pipe/p_state.h | 4 +++-
src/mesa/main/draw.c | 4 ++++
src/mesa/state_tracker/st_draw.c | 16 ++++++++++++++
src/mesa/state_tracker/st_draw_feedback.c | 1 +
7 files changed, 57 insertions(+), 16 deletions(-)
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index fc54dfc7be7..f10c61680e8 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -1435,9 +1435,14 @@ cso_multi_draw(struct cso_context *cso,
struct u_vbuf *vbuf = cso->vbuf_current;
if (vbuf) {
+ /* Increase refcount to be able to use take_index_buffer_ownership with
+ * all draws.
+ */
+ if (num_draws > 1 && info->take_index_buffer_ownership)
+ p_atomic_add(&info->index.resource->reference.count, num_draws - 1);
+
for (unsigned i = 0; i < num_draws; i++) {
- if (draws[i].count)
- u_vbuf_draw_vbo(vbuf, info, NULL, draws[i]);
+ u_vbuf_draw_vbo(vbuf, info, NULL, draws[i]);
if (info->increment_draw_id)
info->drawid++;
diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 187b6c367c3..39fbd23d413 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -100,6 +100,7 @@ simplify_draw_info(struct pipe_draw_info *info)
*/
info->has_user_indices = false;
info->index_bounds_valid = false;
+ info->take_index_buffer_ownership = false;
info->_pad = 0;
/* This shouldn't be set when merging single draws. */
@@ -2335,6 +2336,7 @@ tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
info->info.index_bounds_valid = false;
info->info.has_user_indices = false;
+ info->info.take_index_buffer_ownership = false;
pipe->draw_vbo(pipe, &info->info, NULL, draw, 1);
if (info->info.index_size)
@@ -2353,6 +2355,7 @@ tc_call_draw_indirect(struct pipe_context *pipe, union tc_payload *payload)
struct tc_draw_indirect *info = (struct tc_draw_indirect*)payload;
info->info.index_bounds_valid = false;
+ info->info.take_index_buffer_ownership = false;
pipe->draw_vbo(pipe, &info->info, &info->indirect, &info->draw, 1);
if (info->info.index_size)
@@ -2376,6 +2379,7 @@ tc_call_draw_multi(struct pipe_context *pipe, union tc_payload *payload)
info->info.has_user_indices = false;
info->info.index_bounds_valid = false;
+ info->info.take_index_buffer_ownership = false;
pipe->draw_vbo(pipe, &info->info, NULL, info->slot, info->num_draws);
if (info->info.index_size)
@@ -2404,7 +2408,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
struct tc_draw_indirect *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_indirect, tc_draw_indirect);
- if (index_size) {
+ if (index_size && !info->take_index_buffer_ownership) {
tc_set_resource_reference(&p->info.index.resource,
info->index.resource);
}
@@ -2452,7 +2456,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
/* Non-indexed call or indexed with a real index buffer. */
struct tc_draw_single *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_single, tc_draw_single);
- if (index_size) {
+ if (index_size && !info->take_index_buffer_ownership) {
tc_set_resource_reference(&p->info.index.resource,
info->index.resource);
}
@@ -2520,7 +2524,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
struct tc_draw_multi *p =
tc_add_slot_based_call(tc, TC_CALL_draw_multi, tc_draw_multi,
num_draws);
- if (index_size) {
+ if (index_size && !info->take_index_buffer_ownership) {
tc_set_resource_reference(&p->info.index.resource,
info->index.resource);
}
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index b51631f2cee..4775591abad 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -1278,6 +1278,12 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
unsigned *indirect_data, unsigned stride,
unsigned draw_count)
{
+ /* Increase refcount to be able to use take_index_buffer_ownership with
+ * all draws.
+ */
+ if (draw_count > 1 && info->take_index_buffer_ownership)
+ p_atomic_add(&info->index.resource->reference.count, draw_count - 1);
+
assert(info->index_size);
for (unsigned i = 0; i < draw_count; i++) {
@@ -1286,10 +1292,6 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
draw.count = indirect_data[offset + 0];
info->instance_count = indirect_data[offset + 1];
-
- if (!draw.count || !info->instance_count)
- continue;
-
draw.start = indirect_data[offset + 2];
info->index_bias = indirect_data[offset + 3];
info->start_instance = indirect_data[offset + 4];
@@ -1345,13 +1347,13 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
}
if (!draw_count)
- return;
+ goto cleanup;
unsigned data_size = (draw_count - 1) * indirect->stride +
(new_info.index_size ? 20 : 16);
unsigned *data = malloc(data_size);
if (!data)
- return; /* report an error? */
+ goto cleanup; /* report an error? */
/* Read the used buffer range only once, because the read can be
* uncached.
@@ -1449,7 +1451,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
new_info.instance_count = end_instance - new_info.start_instance;
if (new_info.start_instance == ~0u || !new_info.instance_count)
- return;
+ goto cleanup;
} else {
/* Non-indexed multidraw.
*
@@ -1486,7 +1488,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
new_info.instance_count = end_instance - new_info.start_instance;
if (new_draw.start == ~0u || !new_draw.count || !new_info.instance_count)
- return;
+ goto cleanup;
}
}
@@ -1540,7 +1542,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
start_vertex, num_vertices,
min_index, unroll_indices)) {
debug_warn_once("u_vbuf_translate_begin() failed");
- return;
+ goto cleanup;
}
if (unroll_indices) {
@@ -1562,7 +1564,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
new_info.start_instance,
new_info.instance_count) != PIPE_OK) {
debug_warn_once("u_vbuf_upload_buffers() failed");
- return;
+ goto cleanup;
}
mgr->dirty_real_vb_mask |= user_vb_mask;
@@ -1597,6 +1599,13 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);
}
+ return;
+
+cleanup:
+ if (info->take_index_buffer_ownership) {
+ struct pipe_resource *indexbuf = info->index.resource;
+ pipe_resource_reference(&indexbuf, NULL);
+ }
}
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr)
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 54dc20f2a70..c1bdf5efc6c 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -750,7 +750,9 @@ struct pipe_draw_info
bool index_bounds_valid:1; /**< whether min_index and max_index are valid;
they're always invalid if index_size == 0 */
bool increment_draw_id:1; /**< whether drawid increments for direct draws */
- char _pad:4; /**< padding for memcmp */
+ bool take_index_buffer_ownership:1; /**< callee inherits caller's refcount
+ (no need to reference indexbuf, but still needs to unreference it) */
+ char _pad:3; /**< padding for memcmp */
unsigned start_instance; /**< first instance id */
unsigned instance_count; /**< number of instances */
diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c
index 2438091ec5d..343b8439dc7 100644
--- a/src/mesa/main/draw.c
+++ b/src/mesa/main/draw.c
@@ -578,6 +578,7 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
info.has_user_indices = false;
info.index_bounds_valid = true;
info.increment_draw_id = false;
+ info.take_index_buffer_ownership = false;
info._pad = 0;
/* Packed section end. */
info.start_instance = baseInstance;
@@ -929,6 +930,7 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first,
info.has_user_indices = false;
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
+ info.take_index_buffer_ownership = false;
info._pad = 0;
/* Packed section end. */
info.start_instance = 0;
@@ -1064,6 +1066,7 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
info.has_user_indices = index_bo == NULL;
info.index_bounds_valid = index_bounds_valid;
info.increment_draw_id = false;
+ info.take_index_buffer_ownership = false;
info._pad = 0;
/* Packed section end. */
info.start_instance = baseInstance;
@@ -1521,6 +1524,7 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
info.has_user_indices = index_bo == NULL;
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
+ info.take_index_buffer_ownership = false;
info._pad = 0;
/* Packed section end. */
info.start_instance = 0;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index c95fbd411ad..be0ea865a83 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -158,6 +158,7 @@ st_draw_vbo(struct gl_context *ctx,
info.restart_index = 0;
info.start_instance = base_instance;
info.instance_count = num_instances;
+ info.take_index_buffer_ownership = false;
info._pad = 0;
if (ib) {
@@ -305,6 +306,11 @@ st_draw_gallium_complex(struct gl_context *ctx,
info->mode = mode[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
+
+ /* We can pass the reference only once. st_buffer_object keeps
+ * the reference alive for later draws.
+ */
+ info->take_index_buffer_ownership = false;
}
}
break;
@@ -315,6 +321,11 @@ st_draw_gallium_complex(struct gl_context *ctx,
info->index_bias = base_vertex[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
+
+ /* We can pass the reference only once. st_buffer_object keeps
+ * the reference alive for later draws.
+ */
+ info->take_index_buffer_ownership = false;
}
}
break;
@@ -328,6 +339,11 @@ st_draw_gallium_complex(struct gl_context *ctx,
info->index_bias = base_vertex[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
+
+ /* We can pass the reference only once. st_buffer_object keeps
+ * the reference alive for later draws.
+ */
+ info->take_index_buffer_ownership = false;
}
}
break;
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 206fa410bdc..3900c1644dd 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -124,6 +124,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
/* Initialize pipe_draw_info. */
info.primitive_restart = false;
+ info.take_index_buffer_ownership = false;
info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
info.restart_index = 0;
More information about the mesa-commit
mailing list