From 9fd0f455af7bc741ea330fcd12478833580dbcfc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 1 Jul 2020 13:00:16 -0700 Subject: [PATCH] util: Change a codegenned switch statement to a nice little table. This saves us 13 to 35kb on release drivers in my builds. Acked-by: Matt Turner Reviewed-by: Kenneth Graunke Reviewed-by: Jason Ekstrand Part-of: --- src/gallium/drivers/svga/svga_pipe_clear.c | 6 +- src/gallium/frontends/nine/device9.c | 18 +-- src/util/format/u_format_table.py | 128 ++++++++++++--------- 3 files changed, 84 insertions(+), 68 deletions(-) diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index 624c2a75931..82b102081e5 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -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)) { diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index 98f15efcbee..b24d9b698b9 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -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, diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index bb89d56a42d..56ae6463394 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -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(): -- 2.30.2