+
+ assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
+ assert(vk_format_aspects(vk_format) == VK_IMAGE_ASPECT_COLOR_BIT);
+
+ const struct isl_format_layout *isl_layout =
+ isl_format_get_layout(format.isl_format);
+
+ if (tiling == VK_IMAGE_TILING_OPTIMAL &&
+ !util_is_power_of_two(isl_layout->bs)) {
+ /* Tiled formats *must* be power-of-two because we need up upload
+ * them with the render pipeline. For 3-channel formats, we fix
+ * this by switching them over to RGBX or RGBA formats under the
+ * hood.
+ */
+ enum isl_format rgbx = isl_format_rgb_to_rgbx(format.isl_format);
+ if (rgbx != ISL_FORMAT_UNSUPPORTED) {
+ format.isl_format = rgbx;
+ } else {
+ format.isl_format = isl_format_rgb_to_rgba(format.isl_format);
+ format.swizzle = (struct anv_format_swizzle) RGB1;
+ }
+ }
+
+ /* The B4G4R4A4 format isn't available prior to Sky Lake so we have to fall
+ * back to a format with a more complex swizzle.
+ */
+ if (vk_format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 && devinfo->gen < 9) {
+ return (struct anv_format) {
+ .isl_format = ISL_FORMAT_B4G4R4A4_UNORM,
+ .swizzle = ISL_SWIZZLE(GREEN, RED, ALPHA, BLUE),
+ };
+ }
+
+ return format;