From: Icecream95 Date: Wed, 11 Dec 2019 01:22:19 +0000 (+1300) Subject: gallium/auxiliary: Reduce conversions in u_vbuf_get_minmax_index_mapped X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=80aca96803a37a7436ff96c0cec4a2643f11ed05;p=mesa.git gallium/auxiliary: Reduce conversions in u_vbuf_get_minmax_index_mapped With this patch, GCC generates vectorized code that does the comparisons without converting the indices to 32-bit first. This optimization makes the aforementioned function almost twice as fast for ARM NEON, and should speed up vectorised code on other platforms. Without vectorisation, the function is still a percent or two faster, but slightly larger. Reviewed-by: Eric Anholt Reviewed-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 4b8dc8e4ae6..40bdf1ed830 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -1030,12 +1030,11 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info, const void *indices, unsigned *out_min_index, unsigned *out_max_index) { - unsigned max = 0; - unsigned min = ~0u; - switch (info->index_size) { case 4: { const unsigned *ui_indices = (const unsigned*)indices; + unsigned max = 0; + unsigned min = ~0u; if (info->primitive_restart) { for (unsigned i = 0; i < info->count; i++) { if (ui_indices[i] != info->restart_index) { @@ -1050,10 +1049,14 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info, if (ui_indices[i] < min) min = ui_indices[i]; } } + *out_min_index = min; + *out_max_index = max; break; } case 2: { const unsigned short *us_indices = (const unsigned short*)indices; + unsigned short max = 0; + unsigned short min = ~((unsigned short)0); if (info->primitive_restart) { for (unsigned i = 0; i < info->count; i++) { if (us_indices[i] != info->restart_index) { @@ -1068,10 +1071,14 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info, if (us_indices[i] < min) min = us_indices[i]; } } + *out_min_index = min; + *out_max_index = max; break; } case 1: { const unsigned char *ub_indices = (const unsigned char*)indices; + unsigned char max = 0; + unsigned char min = ~((unsigned char)0); if (info->primitive_restart) { for (unsigned i = 0; i < info->count; i++) { if (ub_indices[i] != info->restart_index) { @@ -1086,14 +1093,13 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info, if (ub_indices[i] < min) min = ub_indices[i]; } } + *out_min_index = min; + *out_max_index = max; break; } default: assert(0); } - - *out_min_index = min; - *out_max_index = max; } void u_vbuf_get_minmax_index(struct pipe_context *pipe,