radv: Add VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 rendering support.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6831>
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 6f0a6a0..8023956 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -1196,6 +1196,10 @@
 				sx_blend_opt_epsilon |= V_028758_10BIT_FORMAT << (i * 4);
 			}
 			break;
+		case V_028C70_COLOR_5_9_9_9:
+			if (spi_format == V_028714_SPI_SHADER_FP16_ABGR)
+				sx_ps_downconvert |= V_028754_SX_RT_EXPORT_9_9_9_E5 << (i * 4);
+			break;
 		}
 	}
 
diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
index 6f7708d..ed9e30f 100644
--- a/src/amd/vulkan/radv_formats.c
+++ b/src/amd/vulkan/radv_formats.c
@@ -32,6 +32,7 @@
 #include "util/u_half.h"
 #include "util/format_srgb.h"
 #include "util/format_r11g11b10f.h"
+#include "util/format_rgb9e5.h"
 
 uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc,
 					  int first_non_void)
@@ -565,7 +566,8 @@
 		num_format != ~0;
 }
 
-bool radv_is_colorbuffer_format_supported(VkFormat format, bool *blendable)
+bool radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice,
+                                          VkFormat format, bool *blendable)
 {
 	const struct vk_format_description *desc = vk_format_description(format);
 	uint32_t color_format = radv_translate_colorformat(format);
@@ -580,6 +582,10 @@
 		*blendable = false;
 	} else
 		*blendable = true;
+
+	if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 && pdevice->rad_info.chip_class < GFX10_3)
+		return false;
+
 	return color_format != V_028C70_COLOR_INVALID &&
 		color_swap != ~0U &&
 		color_num_format != ~0;
@@ -727,7 +733,7 @@
 				linear &= ~VK_FORMAT_FEATURE_BLIT_SRC_BIT;
 			}
 		}
-		if (radv_is_colorbuffer_format_supported(format, &blendable)) {
+		if (radv_is_colorbuffer_format_supported(physical_device, format, &blendable)) {
 			linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
 			tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
 			if (blendable) {
@@ -797,6 +803,9 @@
 	if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
 		return V_028C70_COLOR_10_11_11;
 
+	if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
+		return V_028C70_COLOR_5_9_9_9;
+
 	if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
 		return V_028C70_COLOR_INVALID;
 
@@ -930,6 +939,9 @@
 	if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
 		return V_028C70_SWAP_STD;
 
+	if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
+		return V_028C70_SWAP_STD;
+
 	if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
 		return ~0U;
 
@@ -991,6 +1003,10 @@
 		clear_vals[0] = float3_to_r11g11b10f(value->float32);
 		clear_vals[1] = 0;
 		return true;
+	} else if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
+		clear_vals[0] = float3_to_rgb9e5(value->float32);
+		clear_vals[1] = 0;
+		return true;
 	}
 
 	if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) {
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 44793aa..27601aa 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -222,8 +222,8 @@
 
 	/* Determine if the formats are DCC compatible. */
 	dcc_compatible_formats =
-		radv_is_colorbuffer_format_supported(format,
-						     &blendable);
+		radv_is_colorbuffer_format_supported(device->physical_device,
+						     format, &blendable);
 
 	if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
 		const struct VkImageFormatListCreateInfo *format_list =
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 90012cd..4fcb57c 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1813,7 +1813,8 @@
 bool radv_format_pack_clear_color(VkFormat format,
 				  uint32_t clear_vals[2],
 				  VkClearColorValue *value);
-bool radv_is_colorbuffer_format_supported(VkFormat format, bool *blendable);
+bool radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice,
+                                          VkFormat format, bool *blendable);
 bool radv_dcc_formats_compatible(VkFormat format1,
                                  VkFormat format2);
 bool radv_device_supports_etc(struct radv_physical_device *physical_device);