util: Change a codegenned switch statement to a nice little table.
authorEric Anholt <eric@anholt.net>
Wed, 1 Jul 2020 20:00:16 +0000 (13:00 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 12 Aug 2020 21:22:24 +0000 (14:22 -0700)
This saves us 13 to 35kb on release drivers in my builds.

Acked-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5826>

src/gallium/drivers/svga/svga_pipe_clear.c
src/gallium/frontends/nine/device9.c
src/util/format/u_format_table.py

index 624c2a7593124d59d6cfc10e7f248c22adcb4ad8..82b102081e529a6a3c0f91ad412019c55f552a94 100644 (file)
@@ -290,8 +290,6 @@ svga_clear_texture(struct pipe_context *pipe,
    union pipe_color_union color;
    const struct util_format_description *desc =
       util_format_description(surface->format);
-   const struct util_format_description *unpack =
-      util_format_unpack_description(surface->format);
 
    if (util_format_is_depth_or_stencil(surface->format)) {
       float depth;
@@ -304,8 +302,8 @@ svga_clear_texture(struct pipe_context *pipe,
          stencil = 0;
       }
       else {
-         unpack->unpack_z_float(&depth, 0, data, 0, 1, 1);
-         unpack->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+         util_format_unpack_z_float(surface->format, &depth, data, 1);
+         util_format_unpack_s_8uint(surface->format, &stencil, data, 1);
       }
 
       if (util_format_has_depth(desc)) {
index 98f15efcbee75bd7870b3da7f0e2c3606e6c8e44..b24d9b698b942b07fedd23e34f67b6120e231dcc 100644 (file)
@@ -800,26 +800,26 @@ NineDevice9_SetCursorProperties( struct NineDevice9 *This,
     {
         D3DLOCKED_RECT lock;
         HRESULT hr;
-        const struct util_format_description *sfmt =
-            util_format_description(surf->base.info.format);
-        assert(sfmt);
+        const struct util_format_unpack_description *unpack =
+            util_format_unpack_description(surf->base.info.format);
+        assert(unpack);
 
         hr = NineSurface9_LockRect(surf, &lock, NULL, D3DLOCK_READONLY);
         if (FAILED(hr))
             ret_err("Failed to map cursor source image.\n",
                     D3DERR_DRIVERINTERNALERROR);
 
-        sfmt->unpack_rgba_8unorm(ptr, transfer->stride,
-                                 lock.pBits, lock.Pitch,
-                                 This->cursor.w, This->cursor.h);
+        unpack->unpack_rgba_8unorm(ptr, transfer->stride,
+                                   lock.pBits, lock.Pitch,
+                                   This->cursor.w, This->cursor.h);
 
         if (hw_cursor) {
             void *data = lock.pBits;
             /* SetCursor assumes 32x32 argb with pitch 128 */
             if (lock.Pitch != 128) {
-                sfmt->unpack_rgba_8unorm(This->cursor.hw_upload_temp, 128,
-                                         lock.pBits, lock.Pitch,
-                                         32, 32);
+                unpack->unpack_rgba_8unorm(This->cursor.hw_upload_temp, 128,
+                                           lock.pBits, lock.Pitch,
+                                           32, 32);
                 data = This->cursor.hw_upload_temp;
             }
             hw_cursor = ID3DPresent_SetCursor(This->swapchains[0]->present,
index bb89d56a42db10ce48156e43bb544a8009763b55..56ae64633945dafda79018674fa7b9ee1f4858f1 100644 (file)
@@ -78,6 +78,39 @@ swizzle_map = {
     SWIZZLE_NONE: "PIPE_SWIZZLE_NONE",
 }
 
+def has_access(format):
+    # We don't generate code for YUV formats, and many of the new ones lack
+    # pack/unpack functions for softpipe/llvmpipe.
+    noaccess_formats = [
+        'yv12',
+        'yv16',
+        'iyuv',
+        'nv12',
+        'nv16',
+        'nv21',
+        'p010',
+        'p012',
+        'p016',
+        'xyuv',
+        'ayuv',
+        'r8g8_r8b8_unorm',
+        'g8r8_b8r8_unorm',
+        'g8r8_g8b8_unorm',
+        'y8_u8_v8_422_unorm',
+        'y8_u8v8_422_unorm',
+        'y8_u8_v8_444_unorm',
+        'y16_u16_v16_420_unorm',
+        'y16_u16_v16_422_unorm',
+        'y16_u16v16_422_unorm',
+        'y16_u16_v16_444_unorm',
+    ]
+    if format.short_name() in noaccess_formats:
+        return False
+    if format.layout in ('astc', 'atc', 'fxt1'):
+        return False
+    if format.layout == 'etc' and format.short_name() != 'etc1_rgb8':
+        return False
+    return True
 
 def write_format_table(formats):
     print('/* This file is autogenerated by u_format_table.py from u_format.csv. Do not edit directly. */')
@@ -128,26 +161,19 @@ def write_format_table(formats):
         print("const struct util_format_%sdescription *" % type)
         print("util_format_%sdescription(enum pipe_format format)" % type)
         print("{")
-        print("   if (format >= PIPE_FORMAT_COUNT) {")
+        print("   if (format >= ARRAY_SIZE(util_format_%sdescriptions))" % (type))
         print("      return NULL;")
-        print("   }")
         print()
-        print("   switch (format) {")
-        for format in formats:
-            print("   case %s:" % format.name)
-            print("      return &util_format_%s_%sdescription;" % (format.short_name(), type))
-        print("   default:")
-        print("      return NULL;")
-        print("   }")
+        print("   return &util_format_%sdescriptions[format];" % (type))
         print("}")
         print()
 
-
+    print('static const struct util_format_description')
+    print('util_format_descriptions[] = {')
     for format in formats:
         sn = format.short_name()
 
-        print('const struct util_format_description')
-        print('util_format_%s_description = {' % (sn,))
+        print("   [%s] = {" % (format.name,))
         print("   %s," % (format.name,))
         print("   \"%s\"," % (format.name,))
         print("   \"%s\"," % (sn,))
@@ -162,43 +188,24 @@ def write_format_table(formats):
         u_format_pack.print_channels(format, do_channel_array)
         u_format_pack.print_channels(format, do_swizzle_array)
         print("   %s," % (colorspace_map(format.colorspace),))
-        print("};")
+        print("   },")
         print()
+    print("};")
+    print()
+    generate_table_getter("")
+
+    print('static const struct util_format_pack_description')
+    print('util_format_pack_descriptions[] = {')
+    for format in formats:
+        sn = format.short_name()
+
+        if not has_access(format):
+            print("   [%s] = { 0 }," % (format.name,))
+            continue
 
-        # We don't generate code for YUV formats, and many of the new ones lack pack/unpack
-        # functions for softpipe/llvmpipe.
-        noaccess_formats = [
-            'yv12',
-            'yv16',
-            'iyuv',
-            'nv12',
-            'nv16',
-            'nv21',
-            'p010',
-            'p012',
-            'p016',
-            'xyuv',
-            'ayuv',
-            'r8g8_r8b8_unorm',
-            'g8r8_b8r8_unorm',
-            'g8r8_g8b8_unorm',
-            'y8_u8_v8_422_unorm',
-            'y8_u8v8_422_unorm',
-            'y8_u8_v8_444_unorm',
-            'y16_u16_v16_420_unorm',
-            'y16_u16_v16_422_unorm',
-            'y16_u16v16_422_unorm',
-            'y16_u16_v16_444_unorm',
-        ]
-        access = sn not in noaccess_formats
-        if format.layout in ('astc', 'atc', 'fxt1'):
-            access = False
-        if format.layout == 'etc' and sn != 'etc1_rgb8':
-            access = False
-
-        print('const struct util_format_pack_description')
-        print('util_format_%s_pack_description = {' % sn)
-        if format.colorspace != ZS and not format.is_pure_color() and access:
+        print("   [%s] = {" % (format.name,))
+
+        if format.colorspace != ZS and not format.is_pure_color():
             print("   .pack_rgba_8unorm = &util_format_%s_pack_rgba_8unorm," % sn)
             print("   .pack_rgba_float = &util_format_%s_pack_rgba_float," % sn)
 
@@ -212,12 +219,24 @@ def write_format_table(formats):
         if format.is_pure_unsigned() or format.is_pure_signed():
             print("   .pack_rgba_uint = &util_format_%s_pack_unsigned," % sn)
             print("   .pack_rgba_sint = &util_format_%s_pack_signed," % sn)
-        print("};")
+        print("   },")
         print()
+    print("};")
+    print()
+    generate_table_getter("pack_")
+
+    print('static const struct util_format_unpack_description')
+    print('util_format_unpack_descriptions[] = {')
+    for format in formats:
+        sn = format.short_name()
+
+        if not has_access(format):
+            print("   [%s] = { 0 }," % (format.name,))
+            continue
+
+        print("   [%s] = {" % (format.name,))
 
-        print('const struct util_format_unpack_description')
-        print('util_format_%s_unpack_description = {' % sn)
-        if format.colorspace != ZS and not format.is_pure_color() and access:
+        if format.colorspace != ZS and not format.is_pure_color():
             print("   .unpack_rgba_8unorm = &util_format_%s_unpack_rgba_8unorm," % sn)
             if format.layout == 's3tc' or format.layout == 'rgtc':
                 print("   .fetch_rgba_8unorm = &util_format_%s_fetch_rgba_8unorm," % sn)
@@ -237,11 +256,10 @@ def write_format_table(formats):
         elif format.is_pure_signed():
             print("   .unpack_rgba = &util_format_%s_unpack_signed," % sn)
             print("   .fetch_rgba_sint = &util_format_%s_fetch_signed," % sn)
-        print("};")
-        print()
+        print("   },")
+    print("};")
+    print()
 
-    generate_table_getter("")
-    generate_table_getter("pack_")
     generate_table_getter("unpack_")
 
 def main():