From d3225e533fe3ac90cdded81e4f7df55082bc387e Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 16 Jul 2018 01:31:09 +0200 Subject: [PATCH] radv: Add logic for multisample format descriptions. Reviewed-by: Samuel Pitoiset --- src/amd/vulkan/radv_formats.c | 11 ++++++++ src/amd/vulkan/vk_format.h | 36 +++++++++++++++++++++++++- src/amd/vulkan/vk_format_parse.py | 43 +++++++++++++++++++++++++------ src/amd/vulkan/vk_format_table.py | 6 ++++- 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index 773600b7f5d..8095128e17a 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -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 { diff --git a/src/amd/vulkan/vk_format.h b/src/amd/vulkan/vk_format.h index e89896c8969..0b62ea721fa 100644 --- a/src/amd/vulkan/vk_format.h +++ b/src/amd/vulkan/vk_format.h @@ -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 */ diff --git a/src/amd/vulkan/vk_format_parse.py b/src/amd/vulkan/vk_format_parse.py index ba730388a7b..506c723ea51 100644 --- a/src/amd/vulkan/vk_format_parse.py +++ b/src/amd/vulkan/vk_format_parse.py @@ -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 diff --git a/src/amd/vulkan/vk_format_table.py b/src/amd/vulkan/vk_format_table.py index 44c3439e9fc..420c3f96abc 100644 --- a/src/amd/vulkan/vk_format_table.py +++ b/src/amd/vulkan/vk_format_table.py @@ -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("{") -- 2.30.2