+struct iris_format_info
+iris_format_for_usage(const struct gen_device_info *devinfo,
+ enum pipe_format pformat,
+ isl_surf_usage_flags_t usage)
+{
+ enum isl_format format = iris_isl_format_for_pipe_format(pformat);
+ const struct isl_format_layout *fmtl = isl_format_get_layout(format);
+ struct isl_swizzle swizzle = ISL_SWIZZLE_IDENTITY;
+
+ if (!util_format_is_srgb(pformat)) {
+ if (util_format_is_intensity(pformat)) {
+ swizzle = ISL_SWIZZLE(RED, RED, RED, RED);
+ } else if (util_format_is_luminance(pformat)) {
+ swizzle = ISL_SWIZZLE(RED, RED, RED, ONE);
+ } else if (util_format_is_luminance_alpha(pformat)) {
+ swizzle = ISL_SWIZZLE(RED, RED, RED, GREEN);
+ } else if (util_format_is_alpha(pformat)) {
+ swizzle = ISL_SWIZZLE(ZERO, ZERO, ZERO, RED);
+ }
+ }
+
+ /* When faking RGBX pipe formats with RGBA ISL formats, override alpha. */
+ if (!util_format_has_alpha(pformat) && fmtl->channels.a.type != ISL_VOID) {
+ swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE);
+ }
+
+ if ((usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
+ pformat == PIPE_FORMAT_A8_UNORM) {
+ /* Most of the hardware A/LA formats are not renderable, except
+ * for A8_UNORM. SURFACE_STATE's shader channel select fields
+ * cannot be used to swap RGB and A channels when rendering (as
+ * it could impact alpha blending), so we have to use the actual
+ * A8_UNORM format when rendering.
+ */
+ format = ISL_FORMAT_A8_UNORM;
+ swizzle = ISL_SWIZZLE_IDENTITY;
+ }
+
+ /* We choose RGBA over RGBX for rendering the hardware doesn't support
+ * rendering to RGBX. However, when this internal override is used on Gen9+,
+ * fast clears don't work correctly.
+ *
+ * i965 fixes this by pretending to not support RGBX formats, and the higher
+ * layers of Mesa pick the RGBA format instead. Gallium doesn't work that
+ * way, and might choose a different format, like BGRX instead of RGBX,
+ * which will also cause problems when sampling from a surface fast cleared
+ * as RGBX. So we always choose RGBA instead of RGBX explicitly
+ * here.
+ */
+ if (isl_format_is_rgbx(format) &&
+ !isl_format_supports_rendering(devinfo, format)) {
+ format = isl_format_rgbx_to_rgba(format);
+ swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE);
+ }
+
+ return (struct iris_format_info) { .fmt = format, .swizzle = swizzle };
+}
+
+/**
+ * The pscreen->is_format_supported() driver hook.
+ *
+ * Returns true if the given format is supported for the given usage
+ * (PIPE_BIND_*) and sample count.
+ */