diff --git a/trunk/9920.diff b/trunk/9920.diff new file mode 100644 index 00000000..6e6133be --- /dev/null +++ b/trunk/9920.diff @@ -0,0 +1,132 @@ +diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c +index d2259dd7cb78bb77031d6343ef5b001365c3faed..058509f8f37aecaf5da7036528f106bf353b5c5a 100644 +--- a/src/gallium/auxiliary/util/u_threaded_context.c ++++ b/src/gallium/auxiliary/util/u_threaded_context.c +@@ -244,7 +244,7 @@ tc_add_sized_call(struct threaded_context *tc, enum tc_call_id id, + unsigned num_call_slots) + { + struct tc_batch *next = &tc->batch_slots[tc->next]; +- ++ assert(num_call_slots <= TC_CALLS_PER_BATCH); + tc_debug_check(tc); + + if (unlikely(next->num_total_call_slots + num_call_slots > TC_CALLS_PER_BATCH)) { +@@ -2437,6 +2437,10 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info, + return; + } + ++ const int draw_overhead_bytes = offsetof(struct tc_call, payload) + sizeof(struct tc_draw_multi); ++ const int one_draw_payload_bytes = sizeof(((struct tc_draw_multi*)NULL)->slot[0]); ++ const int slots_for_one_draw = DIV_ROUND_UP(draw_overhead_bytes + one_draw_payload_bytes, ++ sizeof(struct tc_call)); + /* Multi draw. */ + if (index_size && has_user_indices) { + struct pipe_resource *buffer = NULL; +@@ -2463,43 +2467,77 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info, + if (unlikely(!buffer)) + return; + +- struct tc_draw_multi *p = +- tc_add_slot_based_call(tc, TC_CALL_draw_multi, tc_draw_multi, +- num_draws); +- memcpy(&p->info, info, DRAW_INFO_SIZE_WITHOUT_INDEXBUF_AND_MIN_MAX_INDEX); +- p->info.index.resource = buffer; +- p->num_draws = num_draws; ++ int total_offset = 0; ++ while (num_draws) { ++ struct tc_batch *next = &tc->batch_slots[tc->next]; ++ ++ int nb_slots_left = TC_CALLS_PER_BATCH - next->num_total_call_slots; ++ /* If there isn't enough place for one draw, try to fill the next one */ ++ if (nb_slots_left < slots_for_one_draw) ++ nb_slots_left = TC_CALLS_PER_BATCH; ++ const int size_left_bytes = nb_slots_left * sizeof(struct tc_call); + +- /* Upload index buffers. */ +- for (unsigned i = 0, offset = 0; i < num_draws; i++) { +- unsigned count = draws[i].count; ++ /* How many draws can we fit in the current batch */ ++ const int dr = MIN2(num_draws, (size_left_bytes - draw_overhead_bytes) / one_draw_payload_bytes); + +- if (!count) { +- p->slot[i].start = 0; +- p->slot[i].count = 0; +- continue; ++ struct tc_draw_multi *p = ++ tc_add_slot_based_call(tc, TC_CALL_draw_multi, tc_draw_multi, ++ dr); ++ memcpy(&p->info, info, DRAW_INFO_SIZE_WITHOUT_INDEXBUF_AND_MIN_MAX_INDEX); ++ p->info.index.resource = buffer; ++ p->num_draws = dr; ++ ++ /* Upload index buffers. */ ++ for (unsigned i = 0, offset = 0; i < dr; i++) { ++ unsigned count = draws[i + total_offset].count; ++ ++ if (!count) { ++ p->slot[i].start = 0; ++ p->slot[i].count = 0; ++ continue; ++ } ++ ++ unsigned size = count << index_size_shift; ++ memcpy(ptr + offset, ++ (uint8_t*)info->index.user + ++ (draws[i + total_offset].start << index_size_shift), size); ++ p->slot[i].start = (buffer_offset + offset) >> index_size_shift; ++ p->slot[i].count = count; ++ offset += size; + } + +- unsigned size = count << index_size_shift; +- memcpy(ptr + offset, +- (uint8_t*)info->index.user + +- (draws[i].start << index_size_shift), size); +- p->slot[i].start = (buffer_offset + offset) >> index_size_shift; +- p->slot[i].count = count; +- offset += size; ++ total_offset += dr; ++ num_draws -= dr; + } + } else { +- /* Non-indexed call or indexed with a real index buffer. */ +- struct tc_draw_multi *p = +- tc_add_slot_based_call(tc, TC_CALL_draw_multi, tc_draw_multi, +- num_draws); +- if (index_size) { +- tc_set_resource_reference(&p->info.index.resource, +- info->index.resource); ++ int total_offset = 0; ++ while (num_draws) { ++ struct tc_batch *next = &tc->batch_slots[tc->next]; ++ ++ int nb_slots_left = TC_CALLS_PER_BATCH - next->num_total_call_slots; ++ /* If there isn't enough place for one draw, try to fill the next one */ ++ if (nb_slots_left < slots_for_one_draw) ++ nb_slots_left = TC_CALLS_PER_BATCH; ++ const int size_left_bytes = nb_slots_left * sizeof(struct tc_call); ++ ++ /* How many draws can we fit in the current batch */ ++ const int dr = MIN2(num_draws, (size_left_bytes - draw_overhead_bytes) / one_draw_payload_bytes); ++ ++ /* Non-indexed call or indexed with a real index buffer. */ ++ struct tc_draw_multi *p = ++ tc_add_slot_based_call(tc, TC_CALL_draw_multi, tc_draw_multi, ++ dr); ++ if (index_size) { ++ tc_set_resource_reference(&p->info.index.resource, ++ info->index.resource); ++ } ++ memcpy(&p->info, info, DRAW_INFO_SIZE_WITHOUT_MIN_MAX_INDEX); ++ p->num_draws = dr; ++ memcpy(p->slot, &draws[total_offset], sizeof(draws[0]) * dr); ++ num_draws -= dr; ++ ++ total_offset += dr; + } +- memcpy(&p->info, info, DRAW_INFO_SIZE_WITHOUT_MIN_MAX_INDEX); +- p->num_draws = num_draws; +- memcpy(p->slot, draws, sizeof(draws[0]) * num_draws); + } + } + diff --git a/trunk/PKGBUILD b/trunk/PKGBUILD index 13f5dc4f..177cf8e6 100644 --- a/trunk/PKGBUILD +++ b/trunk/PKGBUILD @@ -16,8 +16,10 @@ makedepends=('python-mako' 'libxml2' 'libx11' 'xorgproto' 'libdrm' 'libxshmfence url="https://www.mesa3d.org/" license=('custom') source=(https://mesa.freedesktop.org/archive/mesa-${pkgver}.tar.xz{,.sig} + 9920.diff LICENSE) sha512sums=('c3d7969b56e1c31ee642e3b7143d565c4233173dab7cc5576b686c873c27134dc8292a9f2caa0a0dd3c54d0c89d27d6030f36a2c84f85dcedee7ae80b19e5c3b' + 'SKIP' 'SKIP' 'f9f0d0ccf166fe6cb684478b6f1e1ab1f2850431c06aa041738563eb1808a004e52cdec823c103c9e180f03ffc083e95974d291353f0220fe52ae6d4897fecc7') validpgpkeys=('8703B6700E7EE06D7A39B8D6EDAE37B02CEB490D' # Emil Velikov @@ -27,6 +29,11 @@ validpgpkeys=('8703B6700E7EE06D7A39B8D6EDAE37B02CEB490D' # Emil Velikov '57551DE15B968F6341C248F68D8E31AFC32428A6') # Eric Engestrom +prepare() { + cd "${srcdir}/$pkgbase-$pkgver" + patch -p1 < ../9920.diff +} + build() { arch-meson mesa-$pkgver build \ -D b_lto=true \