diff --git a/src/util/format/u_format.h b/src/util/format/u_format.h index 126e26091f1..a9c87beb143 100644 --- a/src/util/format/u_format.h +++ b/src/util/format/u_format.h @@ -237,6 +237,15 @@ struct util_format_description * Colorspace transformation. */ enum util_format_colorspace colorspace; + + /** + * For sRGB formats, equivalent linear format; for linear formats, + * equivalent sRGB format + */ + union { + enum pipe_format srgb_equivalent; + enum pipe_format linear_equivalent; + }; }; struct util_format_pack_description { @@ -1059,107 +1068,7 @@ util_format_srgb(enum pipe_format format) if (util_format_is_srgb(format)) return format; - switch (format) { - case PIPE_FORMAT_L8_UNORM: - return PIPE_FORMAT_L8_SRGB; - case PIPE_FORMAT_R8_UNORM: - return PIPE_FORMAT_R8_SRGB; - case PIPE_FORMAT_L8A8_UNORM: - return PIPE_FORMAT_L8A8_SRGB; - case PIPE_FORMAT_R8G8_UNORM: - return PIPE_FORMAT_R8G8_SRGB; - case PIPE_FORMAT_R8G8B8_UNORM: - return PIPE_FORMAT_R8G8B8_SRGB; - case PIPE_FORMAT_B8G8R8_UNORM: - return PIPE_FORMAT_B8G8R8_SRGB; - case PIPE_FORMAT_A8B8G8R8_UNORM: - return PIPE_FORMAT_A8B8G8R8_SRGB; - case PIPE_FORMAT_X8B8G8R8_UNORM: - return PIPE_FORMAT_X8B8G8R8_SRGB; - case PIPE_FORMAT_B8G8R8A8_UNORM: - return PIPE_FORMAT_B8G8R8A8_SRGB; - case PIPE_FORMAT_B8G8R8X8_UNORM: - return PIPE_FORMAT_B8G8R8X8_SRGB; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return PIPE_FORMAT_A8R8G8B8_SRGB; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return PIPE_FORMAT_X8R8G8B8_SRGB; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return PIPE_FORMAT_R8G8B8A8_SRGB; - case PIPE_FORMAT_R8G8B8X8_UNORM: - return PIPE_FORMAT_R8G8B8X8_SRGB; - case PIPE_FORMAT_DXT1_RGB: - return PIPE_FORMAT_DXT1_SRGB; - case PIPE_FORMAT_DXT1_RGBA: - return PIPE_FORMAT_DXT1_SRGBA; - case PIPE_FORMAT_DXT3_RGBA: - return PIPE_FORMAT_DXT3_SRGBA; - case PIPE_FORMAT_DXT5_RGBA: - return PIPE_FORMAT_DXT5_SRGBA; - case PIPE_FORMAT_R5G6B5_UNORM: - return PIPE_FORMAT_R5G6B5_SRGB; - case PIPE_FORMAT_B5G6R5_UNORM: - return PIPE_FORMAT_B5G6R5_SRGB; - case PIPE_FORMAT_BPTC_RGBA_UNORM: - return PIPE_FORMAT_BPTC_SRGBA; - case PIPE_FORMAT_ETC2_RGB8: - return PIPE_FORMAT_ETC2_SRGB8; - case PIPE_FORMAT_ETC2_RGB8A1: - return PIPE_FORMAT_ETC2_SRGB8A1; - case PIPE_FORMAT_ETC2_RGBA8: - return PIPE_FORMAT_ETC2_SRGBA8; - case PIPE_FORMAT_ASTC_4x4: - return PIPE_FORMAT_ASTC_4x4_SRGB; - case PIPE_FORMAT_ASTC_5x4: - return PIPE_FORMAT_ASTC_5x4_SRGB; - case PIPE_FORMAT_ASTC_5x5: - return PIPE_FORMAT_ASTC_5x5_SRGB; - case PIPE_FORMAT_ASTC_6x5: - return PIPE_FORMAT_ASTC_6x5_SRGB; - case PIPE_FORMAT_ASTC_6x6: - return PIPE_FORMAT_ASTC_6x6_SRGB; - case PIPE_FORMAT_ASTC_8x5: - return PIPE_FORMAT_ASTC_8x5_SRGB; - case PIPE_FORMAT_ASTC_8x6: - return PIPE_FORMAT_ASTC_8x6_SRGB; - case PIPE_FORMAT_ASTC_8x8: - return PIPE_FORMAT_ASTC_8x8_SRGB; - case PIPE_FORMAT_ASTC_10x5: - return PIPE_FORMAT_ASTC_10x5_SRGB; - case PIPE_FORMAT_ASTC_10x6: - return PIPE_FORMAT_ASTC_10x6_SRGB; - case PIPE_FORMAT_ASTC_10x8: - return PIPE_FORMAT_ASTC_10x8_SRGB; - case PIPE_FORMAT_ASTC_10x10: - return PIPE_FORMAT_ASTC_10x10_SRGB; - case PIPE_FORMAT_ASTC_12x10: - return PIPE_FORMAT_ASTC_12x10_SRGB; - case PIPE_FORMAT_ASTC_12x12: - return PIPE_FORMAT_ASTC_12x12_SRGB; - case PIPE_FORMAT_ASTC_3x3x3: - return PIPE_FORMAT_ASTC_3x3x3_SRGB; - case PIPE_FORMAT_ASTC_4x3x3: - return PIPE_FORMAT_ASTC_4x3x3_SRGB; - case PIPE_FORMAT_ASTC_4x4x3: - return PIPE_FORMAT_ASTC_4x4x3_SRGB; - case PIPE_FORMAT_ASTC_4x4x4: - return PIPE_FORMAT_ASTC_4x4x4_SRGB; - case PIPE_FORMAT_ASTC_5x4x4: - return PIPE_FORMAT_ASTC_5x4x4_SRGB; - case PIPE_FORMAT_ASTC_5x5x4: - return PIPE_FORMAT_ASTC_5x5x4_SRGB; - case PIPE_FORMAT_ASTC_5x5x5: - return PIPE_FORMAT_ASTC_5x5x5_SRGB; - case PIPE_FORMAT_ASTC_6x5x5: - return PIPE_FORMAT_ASTC_6x5x5_SRGB; - case PIPE_FORMAT_ASTC_6x6x5: - return PIPE_FORMAT_ASTC_6x6x5_SRGB; - case PIPE_FORMAT_ASTC_6x6x6: - return PIPE_FORMAT_ASTC_6x6x6_SRGB; - - default: - return PIPE_FORMAT_NONE; - } + return util_format_description(format)->srgb_equivalent; } /** @@ -1169,107 +1078,10 @@ util_format_srgb(enum pipe_format format) static inline enum pipe_format util_format_linear(enum pipe_format format) { - switch (format) { - case PIPE_FORMAT_L8_SRGB: - return PIPE_FORMAT_L8_UNORM; - case PIPE_FORMAT_R8_SRGB: - return PIPE_FORMAT_R8_UNORM; - case PIPE_FORMAT_L8A8_SRGB: - return PIPE_FORMAT_L8A8_UNORM; - case PIPE_FORMAT_R8G8_SRGB: - return PIPE_FORMAT_R8G8_UNORM; - case PIPE_FORMAT_R8G8B8_SRGB: - return PIPE_FORMAT_R8G8B8_UNORM; - case PIPE_FORMAT_B8G8R8_SRGB: - return PIPE_FORMAT_B8G8R8_UNORM; - case PIPE_FORMAT_A8B8G8R8_SRGB: - return PIPE_FORMAT_A8B8G8R8_UNORM; - case PIPE_FORMAT_X8B8G8R8_SRGB: - return PIPE_FORMAT_X8B8G8R8_UNORM; - case PIPE_FORMAT_B8G8R8A8_SRGB: - return PIPE_FORMAT_B8G8R8A8_UNORM; - case PIPE_FORMAT_B8G8R8X8_SRGB: - return PIPE_FORMAT_B8G8R8X8_UNORM; - case PIPE_FORMAT_A8R8G8B8_SRGB: - return PIPE_FORMAT_A8R8G8B8_UNORM; - case PIPE_FORMAT_X8R8G8B8_SRGB: - return PIPE_FORMAT_X8R8G8B8_UNORM; - case PIPE_FORMAT_R8G8B8A8_SRGB: - return PIPE_FORMAT_R8G8B8A8_UNORM; - case PIPE_FORMAT_R8G8B8X8_SRGB: - return PIPE_FORMAT_R8G8B8X8_UNORM; - case PIPE_FORMAT_DXT1_SRGB: - return PIPE_FORMAT_DXT1_RGB; - case PIPE_FORMAT_DXT1_SRGBA: - return PIPE_FORMAT_DXT1_RGBA; - case PIPE_FORMAT_DXT3_SRGBA: - return PIPE_FORMAT_DXT3_RGBA; - case PIPE_FORMAT_DXT5_SRGBA: - return PIPE_FORMAT_DXT5_RGBA; - case PIPE_FORMAT_R5G6B5_SRGB: - return PIPE_FORMAT_R5G6B5_UNORM; - case PIPE_FORMAT_B5G6R5_SRGB: - return PIPE_FORMAT_B5G6R5_UNORM; - case PIPE_FORMAT_BPTC_SRGBA: - return PIPE_FORMAT_BPTC_RGBA_UNORM; - case PIPE_FORMAT_ETC2_SRGB8: - return PIPE_FORMAT_ETC2_RGB8; - case PIPE_FORMAT_ETC2_SRGB8A1: - return PIPE_FORMAT_ETC2_RGB8A1; - case PIPE_FORMAT_ETC2_SRGBA8: - return PIPE_FORMAT_ETC2_RGBA8; - case PIPE_FORMAT_ASTC_4x4_SRGB: - return PIPE_FORMAT_ASTC_4x4; - case PIPE_FORMAT_ASTC_5x4_SRGB: - return PIPE_FORMAT_ASTC_5x4; - case PIPE_FORMAT_ASTC_5x5_SRGB: - return PIPE_FORMAT_ASTC_5x5; - case PIPE_FORMAT_ASTC_6x5_SRGB: - return PIPE_FORMAT_ASTC_6x5; - case PIPE_FORMAT_ASTC_6x6_SRGB: - return PIPE_FORMAT_ASTC_6x6; - case PIPE_FORMAT_ASTC_8x5_SRGB: - return PIPE_FORMAT_ASTC_8x5; - case PIPE_FORMAT_ASTC_8x6_SRGB: - return PIPE_FORMAT_ASTC_8x6; - case PIPE_FORMAT_ASTC_8x8_SRGB: - return PIPE_FORMAT_ASTC_8x8; - case PIPE_FORMAT_ASTC_10x5_SRGB: - return PIPE_FORMAT_ASTC_10x5; - case PIPE_FORMAT_ASTC_10x6_SRGB: - return PIPE_FORMAT_ASTC_10x6; - case PIPE_FORMAT_ASTC_10x8_SRGB: - return PIPE_FORMAT_ASTC_10x8; - case PIPE_FORMAT_ASTC_10x10_SRGB: - return PIPE_FORMAT_ASTC_10x10; - case PIPE_FORMAT_ASTC_12x10_SRGB: - return PIPE_FORMAT_ASTC_12x10; - case PIPE_FORMAT_ASTC_12x12_SRGB: - return PIPE_FORMAT_ASTC_12x12; - case PIPE_FORMAT_ASTC_3x3x3_SRGB: - return PIPE_FORMAT_ASTC_3x3x3; - case PIPE_FORMAT_ASTC_4x3x3_SRGB: - return PIPE_FORMAT_ASTC_4x3x3; - case PIPE_FORMAT_ASTC_4x4x3_SRGB: - return PIPE_FORMAT_ASTC_4x4x3; - case PIPE_FORMAT_ASTC_4x4x4_SRGB: - return PIPE_FORMAT_ASTC_4x4x4; - case PIPE_FORMAT_ASTC_5x4x4_SRGB: - return PIPE_FORMAT_ASTC_5x4x4; - case PIPE_FORMAT_ASTC_5x5x4_SRGB: - return PIPE_FORMAT_ASTC_5x5x4; - case PIPE_FORMAT_ASTC_5x5x5_SRGB: - return PIPE_FORMAT_ASTC_5x5x5; - case PIPE_FORMAT_ASTC_6x5x5_SRGB: - return PIPE_FORMAT_ASTC_6x5x5; - case PIPE_FORMAT_ASTC_6x6x5_SRGB: - return PIPE_FORMAT_ASTC_6x6x5; - case PIPE_FORMAT_ASTC_6x6x6_SRGB: - return PIPE_FORMAT_ASTC_6x6x6; - default: - assert(!util_format_is_srgb(format)); + if (!util_format_is_srgb(format)) return format; - } + + return util_format_description(format)->linear_equivalent; } /** diff --git a/src/util/format/u_format.yaml b/src/util/format/u_format.yaml index fc0aa0ceb47..f14d6190e2f 100644 --- a/src/util/format/u_format.yaml +++ b/src/util/format/u_format.yaml @@ -7,6 +7,7 @@ # Each format entry contains: # - name, per enum pipe_format # - layout, per enum util_format_layout, in shortened lower caps +# - sublayout, to distinguish between meaningfully-different layout variants # - pixel block's width # - pixel block's height # - pixel block's depth, in number of pixels @@ -815,48 +816,56 @@ # - http://msdn.microsoft.com/en-us/library/bb694531.aspx - name: DXT1_RGB layout: s3tc + sublayout: dxt1 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] - name: DXT1_RGBA layout: s3tc + sublayout: dxt1 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, W] - name: DXT3_RGBA layout: s3tc + sublayout: dxt3 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, Z, W] - name: DXT5_RGBA layout: s3tc + sublayout: dxt5 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, Z, W] - name: DXT1_SRGB layout: s3tc + sublayout: dxt1 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] - name: DXT1_SRGBA layout: s3tc + sublayout: dxt1 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, W] - name: DXT3_SRGBA layout: s3tc + sublayout: dxt3 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, Z, W] - name: DXT5_SRGBA layout: s3tc + sublayout: dxt5 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X128] @@ -932,6 +941,7 @@ - name: ETC1_RGB8 layout: etc + sublayout: etc1 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] @@ -939,60 +949,70 @@ - name: ETC2_RGB8 layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] - name: ETC2_SRGB8 layout: etc + sublayout: etc2 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] - name: ETC2_RGB8A1 layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, W] - name: ETC2_SRGB8A1 layout: etc + sublayout: etc2 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, Y, Z, W] - name: ETC2_RGBA8 layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, Z, W] - name: ETC2_SRGBA8 layout: etc + sublayout: etc2 colorspace: SRGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, Z, W] - name: ETC2_R11_UNORM layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, 0, 0, 1] - name: ETC2_R11_SNORM layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X64] swizzles: [X, 0, 0, 1] - name: ETC2_RG11_UNORM layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X128] swizzles: [X, Y, 0, 1] - name: ETC2_RG11_SNORM layout: etc + sublayout: etc2 colorspace: RGB block: {width: 4, height: 4, depth: 1} channels: [X128] diff --git a/src/util/format/u_format_parse.py b/src/util/format/u_format_parse.py index 0170d26583b..274dbad2ad2 100644 --- a/src/util/format/u_format_parse.py +++ b/src/util/format/u_format_parse.py @@ -225,11 +225,17 @@ class Format: self.name = "unknown" self.name = f"PIPE_FORMAT_{consume_str(self, source, 'name')}" self.layout = consume_str(self, source, 'layout') + if 'sublayout' in source: + self.sublayout = consume_str(self, source, 'sublayout') + else: + self.sublayout = None self.block_width = consume_int(self, source, 'block', 'width') self.block_height = consume_int(self, source, 'block', 'height') self.block_depth = consume_int(self, source, 'block', 'depth') consumed(self, source, 'block') self.colorspace = consume_str(self, source, 'colorspace') + self.srgb_equivalent = None + self.linear_equivalent = None # Formats with no endian-dependent swizzling declare their channel and # swizzle layout at the top level. Else they can declare an @@ -323,6 +329,8 @@ class Format: return self.name def __eq__(self, other): + if not other: + return False return self.name == other.name def __hash__(self): @@ -523,6 +531,27 @@ def _parse_channels(fields, layout, colorspace, swizzles): return channels +def mostly_equivalent(one, two): + if one.layout != two.layout or \ + one.sublayout != two.sublayout or \ + one.block_width != two.block_width or \ + one.block_height != two.block_height or \ + one.block_depth != two.block_depth or \ + one.le_swizzles != two.le_swizzles or \ + one.le_channels != two.le_channels or \ + one.be_swizzles != two.be_swizzles or \ + one.be_channels != two.be_channels: + return False + return True + +def should_ignore_for_mapping(fmt): + # This format is a really special reinterpretation of depth/stencil as + # RGB. Until we figure out something better, just special-case it so + # we won't consider it as equivalent to anything. + if fmt.name == "PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8": + return True + return False + def parse(filename): '''Parse the format description in YAML format in terms of the @@ -543,4 +572,24 @@ def parse(filename): raise RuntimeError(f"Duplicate format entry {f.name}") ret.append(f) + for fmt in ret: + if should_ignore_for_mapping(fmt): + continue + if fmt.colorspace != RGB and fmt.colorspace != SRGB: + continue + if fmt.colorspace == RGB: + for equiv in ret: + if equiv.colorspace != SRGB or not mostly_equivalent(fmt, equiv) or \ + should_ignore_for_mapping(equiv): + continue + assert(fmt.srgb_equivalent == None) + fmt.srgb_equivalent = equiv + elif fmt.colorspace == SRGB: + for equiv in ret: + if equiv.colorspace != RGB or not mostly_equivalent(fmt, equiv) or \ + should_ignore_for_mapping(equiv): + continue + assert(fmt.linear_equivalent == None) + fmt.linear_equivalent = equiv + return ret diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index 76d020a2383..1228b5190ae 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -41,7 +41,6 @@ def layout_map(layout): def colorspace_map(colorspace): return 'UTIL_FORMAT_COLORSPACE_' + str(colorspace).upper() - colorspace_channels_map = { 'RGB': ['r', 'g', 'b', 'a'], 'SRGB': ['sr', 'sg', 'sb', 'a'], @@ -150,6 +149,7 @@ def write_format_aliases(formats): print("#define %s %s" % (f.be_alias, f.name), file=sys.stdout3) print("#endif", file=sys.stdout3) + def write_format_table(formats): write_format_table_header(sys.stdout) print('#include "util/format/u_format.h"') @@ -245,20 +245,26 @@ def write_format_table(formats): sn = format.short_name() print(" [%s] = {" % (format.name,)) - print(" %s," % (format.name,)) - print(" \"%s\"," % (format.name,)) - print(" \"%s\"," % (sn,)) - print(" {%u, %u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_depth, format.block_size())) - print(" %s," % (layout_map(format.layout),)) - print(" %u,\t/* nr_channels */" % (format.nr_channels(),)) - print(" %s,\t/* is_array */" % (bool_map(format.is_array()),)) - print(" %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)) - print(" %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)) - print(" %s,\t/* is_unorm */" % (bool_map(format.is_unorm()),)) - print(" %s,\t/* is_snorm */" % (bool_map(format.is_snorm()),)) + print(" .format = %s," % (format.name,)) + print(" .name = \"%s\"," % (format.name,)) + print(" .short_name = \"%s\"," % (sn,)) + print(" .block = {%u, %u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_depth, format.block_size())) + print(" .layout = %s," % (layout_map(format.layout),)) + print(" .nr_channels = %u,\t/* nr_channels */" % (format.nr_channels(),)) + print(" .is_array = %s,\t/* is_array */" % (bool_map(format.is_array()),)) + print(" .is_bitmask = %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)) + print(" .is_mixed = %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)) + print(" .is_unorm = %s,\t/* is_unorm */" % (bool_map(format.is_unorm()),)) + print(" .is_snorm = %s,\t/* is_snorm */" % (bool_map(format.is_snorm()),)) 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(" .colorspace = %s," % (colorspace_map(format.colorspace),)) + if format.srgb_equivalent: + print(" .srgb_equivalent = %s,\t/* srgb_equivalent */" % format.srgb_equivalent.name) + elif format.linear_equivalent: + print(" .linear_equivalent = %s,\t/* linear_equivalent */" % format.linear_equivalent.name) + else: + print(" .srgb_equivalent = PIPE_FORMAT_NONE,\t/* srgb_equivalent */") print(" },") print() print("};")