gallium/u_threaded: clean up direct vs indirect draws

It's called draw_single because multi draws will use a different structure.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7441>
This commit is contained in:
Marek Olšák
2020-11-01 08:38:50 -05:00
committed by Marge Bot
parent d5b37dd3c2
commit 920bbfb3a0
2 changed files with 56 additions and 63 deletions

View File

@@ -62,9 +62,8 @@ enum tc_call_id {
/* This is actually variable-sized, because indirect isn't allocated if it's
* not needed. */
struct tc_full_draw_info {
struct pipe_draw_info draw;
struct pipe_draw_indirect_info indirect;
struct tc_draw_single {
struct pipe_draw_info info;
};
typedef void (*tc_execute)(struct pipe_context *pipe, union tc_payload *payload);
@@ -88,15 +87,15 @@ tc_debug_check(struct threaded_context *tc)
}
static bool
is_next_call_a_mergeable_draw(struct tc_full_draw_info *first_info,
is_next_call_a_mergeable_draw(struct tc_draw_single *first_info,
struct tc_call *next,
struct tc_full_draw_info **next_info)
struct tc_draw_single **next_info)
{
return next->call_id == TC_CALL_draw_vbo &&
(*next_info = (struct tc_full_draw_info*)&next->payload) &&
return next->call_id == TC_CALL_draw_single &&
(*next_info = (struct tc_draw_single*)&next->payload) &&
/* All fields must be the same except start and count. */
memcmp((uint32_t*)&first_info->draw + 2,
(uint32_t*)&(*next_info)->draw + 2,
memcmp((uint32_t*)&first_info->info + 2,
(uint32_t*)&(*next_info)->info + 2,
sizeof(struct pipe_draw_info) - 8) == 0;
}
@@ -115,44 +114,44 @@ tc_batch_execute(void *job, UNUSED int thread_index)
tc_assert(iter->sentinel == TC_SENTINEL);
/* Draw call merging. */
if (iter->call_id == TC_CALL_draw_vbo) {
if (iter->call_id == TC_CALL_draw_single) {
struct tc_call *first = iter;
struct tc_call *next = first + first->num_call_slots;
struct tc_full_draw_info *first_info =
(struct tc_full_draw_info*)&first->payload;
struct tc_full_draw_info *next_info;
struct tc_draw_single *first_info =
(struct tc_draw_single*)&first->payload;
struct tc_draw_single *next_info;
/* If at least 2 consecutive draw calls can be merged... */
if (next != last && next->call_id == TC_CALL_draw_vbo &&
first_info->draw.drawid == 0 &&
if (next != last && next->call_id == TC_CALL_draw_single &&
first_info->info.drawid == 0 &&
is_next_call_a_mergeable_draw(first_info, next, &next_info)) {
/* Merge up to 256 draw calls. */
struct pipe_draw_start_count multi[256];
unsigned num_draws = 2;
multi[0].start = first_info->draw.start;
multi[0].count = first_info->draw.count;
multi[1].start = next_info->draw.start;
multi[1].count = next_info->draw.count;
multi[0].start = first_info->info.start;
multi[0].count = first_info->info.count;
multi[1].start = next_info->info.start;
multi[1].count = next_info->info.count;
if (next_info->draw.index_size)
pipe_resource_reference(&next_info->draw.index.resource, NULL);
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
/* Find how many other draws can be merged. */
next = next + next->num_call_slots;
for (; next != last && num_draws < ARRAY_SIZE(multi) &&
is_next_call_a_mergeable_draw(first_info, next, &next_info);
next += next->num_call_slots, num_draws++) {
multi[num_draws].start = next_info->draw.start;
multi[num_draws].count = next_info->draw.count;
multi[num_draws].start = next_info->info.start;
multi[num_draws].count = next_info->info.count;
if (next_info->draw.index_size)
pipe_resource_reference(&next_info->draw.index.resource, NULL);
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
}
pipe->multi_draw(pipe, &first_info->draw, NULL, multi, num_draws);
if (first_info->draw.index_size)
pipe_resource_reference(&first_info->draw.index.resource, NULL);
pipe->multi_draw(pipe, &first_info->info, NULL, multi, num_draws);
if (first_info->info.index_size)
pipe_resource_reference(&first_info->info.index.resource, NULL);
iter = next;
continue;
}
@@ -2195,43 +2194,34 @@ out_of_memory:
}
static void
tc_call_draw_vbo(struct pipe_context *pipe, union tc_payload *payload)
tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
{
struct tc_full_draw_info *info = (struct tc_full_draw_info*)payload;
struct tc_draw_single *info = (struct tc_draw_single*)payload;
pipe->draw_vbo(pipe, &info->draw, NULL);
if (info->draw.index_size)
pipe_resource_reference(&info->draw.index.resource, NULL);
pipe->draw_vbo(pipe, &info->info, NULL);
if (info->info.index_size)
pipe_resource_reference(&info->info.index.resource, NULL);
}
struct tc_draw_indirect {
struct pipe_draw_info info;
struct pipe_draw_indirect_info indirect;
};
static void
tc_call_draw_indirect(struct pipe_context *pipe, union tc_payload *payload)
{
struct tc_full_draw_info *info = (struct tc_full_draw_info*)payload;
struct tc_draw_indirect *info = (struct tc_draw_indirect*)payload;
pipe->draw_vbo(pipe, &info->draw, &info->indirect);
if (info->draw.index_size)
pipe_resource_reference(&info->draw.index.resource, NULL);
pipe->draw_vbo(pipe, &info->info, &info->indirect);
if (info->info.index_size)
pipe_resource_reference(&info->info.index.resource, NULL);
pipe_resource_reference(&info->indirect.buffer, NULL);
pipe_resource_reference(&info->indirect.indirect_draw_count, NULL);
pipe_so_target_reference(&info->indirect.count_from_stream_output, NULL);
}
static struct tc_full_draw_info *
tc_add_draw_vbo(struct pipe_context *_pipe, bool indirect)
{
if (indirect) {
return (struct tc_full_draw_info*)
tc_add_sized_call(threaded_context(_pipe), TC_CALL_draw_indirect,
tc_payload_size_to_call_slots(sizeof(struct tc_full_draw_info)));
} else {
return (struct tc_full_draw_info*)
tc_add_sized_call(threaded_context(_pipe), TC_CALL_draw_vbo,
tc_payload_size_to_call_slots(sizeof(struct pipe_draw_info)));
}
}
static void
tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
@@ -2243,12 +2233,13 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
if (unlikely(indirect)) {
assert(!has_user_indices);
struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, true);
struct tc_draw_indirect *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_indirect, tc_draw_indirect);
if (index_size) {
tc_set_resource_reference(&p->draw.index.resource,
tc_set_resource_reference(&p->info.index.resource,
info->index.resource);
}
memcpy(&p->draw, info, sizeof(*info));
memcpy(&p->info, info, sizeof(*info));
tc_set_resource_reference(&p->indirect.buffer, indirect->buffer);
tc_set_resource_reference(&p->indirect.indirect_draw_count,
@@ -2272,19 +2263,21 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
if (unlikely(!buffer))
return;
struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, false);
memcpy(&p->draw, info, sizeof(*info));
p->draw.has_user_indices = false;
p->draw.index.resource = buffer;
p->draw.start = offset >> util_logbase2(index_size);
struct tc_draw_single *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_single, tc_draw_single);
memcpy(&p->info, info, sizeof(*info));
p->info.has_user_indices = false;
p->info.index.resource = buffer;
p->info.start = offset >> util_logbase2(index_size);
} else {
/* Non-indexed call or indexed with a real index buffer. */
struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, false);
struct tc_draw_single *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_single, tc_draw_single);
if (index_size) {
tc_set_resource_reference(&p->draw.index.resource,
tc_set_resource_reference(&p->info.index.resource,
info->index.resource);
}
memcpy(&p->draw, info, sizeof(*info));
memcpy(&p->info, info, sizeof(*info));
}
}

View File

@@ -26,7 +26,7 @@ CALL(transfer_unmap)
CALL(buffer_subdata)
CALL(texture_subdata)
CALL(emit_string_marker)
CALL(draw_vbo)
CALL(draw_single)
CALL(draw_indirect)
CALL(launch_grid)
CALL(resource_copy_region)