From: Marek Olšák Date: Tue, 27 Aug 2019 00:10:43 +0000 (-0400) Subject: gallium/util: add planar format layouts and helpers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=20f132e5eff2d59d02088f6b1e42a56cdeee117c;p=mesa.git gallium/util: add planar format layouts and helpers Reviewed-by: Bas Nieuwenhuizen --- diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c index 5d3ee861a73..73c25d727ba 100644 --- a/src/gallium/auxiliary/util/u_format.c +++ b/src/gallium/auxiliary/util/u_format.c @@ -39,6 +39,7 @@ #include "util/u_math.h" #include "pipe/p_defines.h" +#include "pipe/p_screen.h" boolean @@ -968,3 +969,25 @@ util_format_snorm8_to_sint8(enum pipe_format format) return format; } } + +bool +util_format_planar_is_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned storage_sample_count, + unsigned bind) +{ + unsigned num_planes = util_format_get_num_planes(format); + assert(num_planes >= 2); + + for (unsigned i = 0; i < num_planes; i++) { + if (!screen->is_format_supported(screen, + util_format_get_plane_format(format, i), + target, sample_count, + storage_sample_count, bind)) + return false; + } + + return true; +} diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 0a840a2c357..926f881e590 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -356,13 +356,13 @@ PIPE_FORMAT_R10G10B10X2_USCALED , plain, 1, 1, 1, u10 , u10 , u10 , x2 , xy # A.k.a. D3DDECLTYPE_DEC3N PIPE_FORMAT_R10G10B10X2_SNORM , plain, 1, 1, 1, sn10, sn10, sn10 , x2 , xyz1, rgb, x2 , sn10, sn10, sn10, wzy1 -PIPE_FORMAT_YV12 , other, 1, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv -PIPE_FORMAT_YV16 , other, 1, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv -PIPE_FORMAT_IYUV , other, 1, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv -PIPE_FORMAT_NV12 , other, 1, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv -PIPE_FORMAT_NV21 , other, 1, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv +PIPE_FORMAT_YV12 , planar3, 1, 1, 1, , , , , xyzw, yuv +PIPE_FORMAT_YV16 , planar3, 1, 1, 1, , , , , xyzw, yuv +PIPE_FORMAT_IYUV , planar3, 1, 1, 1, , , , , xyzw, yuv +PIPE_FORMAT_NV12 , planar2, 1, 1, 1, , , , , xyzw, yuv +PIPE_FORMAT_NV21 , planar2, 1, 1, 1, , , , , xyzw, yuv -PIPE_FORMAT_P016 , other, 1, 1, 1, x16 , x16 , , , xyzw, yuv +PIPE_FORMAT_P016 , planar2, 1, 1, 1, , , , , xyzw, yuv # Usually used to implement IA44 and AI44 formats in video decoding PIPE_FORMAT_A4R4_UNORM , plain, 1, 1, 1, un4 , un4 , , , y00x, rgb, un4, un4 , , , x00y diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 115656a7034..d9e232925f2 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -35,6 +35,7 @@ #include "util/u_debug.h" union pipe_color_union; +struct pipe_screen; #ifdef __cplusplus @@ -87,6 +88,10 @@ enum util_format_layout { UTIL_FORMAT_LAYOUT_ATC, + /** Formats with 2 or more planes. */ + UTIL_FORMAT_LAYOUT_PLANAR2, + UTIL_FORMAT_LAYOUT_PLANAR3, + /** * Everything else that doesn't fit in any of the above layouts. */ @@ -1264,6 +1269,79 @@ util_format_luminance_to_red(enum pipe_format format) } } +static inline unsigned +util_format_get_num_planes(enum pipe_format format) +{ + switch (util_format_description(format)->layout) { + case UTIL_FORMAT_LAYOUT_PLANAR3: + return 3; + case UTIL_FORMAT_LAYOUT_PLANAR2: + return 2; + default: + return 1; + } +} + +static inline enum pipe_format +util_format_get_plane_format(enum pipe_format format, unsigned plane) +{ + switch (format) { + case PIPE_FORMAT_YV12: + case PIPE_FORMAT_YV16: + case PIPE_FORMAT_IYUV: + return PIPE_FORMAT_R8_UNORM; + case PIPE_FORMAT_NV12: + return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM; + case PIPE_FORMAT_NV21: + return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM; + case PIPE_FORMAT_P016: + return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM; + default: + return format; + } +} + +static inline unsigned +util_format_get_plane_width(enum pipe_format format, unsigned plane, + unsigned width) +{ + switch (format) { + case PIPE_FORMAT_YV12: + case PIPE_FORMAT_YV16: + case PIPE_FORMAT_IYUV: + case PIPE_FORMAT_NV12: + case PIPE_FORMAT_NV21: + case PIPE_FORMAT_P016: + return !plane ? width : (width + 1) / 2; + default: + return width; + } +} + +static inline unsigned +util_format_get_plane_height(enum pipe_format format, unsigned plane, + unsigned height) +{ + switch (format) { + case PIPE_FORMAT_YV12: + case PIPE_FORMAT_IYUV: + case PIPE_FORMAT_NV12: + case PIPE_FORMAT_NV21: + case PIPE_FORMAT_P016: + return !plane ? height : (height + 1) / 2; + case PIPE_FORMAT_YV16: + default: + return height; + } +} + +bool util_format_planar_is_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned storage_sample_count, + unsigned bind); + /** * Return the number of components stored. * Formats with block size != 1x1 will always have 1 component (the block). diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index aae6b5ab9f0..75951eb4bdb 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -694,7 +694,7 @@ def generate_format_fetch(format, dst_channel, dst_native_type, dst_suffix): def is_format_hand_written(format): - return format.layout in ('s3tc', 'rgtc', 'etc', 'bptc', 'astc', 'atc', 'subsampled', 'other') or format.colorspace == ZS + return format.layout != PLAIN or format.colorspace == ZS def generate(formats):