radv: Add logic for multisample format descriptions.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Sun, 15 Jul 2018 23:31:09 +0000 (01:31 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 25 Apr 2019 19:56:20 +0000 (19:56 +0000)
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/vulkan/radv_formats.c
src/amd/vulkan/vk_format.h
src/amd/vulkan/vk_format_parse.py
src/amd/vulkan/vk_format_table.py

index 773600b7f5dec56e5e10c0687809a8469d132e50..8095128e17abbe4cd899f210a1674f6352712652 100644 (file)
@@ -39,6 +39,8 @@ uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *de
        unsigned type;
        int i;
 
+       assert(desc->layout != VK_FORMAT_LAYOUT_MULTIPLANE);
+
        if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
                return V_008F0C_BUF_DATA_FORMAT_10_11_11;
 
@@ -110,6 +112,8 @@ uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *de
 uint32_t radv_translate_buffer_numformat(const struct vk_format_description *desc,
                                         int first_non_void)
 {
+       assert(desc->layout != VK_FORMAT_LAYOUT_MULTIPLANE);
+
        if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
                return V_008F0C_BUF_NUM_FORMAT_FLOAT;
 
@@ -146,6 +150,8 @@ uint32_t radv_translate_tex_dataformat(VkFormat format,
        bool uniform = true;
        int i;
 
+       assert(vk_format_get_plane_count(format) == 1);
+
        if (!desc)
                return ~0;
        /* Colorspace (return non-RGB formats directly). */
@@ -371,6 +377,8 @@ uint32_t radv_translate_tex_numformat(VkFormat format,
                                      const struct vk_format_description *desc,
                                      int first_non_void)
 {
+       assert(vk_format_get_plane_count(format) == 1);
+
        switch (format) {
        case VK_FORMAT_D24_UNORM_S8_UINT:
                return V_008F14_IMG_NUM_FORMAT_UNORM;
@@ -433,6 +441,9 @@ uint32_t radv_translate_color_numformat(VkFormat format,
                                        int first_non_void)
 {
        unsigned ntype;
+
+       assert(vk_format_get_plane_count(format) == 1);
+
        if (first_non_void == -1 || desc->channel[first_non_void].type == VK_FORMAT_TYPE_FLOAT)
                ntype = V_028C70_NUMBER_FLOAT;
        else {
index e89896c89693b7c012af038e435006086b93f4ae..0b62ea721fa64b5a2a86968f52ed5a5d0752c854 100644 (file)
@@ -74,7 +74,12 @@ enum vk_format_layout {
        /**
         * Everything else that doesn't fit in any of the above layouts.
         */
-       VK_FORMAT_LAYOUT_OTHER = 9
+       VK_FORMAT_LAYOUT_OTHER = 9,
+
+       /**
+        * Formats that contain multiple planes.
+        */
+       VK_FORMAT_LAYOUT_MULTIPLANE = 10,
 };
 
 struct vk_format_block
@@ -133,6 +138,11 @@ struct vk_format_description
        unsigned char swizzle[4];
 
        enum vk_format_colorspace colorspace;
+
+       unsigned plane_count:2;
+       unsigned width_divisor:2;
+       unsigned height_divisor:2;
+       VkFormat plane_formats[3];
 };
 
 extern const struct vk_format_description vk_format_description_table[];
@@ -548,4 +558,28 @@ vk_format_get_nr_components(VkFormat format)
        return desc->nr_channels;
 }
 
+static inline unsigned
+vk_format_get_plane_count(VkFormat format)
+{
+       const struct vk_format_description *desc = vk_format_description(format);
+
+       return desc->plane_count;
+}
+
+static inline VkFormat
+vk_format_get_plane_format(VkFormat format, unsigned plane_id)
+{
+       const struct vk_format_description *desc = vk_format_description(format);
+
+       if (desc->layout != VK_FORMAT_LAYOUT_MULTIPLANE) {
+               assert(plane_id == 0);
+               return format;
+       }
+
+       assert(plane_id < desc->plane_count);
+
+       return desc->plane_formats[plane_id];
+}
+
+
 #endif /* VK_FORMAT_H */
index ba730388a7b302fd3f7f34aa3b1b572b9a24ad7a..506c723ea515f0f615239f58ef6c3d82cf7bd99f 100644 (file)
@@ -113,7 +113,7 @@ class Channel:
 class Format:
     '''Describe a pixel format.'''
 
-    def __init__(self, name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace):
+    def __init__(self, name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace, width_divisor, height_divisor, plane_formats):
         self.name = name
         self.layout = layout
         self.block_width = block_width
@@ -124,6 +124,13 @@ class Format:
         self.be_swizzles = be_swizzles
         self.name = name
         self.colorspace = colorspace
+        self.plane_count = len(plane_formats)
+        self.width_divisor = width_divisor
+        self.height_divisor = height_divisor
+        self.plane_formats = plane_formats
+
+        while len(self.plane_formats) < 3:
+            self.plane_formats.append("VK_FORMAT_UNDEFINED")
 
     def __str__(self):
         return self.name
@@ -334,6 +341,16 @@ def _parse_channels(fields, layout, colorspace, swizzles):
 
     return channels
 
+def parse_plane_divisor(format):
+    if format == '444':
+        return (1, 1)
+    elif format == '422':
+        return (2, 1)
+    elif format == '420':
+        return (2, 2)
+    else:
+        return (1, 1)
+
 def parse(filename):
     '''Parse the format description in CSV format in terms of the
     Channel and Format classes above.'''
@@ -354,10 +371,9 @@ def parse(filename):
         fields = [field.strip() for field in line.split(',')]
         if len (fields) < 10:
            continue
-        if len (fields) == 10:
-           fields += fields[4:9]
-        assert len (fields) == 15
-        
+
+        be_fields = fields[4:9]
+
         name = fields[0]
         layout = fields[1]
         block_width, block_height = map(int, fields[2:4])
@@ -366,8 +382,8 @@ def parse(filename):
         le_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
         le_channels = _parse_channels(fields[4:8], layout, colorspace, le_swizzles)
 
-        be_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[14]]
-        be_channels = _parse_channels(fields[10:14], layout, colorspace, be_swizzles)
+        be_swizzles = [_swizzle_parse_map[swizzle] for swizzle in be_fields[4]]
+        be_channels = _parse_channels(be_fields, layout, colorspace, be_swizzles)
 
         le_shift = 0
         for channel in le_channels:
@@ -383,7 +399,18 @@ def parse(filename):
         for i in range(4):
             assert (le_swizzles[i] != SWIZZLE_NONE) == (be_swizzles[i] != SWIZZLE_NONE)
 
-        format = Format(name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace)
+        width_divisor = 1
+        height_divisor = 1
+        plane_formats = [name]
+        if layout == "multiplane":
+            plane_formats = []
+            (width_divisor, height_divisor) = parse_plane_divisor(fields[10])
+
+            for i in range(11, len(fields)):
+                plane_formats.append(fields[i])
+            assert (len(plane_formats) > 1)
+
+        format = Format(name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace, width_divisor, height_divisor, plane_formats)
         formats.append(format)
     return formats
 
index 44c3439e9fc76c4be5be2674f3347f1f4a9e8046..420c3f96abc4943a90590243995ed840ea177eb9 100644 (file)
@@ -140,9 +140,13 @@ def write_format_table(formats):
         print_channels(format, do_channel_array)
         print_channels(format, do_swizzle_array)
         print("   %s," % (colorspace_map(format.colorspace),))
+        print("   %u,\t/* plane_count */" % (format.plane_count))
+        print("   %u,\t/* width_divisor */" % (format.width_divisor))
+        print("   %u,\t/* height_divisor */" % (format.height_divisor))
+        print("   {%s, %s, %s}," % (format.plane_formats[0], format.plane_formats[1], format.plane_formats[2]))
         print("};")
         print()
-        
+
     print("const struct vk_format_description *")
     print("vk_format_description(VkFormat format)")
     print("{")