diff --git a/src/panfrost/lib/pan_afbc.h b/src/panfrost/lib/pan_afbc.h index 0eb79241e28..2099058439d 100644 --- a/src/panfrost/lib/pan_afbc.h +++ b/src/panfrost/lib/pan_afbc.h @@ -81,6 +81,21 @@ enum pan_afbc_mode { PAN_AFBC_MODE_R11G11B10, PAN_AFBC_MODE_S8, + /* YUV special modes */ + PAN_AFBC_MODE_YUV420_6C8, + PAN_AFBC_MODE_YUV420_2C8, + PAN_AFBC_MODE_YUV420_1C8, + PAN_AFBC_MODE_YUV420_6C10, + PAN_AFBC_MODE_YUV420_2C10, + PAN_AFBC_MODE_YUV420_1C10, + + PAN_AFBC_MODE_YUV422_4C8, + PAN_AFBC_MODE_YUV422_2C8, + PAN_AFBC_MODE_YUV422_1C8, + PAN_AFBC_MODE_YUV422_4C10, + PAN_AFBC_MODE_YUV422_2C10, + PAN_AFBC_MODE_YUV422_1C10, + /* Sentintel signalling a format that cannot be compressed */ PAN_AFBC_MODE_INVALID }; @@ -301,8 +316,28 @@ pan_afbc_unswizzled_format(unsigned arch, enum pipe_format format) static inline enum pan_afbc_mode pan_afbc_format(unsigned arch, enum pipe_format format, unsigned plane_idx) { - /* Revisit when adding YUV support. */ - assert(plane_idx == 0); + assert(plane_idx < util_format_get_num_planes(format)); + + switch (format) { + case PIPE_FORMAT_R8_G8B8_420_UNORM: + case PIPE_FORMAT_R8_B8G8_420_UNORM: + return plane_idx == 0 ? PAN_AFBC_MODE_YUV420_1C8 + : PAN_AFBC_MODE_YUV420_2C8; + case PIPE_FORMAT_R8_G8_B8_420_UNORM: + case PIPE_FORMAT_R8_B8_G8_420_UNORM: + return PAN_AFBC_MODE_YUV420_1C8; + case PIPE_FORMAT_R8_G8B8_422_UNORM: + return plane_idx == 0 ? PAN_AFBC_MODE_YUV422_1C8 + : PAN_AFBC_MODE_YUV422_2C8; + case PIPE_FORMAT_R10_G10B10_420_UNORM: + return plane_idx == 0 ? PAN_AFBC_MODE_YUV420_1C10 + : PAN_AFBC_MODE_YUV420_2C10; + case PIPE_FORMAT_R10_G10B10_422_UNORM: + return plane_idx == 0 ? PAN_AFBC_MODE_YUV422_1C10 + : PAN_AFBC_MODE_YUV422_2C10; + default: + break; + } /* sRGB does not change the pixel format itself, only the * interpretation. The interpretation is handled by conversion hardware @@ -454,6 +489,30 @@ pan_afbc_compression_mode(enum pipe_format format, unsigned plane_idx) return MALI_AFBC_COMPRESSION_MODE_R11G11B10; case PAN_AFBC_MODE_S8: return MALI_AFBC_COMPRESSION_MODE_S8; + case PAN_AFBC_MODE_YUV420_6C8: + return MALI_AFBC_COMPRESSION_MODE_YUV420_6C8; + case PAN_AFBC_MODE_YUV420_2C8: + return MALI_AFBC_COMPRESSION_MODE_YUV420_2C8; + case PAN_AFBC_MODE_YUV420_1C8: + return MALI_AFBC_COMPRESSION_MODE_YUV420_1C8; + case PAN_AFBC_MODE_YUV420_6C10: + return MALI_AFBC_COMPRESSION_MODE_YUV420_6C10; + case PAN_AFBC_MODE_YUV420_2C10: + return MALI_AFBC_COMPRESSION_MODE_YUV420_2C10; + case PAN_AFBC_MODE_YUV420_1C10: + return MALI_AFBC_COMPRESSION_MODE_YUV420_1C10; + case PAN_AFBC_MODE_YUV422_4C8: + return MALI_AFBC_COMPRESSION_MODE_YUV422_4C8; + case PAN_AFBC_MODE_YUV422_2C8: + return MALI_AFBC_COMPRESSION_MODE_YUV422_2C8; + case PAN_AFBC_MODE_YUV422_1C8: + return MALI_AFBC_COMPRESSION_MODE_YUV422_1C8; + case PAN_AFBC_MODE_YUV422_4C10: + return MALI_AFBC_COMPRESSION_MODE_YUV422_4C10; + case PAN_AFBC_MODE_YUV422_2C10: + return MALI_AFBC_COMPRESSION_MODE_YUV422_2C10; + case PAN_AFBC_MODE_YUV422_1C10: + return MALI_AFBC_COMPRESSION_MODE_YUV422_1C10; case PAN_AFBC_MODE_INVALID: unreachable("Invalid AFBC format"); } diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index 94d096d9aaa..eabc1a03a08 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -371,6 +371,8 @@ pan_clump_format(enum pipe_format format) case PIPE_FORMAT_G8R8_B8R8_UNORM: case PIPE_FORMAT_R8B8_R8G8_UNORM: case PIPE_FORMAT_B8R8_G8R8_UNORM: + case PIPE_FORMAT_R8_G8B8_422_UNORM: + case PIPE_FORMAT_R8_B8G8_422_UNORM: return MALI_CLUMP_FORMAT_Y8_UV8_422; case PIPE_FORMAT_R8_G8B8_420_UNORM: case PIPE_FORMAT_R8_B8G8_420_UNORM: @@ -558,7 +560,7 @@ pan_emit_iview_plane(const struct pan_image_view *iview, cfg.afbc.tiled_header = (props->modifier & AFBC_FORMAT_MOD_TILED); cfg.afbc.prefetch = true; cfg.afbc.compression_mode = - pan_afbc_compression_mode(iview->format, 0); + pan_afbc_compression_mode(iview->format, plane_index); cfg.afbc.header_stride = layout->slices[level].afbc.header_size_B; } else if (afrc) { #if PAN_ARCH >= 10