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@gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8298>
This commit is contained in:
Marek Olšák 2021-01-02 17:52:04 -05:00 committed by Marge Bot
parent 104a41bd07
commit e6da78e4cc
7 changed files with 57 additions and 16 deletions

View file

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

View file

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

View file

@ -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)

View file

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

View file

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

View file

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

View file

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