gallium/auxiliary: Reduce conversions in u_vbuf_get_minmax_index_mapped
authorIcecream95 <ixn@keemail.me>
Wed, 11 Dec 2019 01:22:19 +0000 (14:22 +1300)
committerMarge Bot <eric+marge@anholt.net>
Mon, 16 Dec 2019 22:57:35 +0000 (22:57 +0000)
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>

src/gallium/auxiliary/util/u_vbuf.c

index 4b8dc8e4ae6c77002801bcc60a056151197f89f9..40bdf1ed8308926b2015aa4916c99bb1dcf921c0 100644 (file)
@@ -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,