diff --git a/src/util/format/u_format.h b/src/util/format/u_format.h index 3dc5d3191e3..2614a16150d 100644 --- a/src/util/format/u_format.h +++ b/src/util/format/u_format.h @@ -141,6 +141,16 @@ struct util_format_channel_description }; +enum pipe_video_chroma_format { + PIPE_VIDEO_CHROMA_FORMAT_NONE = 0, + PIPE_VIDEO_CHROMA_FORMAT_400 = 1, + PIPE_VIDEO_CHROMA_FORMAT_420 = 2, + PIPE_VIDEO_CHROMA_FORMAT_422 = 3, + PIPE_VIDEO_CHROMA_FORMAT_440 = 4, + PIPE_VIDEO_CHROMA_FORMAT_444 = 5, +}; + + struct util_format_description { enum pipe_format format; @@ -238,6 +248,11 @@ struct util_format_description */ enum util_format_colorspace colorspace; + /** + * subsampling. + */ + enum pipe_video_chroma_format subsampling; + /** * For sRGB formats, equivalent linear format; for linear formats, * equivalent sRGB format @@ -1578,6 +1593,12 @@ util_format_rgb_to_bgr(enum pipe_format format); enum pipe_format util_format_rgbx_to_rgba(enum pipe_format format); +static inline enum pipe_video_chroma_format +pipe_format_to_chroma_format(enum pipe_format format) +{ + return util_format_description(format)->subsampling; +} + /* Returns the pipe format for the given array type, bitsize and component count. */ enum pipe_format util_format_get_array(const enum util_format_type type, const unsigned bits, diff --git a/src/util/format/u_format.yaml b/src/util/format/u_format.yaml index bea68f27f14..52fe6b2d96b 100644 --- a/src/util/format/u_format.yaml +++ b/src/util/format/u_format.yaml @@ -31,6 +31,7 @@ # - number of bits # - channel swizzle # - color space: rgb, srgb, yuv, zs +# - subsampling: 400, 420, 422, 440 or 444 # # The channel encoding and swizzle may be defined separately for little-endian # and big-endian hosts when using a packed (non-array/bitmask) format. @@ -695,6 +696,7 @@ alias: UYVY layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [UN8, UN8, UN8, UN8] swizzles: [X, Y, Z, 1] @@ -702,6 +704,7 @@ alias: VYUY layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [UN8, UN8, UN8, UN8] swizzles: [X, Y, Z, 1] @@ -710,6 +713,7 @@ alias: YUYV layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [UN8, UN8, UN8, UN8] swizzles: [X, Y, Z, 1] @@ -717,6 +721,7 @@ alias: YVYU layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [UN8, UN8, UN8, UN8] swizzles: [X, Y, Z, 1] @@ -725,6 +730,7 @@ alias: AYUV layout: other colorspace: YUV + subsampling: 444 block: {width: 4, height: 4, depth: 1} channels: [UN8] swizzles: [X, Y, Z, W] @@ -732,6 +738,7 @@ alias: XYUV layout: other colorspace: YUV + subsampling: 444 block: {width: 4, height: 4, depth: 1} channels: [UN8] swizzles: [X, Y, Z, 1] @@ -2001,6 +2008,7 @@ alias: YV12 layout: planar3 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2008,6 +2016,7 @@ alias: YV16 layout: planar3 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2015,6 +2024,7 @@ alias: IYUV layout: planar3 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2022,6 +2032,7 @@ alias: NV12 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2030,12 +2041,14 @@ layout: planar2 colorspace: YUV block: {width: 1, height: 1, depth: 1} + subsampling: 420 channels: [] swizzles: [X, Y, Z, W] - name: Y8_400_UNORM alias: Y8_UNORM layout: other colorspace: YUV + subsampling: 400 block: {width: 1, height: 1, depth: 1} channels: [UN8] swizzles: [X, 0, 0, 1] @@ -2043,6 +2056,7 @@ alias: NV15 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2050,6 +2064,7 @@ alias: NV20 layout: planar2 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2164,6 +2179,7 @@ - name: Y16_U16V16_444_UNORM layout: planar2 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2225,6 +2241,7 @@ - name: Y8_U8_V8_422_UNORM layout: planar3 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2233,12 +2250,14 @@ layout: planar2 colorspace: YUV block: {width: 1, height: 1, depth: 1} + subsampling: 422 channels: [] swizzles: [X, Y, Z, W] - name: Y8_V8U8_422_UNORM alias: NV61 layout: planar2 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2246,6 +2265,7 @@ alias: NV24 layout: planar2 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2253,18 +2273,21 @@ alias: NV42 layout: planar2 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y8_U8_V8_444_UNORM layout: planar3 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y8_U8_V8_440_UNORM layout: planar3 colorspace: YUV + subsampling: 440 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2273,60 +2296,70 @@ - name: Y10X6_U10X6_V10X6_420_UNORM layout: planar3 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y12X4_U12X4_V12X4_420_UNORM layout: planar3 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y16_U16_V16_420_UNORM layout: planar3 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y10X6_U10X6_V10X6_422_UNORM layout: planar3 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y12X4_U12X4_V12X4_422_UNORM layout: planar3 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y16_U16_V16_422_UNORM layout: planar3 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y10X6_U10X6_V10X6_444_UNORM layout: planar3 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y12X4_U12X4_V12X4_444_UNORM layout: planar3 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y16_U16_V16_444_UNORM layout: planar3 colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y16_U16V16_422_UNORM layout: planar2 colorspace: YUV + subsampling: 422 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2336,6 +2369,7 @@ alias: P010 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2343,6 +2377,7 @@ alias: P012 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2350,6 +2385,7 @@ alias: P016 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2357,6 +2393,7 @@ alias: P030 layout: planar2 colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] @@ -2366,6 +2403,7 @@ alias: Y210 layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] @@ -2373,6 +2411,7 @@ alias: Y212 layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] @@ -2380,6 +2419,7 @@ alias: Y216 layout: subsampled colorspace: YUV + subsampling: 422 block: {width: 2, height: 1, depth: 1} channels: [X64] swizzles: [X, Y, Z, 1] @@ -2389,6 +2429,7 @@ alias: Y410 layout: other colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [UN10, UN10, UN10, UN2] swizzles: [Y, Z, X, W] @@ -2396,6 +2437,7 @@ alias: Y412 layout: other colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [UN16, UN16, UN16, UN16] swizzles: [Y, Z, X, W] @@ -2403,6 +2445,7 @@ alias: Y416 layout: other colorspace: YUV + subsampling: 444 block: {width: 1, height: 1, depth: 1} channels: [UN16, UN16, UN16, UN16] swizzles: [Y, Z, X, W] @@ -2412,12 +2455,14 @@ - name: Y8U8V8_420_UNORM_PACKED layout: subsampled colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] - name: Y10U10V10_420_UNORM_PACKED layout: subsampled colorspace: YUV + subsampling: 420 block: {width: 1, height: 1, depth: 1} channels: [] swizzles: [X, Y, Z, W] diff --git a/src/util/format/u_format_parse.py b/src/util/format/u_format_parse.py index cf236eb6991..f0b77539472 100644 --- a/src/util/format/u_format_parse.py +++ b/src/util/format/u_format_parse.py @@ -234,6 +234,10 @@ class Format: self.block_depth = consume_int(self, source, 'block', 'depth') consumed(self, source, 'block') self.colorspace = consume_str(self, source, 'colorspace') + if 'subsampling' in source: + self.subsampling = consume_int(self, source, 'subsampling') + else: + self.subsampling = None self.srgb_equivalent = None self.linear_equivalent = None diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index a5a70eb60be..8cb52696eb3 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -41,6 +41,9 @@ def layout_map(layout): def colorspace_map(colorspace): return 'UTIL_FORMAT_COLORSPACE_' + str(colorspace).upper() +def subsampling_map(subsampling): + return 'PIPE_VIDEO_CHROMA_FORMAT_' + str(subsampling).upper() + colorspace_channels_map = { 'RGB': ['r', 'g', 'b', 'a'], 'SRGB': ['sr', 'sg', 'sb', 'a'], @@ -304,32 +307,6 @@ def write_format_aliases(formats): CHROMA_SUBSAMP = ['400', '420', '422', '444', '440'] -def write_to_chroma_format(formats): - print('enum pipe_video_chroma_format {', file=sys.stdout3) - for subsamp in CHROMA_SUBSAMP: - print(' PIPE_VIDEO_CHROMA_FORMAT_%s,' % subsamp, file=sys.stdout3) - print(' PIPE_VIDEO_CHROMA_FORMAT_NONE,', file=sys.stdout3) - print('};', file=sys.stdout3) - print(file=sys.stdout3) - print('static inline enum pipe_video_chroma_format', file=sys.stdout3) - print('pipe_format_to_chroma_format(enum pipe_format format)', file=sys.stdout3) - print('{', file=sys.stdout3) - print(' switch(format) {', file=sys.stdout3) - for subsamp in CHROMA_SUBSAMP: - format_count = 0 - for f in formats: - if f.colorspace == 'YUV': - yuv_split_name = f.name.split('_') - if yuv_split_name[-2] == subsamp: - print(' case %s:' % f.name, file=sys.stdout3) - format_count += 1 - if format_count > 0: - print(' return PIPE_VIDEO_CHROMA_FORMAT_%s;' % subsamp, file=sys.stdout3) - print(' default:', file=sys.stdout3) - print(' return PIPE_VIDEO_CHROMA_FORMAT_NONE;', file=sys.stdout3) - print(' }', file=sys.stdout3) - print('}', file=sys.stdout3) - def chroma_horizontal_subsample_factor(subsample_name): assert(subsample_name in CHROMA_SUBSAMP) if subsample_name in ['420', '422']: @@ -530,8 +507,6 @@ def write_type_conv_helpers(formats): print(file=sys.stdout3) def write_format_inline_helpers(formats): - write_to_chroma_format(formats) - print(file=sys.stdout3) write_get_plane_format(formats) print(file=sys.stdout3) write_get_plane_width_height(formats) @@ -656,6 +631,7 @@ def write_format_table(formats): u_format_pack.print_channels(format, do_channel_array) u_format_pack.print_channels(format, do_swizzle_array) print(" .colorspace = %s," % (colorspace_map(format.colorspace),)) + print(" .subsampling = %s," % (subsampling_map(format.subsampling),)) if format.srgb_equivalent: print(" .srgb_equivalent = %s,\t/* srgb_equivalent */" % format.srgb_equivalent.name) elif format.linear_equivalent: diff --git a/src/util/tests/format/u_format_test.c b/src/util/tests/format/u_format_test.c index 81474571e63..51c6d1507c3 100644 --- a/src/util/tests/format/u_format_test.c +++ b/src/util/tests/format/u_format_test.c @@ -731,6 +731,25 @@ test_format_norm_flags(const struct util_format_description *format_desc) return success; } + +/* Test that subsampling is set up correctly */ +static bool +test_format_subsampling(const struct util_format_description *format_desc) +{ + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV || + (format_desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED && + format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB)) { + /* subsampled non-RGB and YUV formats must specify a subsampling format */ + if (format_desc->subsampling == PIPE_VIDEO_CHROMA_FORMAT_NONE) { + fprintf(stderr, "%s is not subsampled, as it should be.\n", + format_desc->name); + return false; + } + } + + return true; +} + typedef bool (*test_func_t)(const struct util_format_description *format_desc, const struct util_format_test_case *test); @@ -856,6 +875,7 @@ test_all(void) TEST_ONE_PACK_FUNC(pack_s_8uint); TEST_FORMAT_METADATA(norm_flags); + TEST_FORMAT_METADATA(subsampling); # undef TEST_ONE_FUNC # undef TEST_ONE_FORMAT