From: Marek Olšák Date: Sat, 2 Jan 2021 22:52:04 +0000 (-0500) Subject: gallium,u_threaded: add pipe_draw_info::take_index_buffer_ownership X-Git-Tag: upstream/21.2.3~8854 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6da78e4ccf00ecd97ae83e799c20242f92b4c1b;p=platform%2Fupstream%2Fmesa.git 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 Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index fc54dfc..f10c616 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 187b6c3..39fbd23 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 b51631f..4775591 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 54dc20f..c1bdf5e 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 2438091..343b843 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 c95fbd4..be0ea86 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 206fa41..3900c16 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;