gallium/util: add planar format layouts and helpers
authorMarek Olšák <marek.olsak@amd.com>
Tue, 27 Aug 2019 00:10:43 +0000 (20:10 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 9 Oct 2019 21:06:54 +0000 (17:06 -0400)
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/gallium/auxiliary/util/u_format.c
src/gallium/auxiliary/util/u_format.csv
src/gallium/auxiliary/util/u_format.h
src/gallium/auxiliary/util/u_format_pack.py

index 5d3ee861a7352146bf19828fdbb0d6c0a4383702..73c25d727bab071883935517096af76e6847e494 100644 (file)
@@ -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;
+}
index 0a840a2c3576fc3449cded6ac3e152d0631e0f1d..926f881e590fd2bc97a5ddb8230d554ea3ee1a81 100644 (file)
@@ -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
index 115656a70347fbcbd57952142ebfa428b6287edd..d9e232925f24066c2d4c759f3cb55c11d341ac4d 100644 (file)
@@ -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).
index aae6b5ab9f016541154c5203bab357410526abf2..75951eb4bdbf0bf1a3ba3208743fbe044ed04f65 100644 (file)
@@ -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):