drm/msm/sde: add p010 format support in sde
Add MOD_QCOM_DX modifier on top of DRM_FORMAT_NV12 base format and update plane size calculation to support linear and compressed p010 buffers. Change-Id: I93bd9557e5c4a4a038891f24730edbbec1dba262 Signed-off-by: Alexander Beykun <abeykun@codeaurora.org>
This commit is contained in:
parent
6f56b2a9c8
commit
be55dab201
2 changed files with 146 additions and 78 deletions
|
@ -11,12 +11,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <uapi/drm/drm_fourcc.h>
|
#include <uapi/drm/drm_fourcc.h>
|
||||||
|
#include <uapi/media/msm_media_info.h>
|
||||||
|
|
||||||
#include "sde_kms.h"
|
#include "sde_kms.h"
|
||||||
#include "sde_formats.h"
|
#include "sde_formats.h"
|
||||||
|
|
||||||
#define SDE_UBWC_META_MACRO_W_H 16
|
#define SDE_UBWC_META_MACRO_W_H 16
|
||||||
#define SDE_UBWC_META_BLOCK_SIZE 256
|
#define SDE_UBWC_META_BLOCK_SIZE 256
|
||||||
|
#define SDE_UBWC_PLANE_SIZE_ALIGNMENT 4096
|
||||||
|
|
||||||
#define SDE_MAX_IMG_WIDTH 0x3FFF
|
#define SDE_MAX_IMG_WIDTH 0x3FFF
|
||||||
#define SDE_MAX_IMG_HEIGHT 0x3FFF
|
#define SDE_MAX_IMG_HEIGHT 0x3FFF
|
||||||
|
|
||||||
|
@ -81,6 +84,23 @@ alpha, chroma, count, bp, flg, fm, np) \
|
||||||
.num_planes = np \
|
.num_planes = np \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
|
||||||
|
{ \
|
||||||
|
.base.pixel_format = DRM_FORMAT_ ## fmt, \
|
||||||
|
.fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
|
||||||
|
.alpha_enable = false, \
|
||||||
|
.element = { (e0), (e1), 0, 0 }, \
|
||||||
|
.bits = { g, b, r, a }, \
|
||||||
|
.chroma_sample = chroma, \
|
||||||
|
.unpack_align_msb = 1, \
|
||||||
|
.unpack_tight = 0, \
|
||||||
|
.unpack_count = 2, \
|
||||||
|
.bpp = 2, \
|
||||||
|
.fetch_mode = fm, \
|
||||||
|
.flag = flg, \
|
||||||
|
.num_planes = np \
|
||||||
|
}
|
||||||
|
|
||||||
#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
|
#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
|
||||||
flg, fm, np) \
|
flg, fm, np) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -99,6 +119,16 @@ flg, fm, np) \
|
||||||
.num_planes = np \
|
.num_planes = np \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct sde_media_color_map - maps drm format to media format
|
||||||
|
* @format: DRM base pixel format
|
||||||
|
* @color: Media API color related to DRM format
|
||||||
|
*/
|
||||||
|
struct sde_media_color_map {
|
||||||
|
uint32_t format;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
|
||||||
static const struct sde_format sde_format_map[] = {
|
static const struct sde_format sde_format_map[] = {
|
||||||
INTERLEAVED_RGB_FMT(ARGB8888,
|
INTERLEAVED_RGB_FMT(ARGB8888,
|
||||||
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
||||||
|
@ -421,6 +451,22 @@ static const struct sde_format sde_format_map_ubwc[] = {
|
||||||
SDE_FETCH_UBWC, 4),
|
SDE_FETCH_UBWC, 4),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sde_format sde_format_map_p010[] = {
|
||||||
|
PSEUDO_YUV_FMT_LOOSE(NV12,
|
||||||
|
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
||||||
|
C1_B_Cb, C2_R_Cr,
|
||||||
|
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
|
||||||
|
SDE_FETCH_LINEAR, 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sde_format sde_format_map_p010_ubwc[] = {
|
||||||
|
PSEUDO_YUV_FMT_LOOSE(NV12,
|
||||||
|
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
||||||
|
C1_B_Cb, C2_R_Cr,
|
||||||
|
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
|
||||||
|
SDE_FETCH_UBWC, 4),
|
||||||
|
};
|
||||||
|
|
||||||
/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
|
/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
|
||||||
* Note: Not using the drm_format_*_subsampling since we have formats
|
* Note: Not using the drm_format_*_subsampling since we have formats
|
||||||
*/
|
*/
|
||||||
|
@ -452,6 +498,37 @@ static void _sde_get_v_h_subsample_rate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _sde_format_get_media_color_ubwc(const struct sde_format *fmt)
|
||||||
|
{
|
||||||
|
static const struct sde_media_color_map sde_media_ubwc_map[] = {
|
||||||
|
{DRM_FORMAT_RGBA8888, COLOR_FMT_RGBA8888_UBWC},
|
||||||
|
{DRM_FORMAT_RGBX8888, COLOR_FMT_RGBA8888_UBWC},
|
||||||
|
{DRM_FORMAT_RGBA1010102, COLOR_FMT_RGBA1010102_UBWC},
|
||||||
|
{DRM_FORMAT_RGBX1010102, COLOR_FMT_RGBA1010102_UBWC},
|
||||||
|
{DRM_FORMAT_RGB565, COLOR_FMT_RGB565_UBWC},
|
||||||
|
};
|
||||||
|
int color_fmt = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
|
||||||
|
if (SDE_FORMAT_IS_DX(fmt)) {
|
||||||
|
if (fmt->unpack_tight)
|
||||||
|
color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
|
||||||
|
else
|
||||||
|
color_fmt = COLOR_FMT_P010_UBWC;
|
||||||
|
} else
|
||||||
|
color_fmt = COLOR_FMT_NV12_UBWC;
|
||||||
|
return color_fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sde_media_ubwc_map); ++i)
|
||||||
|
if (fmt->base.pixel_format == sde_media_ubwc_map[i].format) {
|
||||||
|
color_fmt = sde_media_ubwc_map[i].color;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return color_fmt;
|
||||||
|
}
|
||||||
|
|
||||||
static int _sde_format_get_plane_sizes_ubwc(
|
static int _sde_format_get_plane_sizes_ubwc(
|
||||||
const struct sde_format *fmt,
|
const struct sde_format *fmt,
|
||||||
const uint32_t width,
|
const uint32_t width,
|
||||||
|
@ -459,6 +536,7 @@ static int _sde_format_get_plane_sizes_ubwc(
|
||||||
struct sde_hw_fmt_layout *layout)
|
struct sde_hw_fmt_layout *layout)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int color;
|
||||||
|
|
||||||
memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
|
memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
|
||||||
layout->format = fmt;
|
layout->format = fmt;
|
||||||
|
@ -466,86 +544,55 @@ static int _sde_format_get_plane_sizes_ubwc(
|
||||||
layout->height = height;
|
layout->height = height;
|
||||||
layout->num_planes = fmt->num_planes;
|
layout->num_planes = fmt->num_planes;
|
||||||
|
|
||||||
if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
|
color = _sde_format_get_media_color_ubwc(fmt);
|
||||||
uint32_t y_stride_alignment, uv_stride_alignment;
|
if (color < 0) {
|
||||||
uint32_t y_height_alignment, uv_height_alignment;
|
|
||||||
uint32_t y_tile_width = 32;
|
|
||||||
uint32_t y_tile_height = 8;
|
|
||||||
uint32_t uv_tile_width = y_tile_width / 2;
|
|
||||||
uint32_t uv_tile_height = y_tile_height;
|
|
||||||
uint32_t y_bpp_numer = 1, y_bpp_denom = 1;
|
|
||||||
uint32_t uv_bpp_numer = 1, uv_bpp_denom = 1;
|
|
||||||
|
|
||||||
y_stride_alignment = 128;
|
|
||||||
uv_stride_alignment = 64;
|
|
||||||
y_height_alignment = 32;
|
|
||||||
uv_height_alignment = 32;
|
|
||||||
y_bpp_numer = 1;
|
|
||||||
uv_bpp_numer = 2;
|
|
||||||
y_bpp_denom = 1;
|
|
||||||
uv_bpp_denom = 1;
|
|
||||||
|
|
||||||
layout->num_planes = 4;
|
|
||||||
/* Y bitstream stride and plane size */
|
|
||||||
layout->plane_pitch[0] = ALIGN(width, y_stride_alignment);
|
|
||||||
layout->plane_pitch[0] = (layout->plane_pitch[0] * y_bpp_numer)
|
|
||||||
/ y_bpp_denom;
|
|
||||||
layout->plane_size[0] = ALIGN(layout->plane_pitch[0] *
|
|
||||||
ALIGN(height, y_height_alignment), 4096);
|
|
||||||
|
|
||||||
/* CbCr bitstream stride and plane size */
|
|
||||||
layout->plane_pitch[1] = ALIGN(width / 2, uv_stride_alignment);
|
|
||||||
layout->plane_pitch[1] = (layout->plane_pitch[1] * uv_bpp_numer)
|
|
||||||
/ uv_bpp_denom;
|
|
||||||
layout->plane_size[1] = ALIGN(layout->plane_pitch[1] *
|
|
||||||
ALIGN(height / 2, uv_height_alignment), 4096);
|
|
||||||
|
|
||||||
/* Y meta data stride and plane size */
|
|
||||||
layout->plane_pitch[2] = ALIGN(
|
|
||||||
DIV_ROUND_UP(width, y_tile_width), 64);
|
|
||||||
layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
|
|
||||||
ALIGN(DIV_ROUND_UP(height, y_tile_height), 16), 4096);
|
|
||||||
|
|
||||||
/* CbCr meta data stride and plane size */
|
|
||||||
layout->plane_pitch[3] = ALIGN(
|
|
||||||
DIV_ROUND_UP(width / 2, uv_tile_width), 64);
|
|
||||||
layout->plane_size[3] = ALIGN(layout->plane_pitch[3] *
|
|
||||||
ALIGN(DIV_ROUND_UP(height / 2, uv_tile_height), 16),
|
|
||||||
4096);
|
|
||||||
|
|
||||||
} else if (fmt->base.pixel_format == DRM_FORMAT_ABGR8888 ||
|
|
||||||
fmt->base.pixel_format == DRM_FORMAT_XBGR8888 ||
|
|
||||||
fmt->base.pixel_format == DRM_FORMAT_BGRA1010102 ||
|
|
||||||
fmt->base.pixel_format == DRM_FORMAT_BGRX1010102 ||
|
|
||||||
fmt->base.pixel_format == DRM_FORMAT_BGR565) {
|
|
||||||
|
|
||||||
uint32_t stride_alignment, aligned_bitstream_width;
|
|
||||||
|
|
||||||
if (fmt->base.pixel_format == DRM_FORMAT_BGR565)
|
|
||||||
stride_alignment = 128;
|
|
||||||
else
|
|
||||||
stride_alignment = 64;
|
|
||||||
layout->num_planes = 3;
|
|
||||||
|
|
||||||
/* Nothing in plane[1] */
|
|
||||||
|
|
||||||
/* RGB bitstream stride and plane size */
|
|
||||||
aligned_bitstream_width = ALIGN(width, stride_alignment);
|
|
||||||
layout->plane_pitch[0] = aligned_bitstream_width * fmt->bpp;
|
|
||||||
layout->plane_size[0] = ALIGN(fmt->bpp * aligned_bitstream_width
|
|
||||||
* ALIGN(height, 16), 4096);
|
|
||||||
|
|
||||||
/* RGB meta data stride and plane size */
|
|
||||||
layout->plane_pitch[2] = ALIGN(DIV_ROUND_UP(
|
|
||||||
aligned_bitstream_width, 16), 64);
|
|
||||||
layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
|
|
||||||
ALIGN(DIV_ROUND_UP(height, 4), 16), 4096);
|
|
||||||
} else {
|
|
||||||
DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
|
DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
|
||||||
fmt->base.pixel_format);
|
fmt->base.pixel_format);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDE_FORMAT_IS_YUV(layout->format)) {
|
||||||
|
uint32_t y_sclines, uv_sclines;
|
||||||
|
uint32_t y_meta_scanlines = 0;
|
||||||
|
uint32_t uv_meta_scanlines = 0;
|
||||||
|
|
||||||
|
layout->num_planes = 4;
|
||||||
|
layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width);
|
||||||
|
y_sclines = VENUS_Y_SCANLINES(color, height);
|
||||||
|
layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
|
||||||
|
y_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width);
|
||||||
|
uv_sclines = VENUS_UV_SCANLINES(color, height);
|
||||||
|
layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] *
|
||||||
|
uv_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width);
|
||||||
|
y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height);
|
||||||
|
layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
|
||||||
|
y_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width);
|
||||||
|
uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height);
|
||||||
|
layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] *
|
||||||
|
uv_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
uint32_t rgb_scanlines, rgb_meta_scanlines;
|
||||||
|
|
||||||
|
layout->num_planes = 3;
|
||||||
|
|
||||||
|
layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width);
|
||||||
|
rgb_scanlines = VENUS_RGB_SCANLINES(color, height);
|
||||||
|
layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
|
||||||
|
rgb_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width);
|
||||||
|
rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height);
|
||||||
|
layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
|
||||||
|
rgb_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < SDE_MAX_PLANES; i++)
|
for (i = 0; i < SDE_MAX_PLANES; i++)
|
||||||
layout->total_size += layout->plane_size[i];
|
layout->total_size += layout->plane_size[i];
|
||||||
|
|
||||||
|
@ -574,6 +621,7 @@ static int _sde_format_get_plane_sizes_linear(
|
||||||
} else {
|
} else {
|
||||||
uint32_t v_subsample, h_subsample;
|
uint32_t v_subsample, h_subsample;
|
||||||
uint32_t chroma_samp;
|
uint32_t chroma_samp;
|
||||||
|
uint32_t bpp = 1;
|
||||||
|
|
||||||
chroma_samp = fmt->chroma_sample;
|
chroma_samp = fmt->chroma_sample;
|
||||||
_sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
|
_sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
|
||||||
|
@ -584,8 +632,11 @@ static int _sde_format_get_plane_sizes_linear(
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout->plane_pitch[0] = width;
|
if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
|
||||||
layout->plane_pitch[1] = width / h_subsample;
|
(SDE_FORMAT_IS_DX(fmt)))
|
||||||
|
bpp = 2;
|
||||||
|
layout->plane_pitch[0] = width * bpp;
|
||||||
|
layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
|
||||||
layout->plane_size[0] = layout->plane_pitch[0] * height;
|
layout->plane_size[0] = layout->plane_pitch[0] * height;
|
||||||
layout->plane_size[1] = layout->plane_pitch[1] *
|
layout->plane_size[1] = layout->plane_pitch[1] *
|
||||||
(height / v_subsample);
|
(height / v_subsample);
|
||||||
|
@ -926,6 +977,16 @@ const struct sde_format *sde_get_sde_format_ext(
|
||||||
map_size = ARRAY_SIZE(sde_format_map_ubwc);
|
map_size = ARRAY_SIZE(sde_format_map_ubwc);
|
||||||
DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED", format);
|
DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED", format);
|
||||||
break;
|
break;
|
||||||
|
case DRM_FORMAT_MOD_QCOM_DX:
|
||||||
|
map = sde_format_map_p010;
|
||||||
|
map_size = ARRAY_SIZE(sde_format_map_p010);
|
||||||
|
DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_DX", format);
|
||||||
|
break;
|
||||||
|
case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED):
|
||||||
|
map = sde_format_map_p010_ubwc;
|
||||||
|
map_size = ARRAY_SIZE(sde_format_map_p010_ubwc);
|
||||||
|
DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED/DX", format);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("unsupported format modifier %llX\n", mod0);
|
DRM_ERROR("unsupported format modifier %llX\n", mod0);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -241,8 +241,15 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
|
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QTI DX Format
|
||||||
|
*
|
||||||
|
* Refers to a DX variant of the base format.
|
||||||
|
* Implementation may be platform and base-format specific.
|
||||||
|
*/
|
||||||
|
#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DRM_FOURCC_H */
|
#endif /* DRM_FOURCC_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue