summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIcecream95 <ixn@keemail.me>2019-12-11 14:22:19 +1300
committerMarge Bot <eric+marge@anholt.net>2019-12-16 22:57:35 +0000
commit80aca96803a37a7436ff96c0cec4a2643f11ed05 (patch)
tree0ff26758763ee9a590e5adf3ca37088e864a58e5
parent69ea473eeb91b2c4db26402c3bc2ed5799d26605 (diff)
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 <eric@anholt.net> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3050>
-rw-r--r--src/gallium/auxiliary/util/u_vbuf.c18
1 files changed, 12 insertions, 6 deletions
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,