amd/vpelib: Support vpe 2.0
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Support vpe 2.0
Update vpelib to support vpe 2.0 includes new color formats,
blending, and 3dlut fast loading.

Signed-off-by: Peyton Lee <peytolee@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41073>
This commit is contained in:
Peyton Lee 2026-04-23 08:21:11 +00:00 committed by Marge Bot
parent 85a5d6233b
commit 9225ba47d5
85 changed files with 37666 additions and 39 deletions

View file

@ -79,6 +79,7 @@ union large_integer {
enum vpe_plane_addr_type {
VPE_PLN_ADDR_TYPE_GRAPHICS = 0, /**< For RGB planes */
VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE, /**< For YCbCr planes */
VPE_PLN_ADDR_TYPE_PLANAR, /**< For RGB 3-planar case */
};
/** @struct vpe_plane_address
@ -117,6 +118,23 @@ struct vpe_plane_address {
chroma_dcc_const_color; /**< DCC constant color of the chroma plane */
} video_progressive;
/** @brief Only used for RGB 3-planar case. Each plane is a struct of two \ref
* PHYSICAL_ADDRESS_LOC to store address and meta address, and one \ref large_integer to
* store dcc constant color.
*/
struct {
PHYSICAL_ADDRESS_LOC y_g_addr; /**< Address of the Y/G plane */
PHYSICAL_ADDRESS_LOC y_g_meta_addr; /**< Meta address of the Y/G plane */
union large_integer y_g_dcc_const_color; /**< DCC constant color of the Y/G plane */
PHYSICAL_ADDRESS_LOC cb_b_addr; /**< Address of the Cb/B plane */
PHYSICAL_ADDRESS_LOC cb_b_meta_addr; /**< Meta address of the Cb/B plane */
union large_integer cb_b_dcc_const_color; /**< DCC constant color of the Cb/B plane */
PHYSICAL_ADDRESS_LOC cr_r_addr; /**< Address of the Cr/R plane */
PHYSICAL_ADDRESS_LOC cr_r_meta_addr; /**< Meta address of the Cr/R plane */
union large_integer cr_r_dcc_const_color; /**< DCC constant color of the Cr/R plane */
} planar;
};
};
@ -152,6 +170,14 @@ enum vpe_scan_direction {
2, /**< Right to Left, Bottom to Top. 180 Degree Rotation and no Mirroring */
VPE_SCAN_PATTERN_270_DEGREE =
3, /**< Top to Bottom, Right to Left. 270 Degree Rotation and no Mirroring */
VPE_SCAN_PATTERN_0_DEGREE_H_MIRROR = 4, /**< Right to Left, Top to Bottom. 0 Degree Rotation and
HMirror or 180 Degree Rotation and VMirror */
VPE_SCAN_PATTERN_90_DEGREE_V_MIRROR = 5, /**< Bottom to Top, Right to Left. 270 Degree Rotation
and HMirror or 90 Degree Rotation and VMirror */
VPE_SCAN_PATTERN_180_DEGREE_H_MIRROR = 6, /**< Left to Right, Bottom to Top. 180 Degree Rotation
and HMirror or 0 Degree Rotation and VMirror */
VPE_SCAN_PATTERN_270_DEGREE_V_MIRROR = 7, /**< Top to Bottom, Left to Right. 90 Degree Rotation
and HMirror or 270 Degree Rotation and VMirror */
};
/** @struct vpe_size
@ -235,6 +261,9 @@ enum vpe_surface_pixel_format {
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102, /**< Swapped and alpha rotated RGB 32 bpp
A2 B10 G10 R10 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616, /**< RGB 64 bpp A16 R16 G16 B16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616, /**< RGB 64 bpp A16 B16 G16 R16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616, /**< RGB 64 bpp R16 G16 B16 A16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616, /**< RGB 64 bpp B16 G16 R16 A16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F, /**< Floating point RGB 64 bpp A16 R16 G16 B16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F, /**< Floating point swapped RGB 64 bpp
A16 B16 G16 R16 */
@ -253,6 +282,12 @@ enum vpe_surface_pixel_format {
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT, /**< Swapped Floating point RGB 32 bpp
R11 G11 B10 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE, /**< Shared Exponent RGB 32 bpp R9 G9 B9 E5 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM, /**< RGB 64 bpp UNORM A16 R16 G16 B16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM, /**< RGB 64 bpp UNORM R16 G16 B16 A16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM, /**< RGB 64 bpp SNORM A16 R16 G16 B16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM, /**< RGB 64 bpp SNORM R16 G16 B16 A16 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_R8, /**< Monochrome 8 bpp R8 */
VPE_SURFACE_PIXEL_FORMAT_GRPH_R16, /**< Monochrome 16 bpp R16 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, /**< Start of YCbCr formats. Used internally.*/
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr =
VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, /**< Planar YUV 4:2:0 8 bpc Y Cb Cr, AKA NV12*/
@ -268,9 +303,27 @@ enum vpe_surface_pixel_format {
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr, /**< Packed YUV 4:2:2 8 bpc Y Cb Y Cr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY, /**< Packed YUV 4:2:2 8 bpc Cr Y Cb Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY, /**< Packed YUV 4:2:2 8 bpc Cb Y Cr Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb, /**< Packed YUV 4:2:2 10 bpc Y Cr Y Cb */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr, /**< Packed YUV 4:2:2 10 bpc Y Cb Y Cr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY, /**< Packed YUV 4:2:2 10 bpc Cr Y Cb Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY, /**< Packed YUV 4:2:2 10 bpc Cb Y Cr Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb, /**< Packed YUV 4:2:2 12 bpc Y Cr Y Cb */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr, /**< Packed YUV 4:2:2 12 bpc Y Cb Y Cr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY, /**< Packed YUV 4:2:2 12 bpc Cr Y Cb Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY, /**< Packed YUV 4:2:2 12 bpc Cb Y Cr Y */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb, /**< Semi-Planar YUV 4:2:2 8 bpc Y Cr Cb */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr, /**< Semi-Planar YUV 4:2:2 8 bpc Y Cb Cr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb, /**< Semi-Planar YUV 4:2:2 10 bpc Y Cr Cb */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr, /**< Semi-Planar YUV 4:2:2 10 bpc Y Cb Cr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb, /**< Semi-Planar YUV 4:2:2 12 bpc Y Cr Cb */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr, /**< Semi-Planar YUV 4:2:2 12 bpc Y Cb Cr */
VPE_SURFACE_PIXEL_FORMAT_SUBSAMPLE_END =
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY, /**< End of chroma sub-sampled formats. Used
internally */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr, /**< End of chroma sub-sampled formats.
Used internally */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212, /**< Y416 64 bpp A12 Cr12 Y12 Cb12 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212, /**< A-rotated Y416 64 bpp Cr12 Y12 Cb12 A12 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA, /**< Alpha plane 8bpc passed as YUV 4:2:0 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888, /**< AYUV 32 bpp 8 bpc Cb8 Cr8 Y8 A8*/
VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010, /**< Y410 32 bpp A2 Cr10 Y10 Cb10 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102, /**< A-rotated Y410 32 bpp Cr10 Y10 Cb10 A2 */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888, /**< AYUV 32 bpp 8 bpc A8 Y8 Cr8 Cb8 */
@ -281,6 +334,17 @@ enum vpe_surface_pixel_format {
VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888, /**< AYUV 32 bpp 8 bpc A8 Y8 Cb8 Cbr */
VPE_SURFACE_PIXEL_FORMAT_VIDEO_END =
VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888, /**< End of YCbCr formats. Used internally. */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_BEGIN, /**< Full 3 Plane Formats */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB = /**< Planar RGB 8bpc */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_BEGIN,
VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr, /**< Planar YCbCr 8bpc */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB, /**< Planar RGB 16bpc */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr, /**< Planar YCbCr 16bpc */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT, /**< Planar RGB FP16 */
VPE_SURFACE_PIXEL_FORMAT_PLANAR_END =
VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT, /**< End of PLANAR formats. Used
internally. */
VPE_SURFACE_PIXEL_FORMAT_INVALID /**< Used for the formats which are not among
the recognized formats. */
};
@ -338,6 +402,13 @@ struct vpe_scaling_taps {
uint32_t h_taps_c; /**< Number of horizontal taps for chroma plane */
};
/** @enum vpe_3dlut_mem_align
* @brief 3DLUT dma buffer alignment
*/
enum vpe_3dlut_mem_align {
VPE_3DLUT_ALIGNMENT_128 = 0, /**< 32 bytes alignment */
VPE_3DLUT_ALIGNMENT_256 = 1, /**< 64 bytes alignment */
};
#ifdef __cplusplus
}
#endif

View file

@ -47,6 +47,7 @@ struct vpe;
* VPE library supports up to 8 taps and 64 phases, only (32+1) phases needed
*/
#define MAX_NB_POLYPHASE_COEFFS (8 * 33)
#define VPE_FROD_MAX_STAGE 3
/** @enum vpe_status
* @brief The status of VPE to indicate whether it supports the given job or not.
@ -94,6 +95,10 @@ enum vpe_status {
VPE_STATUS_SCALER_NOT_SET, /**< Scaler parameters are not set. */
VPE_STATUS_GEOMETRICSCALING_ERROR, /**< Geometric scaling is not supported for the
given case. */
VPE_INVALID_HISTOGRAM_SELECTION,
VPE_STATUS_HISTOGRAM_NOT_SUPPORTED, /**< Histogram is not supported. */
VPE_STATUS_FROD_NOT_SUPPORTED, /**< FROD is not supported. */
VPE_STATUS_LUT_COMPOUND_NOT_SUPPORTED, /**< LUT Compound (CSC+1D+3D) is not supported. */
};
/*****************************************************
@ -125,8 +130,38 @@ enum vpe_ip_level {
VPE_IP_LEVEL_UNKNOWN = (-1),
VPE_IP_LEVEL_1_0, /**< vpe 1.0 */
VPE_IP_LEVEL_1_1, /**< vpe 1.1 */
VPE_IP_LEVEL_2_0, /**< vpe 2.0 */
};
enum vpe_mps_mode {
VPE_MPS_DISABLED = 0,
VPE_MPS_BLENDING_ONLY,
VPE_MPS_ENABLED
};
enum vpe_hist_collection_mode {
VPE_HISTOGRAM_NONE = 0, /**< Disable histogram collection in channel 0. */
VPE_HISTOGRAM_R_Cr, /**< Create a histogram from R or Cr for RGB/YCbCr input surfaces respectivley. */
VPE_HISTOGRAM_G_Y, /**< Create a histogram from G or Y for RGB/YCbCr input surfaces respectivley */
VPE_HISTOGRAM_B_CB, /**< Create a histogram from B or Cb for RGB/YCbCr input surfaces respectivley */
VPE_HISTOGRAM_MAX_RGB_YCbCr, /**< Create a histogram from MAX(R,G,B) or MAX(Y,Cb,Cr) for RGB/YCbCr input surfaces respectivley */
VPE_HISTOGRAM_RGB_TRANSFORMED_Y, /**< Create a histogram of luma from transformed RGB. If the input surfae is YCbCr, this mode wll default to collecting Y directly. */
VPE_HISTOGRAM_MIN_RGB_YCbCr, /**< Create a histogram from MIN(R,G,B) or MIN (Y,Cb,Cr) for RGB/YCbCr input surfaces respectivley */
VPE_HISTOGRAM_LAST_TYPE
};
enum hist_channels {
hist_channel1 = 0,
hist_channel2,
hist_channel3,
hist_max_channel
};
static const enum vpe_hist_collection_mode channel_hist_allowed_mode[hist_max_channel][2] = {
{VPE_HISTOGRAM_R_Cr, VPE_HISTOGRAM_MAX_RGB_YCbCr},
{VPE_HISTOGRAM_G_Y, VPE_HISTOGRAM_RGB_TRANSFORMED_Y},
{VPE_HISTOGRAM_B_CB, VPE_HISTOGRAM_MIN_RGB_YCbCr} };
/****************************************
* Plane Caps
****************************************/
@ -142,6 +177,19 @@ struct vpe_pixel_format_support {
uint32_t p016 : 1; /**< planar 4:2:0 16-bits */
uint32_t ayuv : 1; /**< packed 4:4:4 8-bits */
uint32_t yuy2 : 1; /**< packed 4:2:2 8-bits */
uint32_t y210 : 1; /**< packed 4:2:2 10-bit */
uint32_t y216 : 1; /**< packed 4:2:2 16-bit */
uint32_t p210 : 1; /**< planar 4:2:2 10-bit */
uint32_t p216 : 1; /**< planar 4:2:2 16-bit */
uint32_t rgb8_planar : 1; /**< planar RGB 8-bit */
uint32_t rgb16_planar : 1; /**< planar RGB 16-bit */
uint32_t yuv8_planar : 1; /**< planar YUV 16-bit */
uint32_t yuv16_planar : 1; /**< planar YUV 16-bit */
uint32_t fp16_planar : 1; /**< planar RGB 8-bit */
uint32_t rgbe : 1; /**< shared exponent R9G9B9E5 */
uint32_t rgb111110_fix : 1; /**< fixed R11G11B10 */
uint32_t rgb111110_float : 1; /**< float R11G11B10 */
uint32_t argb_packed_64b : 1; /**< Packed RGBA formats 64-bits per pixel */
};
/** @struct vpe_plane_caps
@ -163,6 +211,8 @@ struct vpe_plane_caps {
uint32_t pitch_alignment; /**< Pitch alignment in bytes */
uint32_t addr_alignment; /**< Plane address alignment in bytes */
uint32_t max_viewport_width; /**< Maximum viewport size */
uint32_t max_viewport_width_64bpp; /**< Maximum viewport size for 64bpp formats with 90/270
degrees rotation */
};
/*************************
@ -196,6 +246,40 @@ struct dpp_color_caps {
struct vpe_rom_curve_caps dgam_rom_caps; /**< Dgam Rom Caps */
};
/** @struct lut_caps
* @brief LUT (Look-Up Table) capabilities
* This structure defines the capabilities for LUT shaper and 3D LUTs.
*/
struct vpe_lut_caps {
struct {
uint32_t dma_data : 1; /**< DMA data support */
uint32_t dma_config : 1; /**< DMA configuration support */
uint32_t non_monotonic : 1; /**< Non-monotonic LUT support */
uint16_t data_alignment; /**< Data alignment in bytes */
uint16_t config_alignment; /**< Configuration alignment in bytes */
uint16_t config_padding; /**< Configuration padding in bytes */
uint16_t data_size; /**< Data size in bytes */
uint16_t config_size; /**< Configuration size in bytes */
uint16_t data_pts_per_channel; /**< Number data of points per channel */
} lut_shaper_caps;
struct {
uint32_t data_dim_9 : 1; /**< Support for 9x9x9 3D LUT */
uint32_t data_dim_17 : 1; /**< Support for 17x17x17 3D LUT */
uint32_t data_dim_33 : 1; /**< Support for 33x33x33 3D LUT */
union {
struct {
uint32_t dma_dim_9 : 1; /**< DMA support for 9x9x9 3D LUT */
uint32_t dma_dim_17 : 1; /**< DMA support for 17x17x17 3D LUT */
uint32_t dma_dim_33 : 1; /**< DMA support for 33x33x33 3D LUT */
};
uint32_t dma; /**< Any DMA support if set */
};
uint16_t alignment; /**< 3D lUT Alignment in bytes */
} lut_3dlut_caps;
uint32_t lut_3d_compound : 1; /**< Support for 3D LUT compound */
};
/** @struct mpc_color_caps
* @brief Color management caps for mpc layer
*/
@ -207,6 +291,26 @@ struct mpc_color_caps {
uint32_t global_alpha : 1; /**< e.g. top plane 30 %. bottom 70 % */
uint32_t top_bottom_blending : 1; /**< two-layer blending */
uint32_t dma_3d_lut : 1; /**< DMA mode support for 3D LUT, Legacy interface, will be replaced by
vpe_lut_caps*/
uint32_t yuv_linear_blend : 1; /**< Support for linear blending of 3D LUT YUV output */
struct {
uint32_t dim_9 : 1; /**< 3D LUT support for 9x9x9 ,Legacy interface, will be replaced by
vpe_lut_caps*/
uint32_t dim_17 : 1; /**< 3D LUT support for 17x17x17, Legacy interface, will be replaced by
vpe_lut_caps */
uint32_t dim_33 : 1; /**< 3D LUT support for 33x33x33, Legacy interface, will be replaced by
vpe_lut_caps */
} lut_dim_caps;
struct {
uint32_t lut_3d_17 : 1; /**< 3D LUT 17x17x17 container fastload support, default 0,Legacy
interface, will be replaced by vpe_lut_caps */
uint32_t lut_3d_33 : 1; /**< 3D LUT 33x33x33 container fastload support, default 0,Legacy
interface, will be replaced by vpe_lut_caps */
} fast_load_caps;
struct vpe_lut_caps lut_caps; /**< LUT capabilities for shaper and 3D LUT configurations. */
};
/** @struct vpe_color_caps
@ -251,6 +355,22 @@ struct vpe_caps {
struct vpe_color_caps color_caps; /**< Color management caps */
struct vpe_plane_caps plane_caps; /**< Plane capabilities */
uint32_t input_dcc_support : 1; /**< Input DCC support */
uint32_t input_internal_dcc : 1; /**< Input internal DCC */
uint32_t output_dcc_support : 1; /**< Output DCC support */
uint32_t output_internal_dcc : 1; /**< Output internal DCC */
uint32_t histogram_support : 1; /**< Histogram support */
uint32_t frod_support : 1; /**< FROD support */
uint32_t alpha_blending_support : 1; /**< Alpha blending support */
uint32_t easf_support : 1; /**< edge adaptive scaling support */
struct {
bool support; /**< iSharp support */
struct {
uint32_t min; /**< iSharp min level */
uint32_t max; /**< iSharp max level */
uint32_t step; /**< iSharp level steps */
} range;
} isharp_caps;
struct {
uint32_t opaque : 1;
uint32_t bg_color : 1;
@ -313,6 +433,7 @@ struct vpe_surface_dcc_cap {
bool capable; /**< DCC capable */
bool const_color_support; /**< DCC const color support */
bool is_internal_dcc;
};
/****************************************
@ -421,7 +542,8 @@ struct vpe_visual_confirm {
struct {
uint32_t input_format : 1; /**< input format, 0: disable, 1: enable*/
uint32_t output_format : 1; /**< output format, 0: disable, 1: enable*/
uint32_t reserved : 30; /**< reserved */
uint32_t pipe_idx : 1; /**< pipe index, 0: disable, 1: enable*/
uint32_t reserved : 29; /**< reserved */
};
uint32_t value; /**< confirm value */
};
@ -460,7 +582,11 @@ struct vpe_debug_options {
uint32_t skip_optimal_tap_check : 1; /**< Skip optimal tap check */
uint32_t disable_lut_caching : 1; /**< disable config caching for all luts */
uint32_t disable_performance_mode : 1; /**< disable performance mode */
uint32_t reserved : 8;
uint32_t multi_pipe_segmentation_policy : 1; /**< policy for when to use MPS feature */
uint32_t opp_background_gen : 1; /**< generate bg color in opp (default mpc) */
uint32_t subsampling_quality : 1; /**< subsample quality */
uint32_t disable_3dlut_fl : 1; /**< disable 3dlut fastloading */
uint32_t reserved : 4;
} flags; /**< debug flags */
// valid only if the corresponding flag is set
@ -485,6 +611,10 @@ struct vpe_debug_options {
uint32_t skip_optimal_tap_check : 1; /**< Skip optimal tap check */
uint32_t disable_lut_caching : 1; /**< disable config caching for all luts */
uint32_t disable_performance_mode : 1; /**< disable performance mode */
uint32_t multi_pipe_segmentation_policy : 2; /**< policy mode for when to use MPS */
uint32_t opp_background_gen : 1; /**< switch bg gen to OPP */
uint32_t subsampling_quality : 2; /**< subsample quality */
uint32_t disable_3dlut_fl : 1; /**< disable 3dlut fastloading */
uint32_t bg_bit_depth; /**< Background color bit depth. */
struct vpe_mem_low_power_enable_options
@ -685,6 +815,30 @@ struct vpe_blend_info {
float global_alpha_value; /**< Global alpha value. In range of 0.0-1.0 */
};
/** @struct vpe_sharpness_range
* @brief Specifies the sharpness to be applied by the scaler (DSCL)
*/
struct vpe_sharpness_range {
int sdr_rgb_min; /**< SDR RGB sharpness min */
int sdr_rgb_max; /**< SDR RGB sharpness max */
int sdr_rgb_mid; /**< SDR RGB sharpness mid */
int sdr_yuv_min; /**< SDR YUV sharpness min */
int sdr_yuv_max; /**< SDR YUV sharpness max */
int sdr_yuv_mid; /**< SDR YUV sharpness mid */
int hdr_rgb_min; /**< HDR RGB sharpness min */
int hdr_rgb_max; /**< HDR RGB sharpness max */
int hdr_rgb_mid; /**< HDR RGB sharpness mid */
};
/** @struct vpe_adaptive_sharpness
* @brief Adaptive sharpness parameters
*/
struct vpe_adaptive_sharpness {
bool enable; /**< Enable adaptive sharpness */
unsigned int sharpness_level; /**< Sharpness level */
struct vpe_sharpness_range sharpness_range; /**< Sharpness range */
};
/** @struct vpe_scaling_info
* @brief Data needs to calculate scaling data.
*/
@ -695,6 +849,11 @@ struct vpe_scaling_info {
* If taps are set to 0, vpe internally calculates the
* required number of taps based on the scaling ratio.
*/
// Adaptive scaling and sharpening params
struct vpe_adaptive_sharpness adaptive_sharpeness; /**< Adaptive scaler sharpness mode. */
bool enable_easf; /**< Enable edge adaptive scaling */
bool prefer_easf; /**< Edge adaptive scaling is prefered if
can be performed. */
};
/** @struct vpe_scaling_filter_coeffs
@ -715,6 +874,12 @@ struct vpe_scaling_filter_coeffs {
vertical polyphase scaling */
};
struct vpe_frod_param {
union {
uint8_t enable_frod;
};
};
/** @struct vpe_hdr_metadata
* @brief HDR metadata
*/
@ -742,6 +907,72 @@ struct vpe_reserved_param {
uint32_t size; /**< Size of the reserved parameter */
};
/** @struct vpe_lut_mem_layout
* @brief vpe 3D-LUT memory layout
*/
enum vpe_lut_type {
VPE_LUT_TYPE_CPU = 0, /**< CPU accessible 3D LUT data, 3 channel, 16 bits depth per channel */
VPE_LUT_TYPE_GPU_1D_PACKED =
1, /**< GPU accessible 3D LUT data, 1D packed, 4 channel, 16 bits depth per channel */
VPE_LUT_TYPE_GPU_3D_SWIZZLE =
2, /**< GPU accessible 3D LUT data, 3D surface 4 channel, 16 bits depth per channel */
};
// Track offset of bkgr streams relative to first stream (alpha)
enum vpe_bkgr_stream_offset {
VPE_BKGR_STREAM_ALPHA_OFFSET = 0, /**< background stream alpha offset */
VPE_BKGR_STREAM_VIDEO_OFFSET = 1, /**< background stream video offset */
VPE_BKGR_STREAM_BACKGROUND_OFFSET = 2, /**< background stream background offset */
VPE_BKGR_STREAM_INTERMEDIATE_OFFSET = 3, /**< background stream intermediate offset */
};
/** @struct vpe_3dlut_compound
* This structure encapsulates auxiliary parameters required for describing a 3D LUT (Look-Up Table)
* operation - whether this is the 3d lut compound case, cositing info for upsampling, 3dlut output
* CS, and 3x4 csc matrix.
*
* @var vpe_3dlut_compound::enabled
* Indicates if the LUT Compound is enabled.
* @var vpe_3dlut_compound::upsampledChromaInput
* Chroma cositing mode for upsampling input.
* @var vpe_3dlut_compound::primaries3D
* Color primaries for the 3D LUT output.
* Note that this is different from stream input/output color space.
* @var vpe_3dlut_compound::pCscMatrix
* 3x4 color space conversion matrix.
*/
struct vpe_3dlut_compound {
bool enabled;
enum vpe_chroma_cositing upsampled_chroma_input;
enum vpe_color_primaries primaries_3D;
struct vpe_color_space out_cs_3D;
float pCscMatrix[3][4];
};
struct vpe_dma_shaper {
bool enabled;
uint64_t data; /**< Accessible to GPU. */
uint64_t config_data; /**< Accessible to GPU. */
uint32_t *data_cpu; /**< Accessible to CPU. */
uint32_t *config_data_cpu; /**< Accessible to CPU. */
uint8_t tmz; /**< tmz bits for shaper */
};
struct vpe_dma_3dlut {
uint64_t data; /**< Accessible to GPU. Only for fast load */
enum vpe_surface_pixel_format format; /**< DMA lut data format */
enum vpe_3dlut_mem_align mem_align; /**< DMA lut memory alignment */
float bias; /**< DMA lut bias */
float scale; /**< DMA lut scale */
uint8_t tmz; /**< tmz bits for 3dlut */
};
struct vpe_dma_info {
struct vpe_dma_3dlut lut3d; /**< DMA 3D LUT parameters */
struct vpe_dma_shaper shaper; /**< DMA shaper parameters */
};
/** @struct vpe_tonemap_params
* @brief Tone mapping parameters
*/
@ -760,6 +991,7 @@ struct vpe_tonemap_params {
factor. */
uint16_t lut_dim; /**< Size of one dimension of the 3D-LUT data*/
uint16_t lut_container_dim; /**< Size of one dimension of the 3D-LUT container*/
enum vpe_lut_type lut_type; /**< LUT data type. If type is GPU, use vpe_dma_info */
uint16_t *lut_data; /**< Accessible to CPU */
bool enable_3dlut; /**< Enable/Disable 3D-LUT */
};
@ -792,6 +1024,28 @@ struct vpe_color_keyer {
float upper_a_bound; /**< Alpha High Bound. Program 1.0f if no alpha channel in input format.*/
};
/** @struct vpe_histogram
* @brief Histogram collection parameters
* VPE can collect up to 3 separate histograms with 256 bins each.
* Internally there are two binning modes. One for integer input surface formats and one for float input surface formats.
*
* Integer Mode : Pixels are evenly binned with each bin having a width of(2 ^ bitdepth) - 1 / 256
*
* Float Mode : The internal float format used for binning is fp16(1.5.10).The bin indeces are first divided
* into two major groups. Bins 0 - 127 are for postivie pixels, bins 128 - 255 are for negative pixels.
* Each major group is further subdivided into 32 exponent bin groups. (A mantissa of 5 gives 32 possible values)
* Finally, the bin groups of size 4 are index by the two MSB of the mantissa to determine the bin index of the pixel.
*/
struct vpe_collection_param {
enum vpe_hist_collection_mode hist_types;/**< histogram collection types*/
struct vpe_surface_info hist_output;/**< histogram output surface*/
};
struct vpe_histogram_param {
struct vpe_collection_param hist_collection_param[hist_max_channel];/**< histogram collection parameters: type and output surface*/
uint32_t hist_format; /**< histogram collection data format:0 for integer, 1 and 2 for fp16 */
uint32_t hist_dsets; /**< number of histogram data sets: 0, 1, 2 */
};
/** @struct vpe_stream
* @brief Input stream/frame properties to be passed to vpelib
*/
@ -803,6 +1057,8 @@ struct vpe_stream {
contrast, hue and saturation.*/
struct vpe_tonemap_params tm_params; /**< Tone mapping parameters*/
struct vpe_hdr_metadata hdr_metadata; /**< HDR metadata */
struct vpe_dma_info dma_info; /**< DMA / fast load params */
struct vpe_3dlut_compound lut_compound; /**< 3D LUT compound params */
struct vpe_scaling_filter_coeffs polyphase_scaling_coeffs; /**< Filter coefficients for
polyphase scaling. */
enum vpe_rotation_angle rotation; /**< Rotation angle of the
@ -825,6 +1081,10 @@ struct vpe_stream {
enum vpe_keyer_mode keyer_mode; /**< Set Keyer Behavior.
* Used for both Luma & Color Keying.
*/
struct vpe_surface_info intermediate_surface; /**< Intermediate stream for two pass operations
* this surface is allocated by caller.
* Set addr to 0 if unused */
struct vpe_histogram_param hist_params; /**< Parameters related to the histogram collection*/
struct vpe_reserved_param reserved_param; /**< Reserved parameter for input surface */
/** @brief stream feature flags
@ -837,7 +1097,39 @@ struct vpe_stream {
* as well as blending.
* Destination rect must equal to target rect.
*/
uint32_t reserved : 30; /**< reserved */
/**
* Flags for Background Replacement (BKGR) and Alpha Combine feature
*
* BKGR requires 3 or 4 inputs:
* For one pass:
* AlphaStream, VideoStream, BackgroundStream
* For two pass:
* AlphaStream, VideoStream, BackgroundStream, Intermediate Surface
*
* For two-pass BKGR, an intermediate surface is required to store results of first pass
*
* stream[i] is the alpha stream passed as NV12.
* Format must be VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA
* is_alpha_combine = 1; is_alpha_plane = 1; is_background_plane = 0;
*
* stream[i+1] is the video stream that will have its background removed (and replaced if
* BKGR) is_alpha_combine = 1; is_alpha_plane = 0; is_background_plane = 0;
*
* If only doing alpha combine, only first 2 streams are required. For BKGR:
* stream[i+2] is the background stream
* is_alpha_combine = 0; is_alpha_plane = 0; is_background_plane = 1;
*
* If two pass: stream[i+3] is the intermediate surface. Format == FP16
* if src stream downscaling: Size == dst rect (downscaled src rect)
* else: Size == src rect
* for one pass we don't need this stream
*
* Ordering also tracked in enum vpe_bkgr_stream_offset
*/
uint32_t is_background_plane : 1; /**< is this stream the new background */
uint32_t is_alpha_combine : 1; /**< set if part of the alpha combine operation */
uint32_t is_alpha_plane : 1; /**< is this the alpha through luma plane */
uint32_t reserved : 27; /**< reserved */
} flags; /**< Data flags */
};
@ -884,6 +1176,9 @@ struct vpe_build_param {
uint16_t num_instances; /**< Number of instances for the collaboration mode */
bool collaboration_mode; /**< Collaboration mode. If set, multiple instances of VPE being
used. */
bool enable_frod;
struct vpe_surface_info frod_surface[VPE_FROD_MAX_STAGE]; /**< FROD outputs */
struct vpe_frod_param frod_param; /**< FROD parameters */
};
/** @struct vpe_bufs_req

View file

@ -24,6 +24,7 @@ c_args_vpe += [
'-DVPE_BUILD_1_0',
'-DVPE_BUILD_1_X',
'-DVPE_BUILD_1_1',
'-DVPE_BUILD_2_0',
]
vpe_files = files(
@ -124,7 +125,31 @@ vpe_files = files(
'src/chip/vpe11/inc/vpe11_vpe_desc_writer.h',
'src/chip/vpe11/vpe11_cmd_builder.c',
'src/chip/vpe11/vpe11_resource.c',
'src/chip/vpe11/vpe11_vpe_desc_writer.c'
'src/chip/vpe11/vpe11_vpe_desc_writer.c',
'src/core/inc/multi_pipe_segmentation.h',
'src/core/multi_pipe_segmentation.c',
'src/core/vpe_spl_translation.c',
'src/chip/vpe20/inc/vpe20_resource.h',
'src/chip/vpe20/vpe20_cdc_be.c',
'src/chip/vpe20/vpe20_cdc_fe.c',
'src/chip/vpe20/vpe20_cmd_builder.c',
'src/chip/vpe20/vpe20_config_writer.c',
'src/chip/vpe20/vpe20_dpp_cm.c',
'src/chip/vpe20/vpe20_dpp_dscl.c',
'src/chip/vpe20/vpe20_dpp.c',
'src/chip/vpe20/vpe20_mpc.c',
'src/chip/vpe20/vpe20_opp.c',
'src/chip/vpe20/vpe20_plane_desc_writer.c',
'src/chip/vpe20/vpe20_resource.c',
'src/chip/vpe20/vpe20_vpe_desc_writer.c',
'src/imported/SPL/dc_spl.c',
'src/imported/SPL/dc_spl.h',
'src/imported/SPL/dc_spl_filters.c',
'src/imported/SPL/dc_spl_isharp_filters.c',
'src/imported/SPL/dc_spl_scl_easf_filters.c',
'src/imported/SPL/dc_spl_scl_filters.c',
'src/imported/SPL/spl_custom_float.c',
'src/imported/SPL/spl_fixpt31_32.c',
)
inc_amd_vpe = include_directories(
@ -135,6 +160,9 @@ inc_amd_vpe = include_directories(
'src/utils/inc',
'src/chip/vpe10/inc',
'src/chip/vpe11/inc',
'src/chip/vpe20/inc',
'src/imported/SPL',
'src/imported',
)
libvpe = static_library(

View file

@ -905,6 +905,8 @@ enum vpe10_coef_filter_type_sel {
SCL_COEF_CHROMA_HORZ_FILTER = 3,
SCL_COEF_ALPHA_VERT_FILTER = 4,
SCL_COEF_ALPHA_HORZ_FILTER = 5,
SCL_COEF_VERTICAL_BLUR_SCALE = SCL_COEF_ALPHA_VERT_FILTER,
SCL_COEF_HORIZONTAL_BLUR_SCALE = SCL_COEF_ALPHA_HORZ_FILTER
};
enum vpe10_dscl_autocal_mode {

View file

@ -40,6 +40,7 @@ enum mux_sel {
static struct cdc_fe_funcs cdc_fe_func = {
.program_surface_config = vpe10_cdc_program_surface_config,
.program_crossbar_config = vpe10_cdc_program_crossbar_config,
.program_3dlut_fl_config = NULL,
.program_viewport = vpe10_cdc_program_viewport,
};

View file

@ -58,6 +58,10 @@ static struct dpp_funcs vpe10_dpp_funcs = {
.set_frame_scaler = vpe10_dpp_set_frame_scaler,
.get_line_buffer_size = vpe10_get_line_buffer_size,
.validate_number_of_taps = vpe10_dpp_validate_number_of_taps,
.enable_clocks = NULL,
.dscl_program_easf = NULL,
.dscl_disable_easf = NULL,
.dscl_program_isharp = NULL,
};
void vpe10_construct_dpp(struct vpe_priv *vpe_priv, struct dpp *dpp)

View file

@ -57,6 +57,12 @@ static struct mpc_funcs mpc_funcs = {
.set_blend_lut = vpe10_mpc_set_blend_lut,
.program_movable_cm = vpe10_mpc_program_movable_cm,
.program_crc = vpe10_mpc_program_crc,
.attach_3dlut_to_mpc_inst = NULL,
.set_gamut_remap2 = NULL,
.update_3dlut_fl_bias_scale = NULL,
.program_mpc_3dlut_fl_config = NULL,
.program_mpc_3dlut_fl = NULL,
.shaper_bypass = NULL,
};
void vpe10_construct_mpc(struct vpe_priv *vpe_priv, struct mpc *mpc)

View file

@ -50,6 +50,13 @@
#define LUT_ENTRY_SIZE (2)
#define LUT_NUM_COMPONENT (3)
#define LUT_BUFFER_SIZE (LUT_NUM_ENTRIES * LUT_ENTRY_SIZE * LUT_NUM_COMPONENT)
#define SHAPER_LUT_DATA_POINTS_PER_CHANNEL (256)
#define SHAPER_LUT_DMA_DATA_SIZE (0)
#define SHAPER_LUT_DMA_CONFIG_SIZE (0)
#define SHAPER_LUT_DMA_DATA_ALIGNMENT (0)
#define SHAPER_LUT_DMA_CONFIG_ALIGNMENT (0)
#define SHAPER_LUT_DMA_CONFIG_PADDING (0)
#define LUT_3D_DMA_ALIGNMENT (0)
// set field/register/bitfield name
#define SFRB(field_name, reg_name, post_fix) .field_name = reg_name##__##field_name##post_fix
@ -188,6 +195,45 @@ static struct vpe_caps
.shared_3d_lut = 1,
.global_alpha = 1,
.top_bottom_blending = 0,
.dma_3d_lut = 0,
.yuv_linear_blend = 0,
.lut_dim_caps =
{
.dim_9 = 1,
.dim_17 = 1,
.dim_33 = 0,
},
.fast_load_caps =
{
.lut_3d_17 = 0,
.lut_3d_33 = 0,
},
.lut_caps =
{
.lut_shaper_caps =
{
.dma_data = 0,
.dma_config = 0,
.non_monotonic = 0,
.data_alignment = SHAPER_LUT_DMA_DATA_ALIGNMENT,
.config_alignment = SHAPER_LUT_DMA_CONFIG_ALIGNMENT,
.config_padding = SHAPER_LUT_DMA_CONFIG_PADDING,
.data_size = SHAPER_LUT_DMA_DATA_SIZE,
.config_size = SHAPER_LUT_DMA_CONFIG_SIZE,
.data_pts_per_channel = SHAPER_LUT_DATA_POINTS_PER_CHANNEL,
},
.lut_3dlut_caps =
{
.data_dim_9 = 1,
.data_dim_17 = 1,
.data_dim_33 = 0,
.dma_dim_9 = 0,
.dma_dim_17 = 0,
.dma_dim_33 = 0,
.alignment = LUT_3D_DMA_ALIGNMENT,
},
.lut_3d_compound = 0,
},
}},
.plane_caps =
{
@ -201,6 +247,19 @@ static struct vpe_caps
.p016 = 0, /**< planar 4:2:0 16-bit */
.ayuv = 0, /**< packed 4:4:4 */
.yuy2 = 0, /**< packed 4:2:2 */
.y210 = 0, /**< packed 4:2:2 10-bit */
.y216 = 0, /**< packed 4:2:2 16-bit */
.p210 = 0, /**< planar 4:2:2 10-bit */
.p216 = 0, /**< planar 4:2:2 16-bit */
.rgb8_planar = 0, /**< planar RGB 8-bit */
.rgb16_planar = 0, /**< planar RGB 16-bit */
.yuv8_planar = 0, /**< planar YUV 16-bit */
.yuv16_planar = 0, /**< planar YUV 16-bit */
.fp16_planar = 0, /**< planar RGB 8-bit */
.rgbe = 0, /**< shared exponent R9G9B9E5 */
.rgb111110_fix = 0, /**< fixed R11G11B10 */
.rgb111110_float = 0, /**< float R11G11B10 */
.argb_packed_64b = 0, /**< Packed RGBA formats 64-bits per pixel */
},
.output_pixel_format_support =
{
@ -211,6 +270,19 @@ static struct vpe_caps
.p016 = 0, /**< planar 4:2:0 16-bit */
.ayuv = 0, /**< packed 4:4:4 */
.yuy2 = 0, /**< packed 4:2:2 */
.y210 = 0, /**< packed 4:2:2 10-bit */
.y216 = 0, /**< packed 4:2:2 16-bit */
.p210 = 0, /**< planar 4:2:2 10-bit */
.p216 = 0, /**< planar 4:2:2 16-bit */
.rgb8_planar = 0, /**< planar RGB 8-bit */
.rgb16_planar = 0, /**< planar RGB 16-bit */
.yuv8_planar = 0, /**< planar YUV 16-bit */
.yuv16_planar = 0, /**< planar YUV 16-bit */
.fp16_planar = 0, /**< planar RGB 8-bit */
.rgbe = 0, /**< shared exponent R9G9B9E5 */
.rgb111110_fix = 0, /**< fixed R11G11B10 */
.rgb111110_float = 0, /**< float R11G11B10 */
.argb_packed_64b = 0, /**< Packed RGBA formats 64-bits per pixel */
},
.max_upscale_factor = 64000,
@ -225,6 +297,24 @@ static struct vpe_caps
.addr_alignment = 256,
.max_viewport_width = 1024,
},
.isharp_caps =
{
.support = false,
.range =
{
.min = 0,
.max = 0,
.step = 0,
},
},
.easf_support = 0,
.input_dcc_support = 0,
.input_internal_dcc = 0,
.output_dcc_support = 0,
.output_internal_dcc = 0,
.histogram_support = 0,
.frod_support = 0,
.alpha_blending_support = 0,
.alpha_fill_caps =
{
.opaque = 1,
@ -453,6 +543,10 @@ enum vpe_status vpe10_construct_resource(struct vpe_priv *vpe_priv, struct resou
res->update_output_gamma = vpe10_update_output_gamma;
res->validate_cached_param = vpe10_validate_cached_param;
res->check_alpha_fill_support = vpe10_check_alpha_fill_support;
res->reset_pipes = NULL;
res->populate_frod_param = NULL;
res->check_lut3d_compound = NULL;
res->update_opp_adjust_and_boundary = NULL;
res->calculate_shaper = vpe10_calculate_shaper;
return VPE_STATUS_OK;

View file

@ -45,6 +45,13 @@
#define LUT_NUM_COMPONENT (3)
#define LUT_BUFFER_SIZE (LUT_NUM_ENTRIES * LUT_ENTRY_SIZE * LUT_NUM_COMPONENT)
#define SHAPER_LUT_DATA_POINTS_PER_CHANNEL (256)
#define SHAPER_LUT_DMA_DATA_SIZE (0)
#define SHAPER_LUT_DMA_CONFIG_SIZE (0)
#define SHAPER_LUT_DMA_DATA_ALIGNMENT (0)
#define SHAPER_LUT_DMA_CONFIG_ALIGNMENT (0)
#define SHAPER_LUT_DMA_CONFIG_PADDING (0)
#define LUT_3D_DMA_ALIGNMENT (0)
// set field/register/bitfield name
#define SFRB(field_name, reg_name, post_fix) .field_name = reg_name##__##field_name##post_fix
@ -126,6 +133,45 @@ static struct vpe_caps
.shared_3d_lut = 1,
.global_alpha = 1,
.top_bottom_blending = 0,
.dma_3d_lut = 0,
.yuv_linear_blend = 0,
.lut_dim_caps =
{
.dim_9 = 1,
.dim_17 = 1,
.dim_33 = 0,
},
.fast_load_caps =
{
.lut_3d_17 = 0,
.lut_3d_33 = 0,
},
.lut_caps =
{
.lut_shaper_caps =
{
.dma_data = 0,
.dma_config = 0,
.non_monotonic = 0,
.data_alignment = SHAPER_LUT_DMA_DATA_ALIGNMENT,
.config_alignment = SHAPER_LUT_DMA_CONFIG_ALIGNMENT,
.config_padding = SHAPER_LUT_DMA_CONFIG_PADDING,
.data_size = SHAPER_LUT_DMA_DATA_SIZE,
.config_size = SHAPER_LUT_DMA_CONFIG_SIZE,
.data_pts_per_channel = SHAPER_LUT_DATA_POINTS_PER_CHANNEL,
},
.lut_3dlut_caps =
{
.data_dim_9 = 1,
.data_dim_17 = 1,
.data_dim_33 = 0,
.dma_dim_9 = 0,
.dma_dim_17 = 0,
.dma_dim_33 = 0,
.alignment = LUT_3D_DMA_ALIGNMENT,
},
.lut_3d_compound = 0,
},
}},
.plane_caps =
{
@ -139,6 +185,10 @@ static struct vpe_caps
.p016 = 0, /**< planar 4:2:0 16-bit */
.ayuv = 0, /**< packed 4:4:4 */
.yuy2 = 0, /**< packed 4:2:2 */
.y210 = 0, /**< packed 4:2:2 10-bit */
.y216 = 0, /**< packed 4:2:2 16-bit */
.p210 = 0, /**< planar 4:2:2 10-bit */
.p216 = 0, /**< planar 4:2:2 16-bit */
},
.output_pixel_format_support =
{
@ -148,7 +198,12 @@ static struct vpe_caps
.p010 = 0, /**< planar 4:2:0 10-bit */
.p016 = 0, /**< planar 4:2:0 16-bit */
.ayuv = 0, /**< packed 4:4:4 */
.yuy2 = 0
.yuy2 = 0, /**< packed 4:2:2 */
.y210 = 0, /**< packed 4:2:2 10-bit */
.y216 = 0, /**< packed 4:2:2 16-bit */
.p210 = 0, /**< planar 4:2:2 10-bit */
.p216 = 0, /**< planar 4:2:2 16-bit */
},
.max_upscale_factor = 64000,
@ -159,6 +214,24 @@ static struct vpe_caps
.addr_alignment = 256,
.max_viewport_width = 1024,
},
.isharp_caps =
{
.support = false,
.range =
{
.min = 0,
.max = 0,
.step = 0,
},
},
.easf_support = 0,
.input_dcc_support = 0,
.input_internal_dcc = 0,
.output_dcc_support = 0,
.output_internal_dcc = 0,
.histogram_support = 0,
.frod_support = 0,
.alpha_blending_support = 0,
.alpha_fill_caps =
{
.opaque = 1,
@ -224,6 +297,9 @@ enum vpe_status vpe11_construct_resource(struct vpe_priv *vpe_priv, struct resou
res->update_output_gamma = vpe10_update_output_gamma;
res->validate_cached_param = vpe11_validate_cached_param;
res->check_alpha_fill_support = vpe10_check_alpha_fill_support;
res->reset_pipes = NULL;
res->populate_frod_param = NULL;
res->check_lut3d_compound = NULL;
res->calculate_shaper = vpe10_calculate_shaper;
return VPE_STATUS_OK;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "cdc.h"
#include "reg_helper.h"
#include "vpe10_cdc_be.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VPE20_CDC_VUPDATE_OFFSET_DEFAULT (20)
#define VPE20_CDC_VUPDATE_WIDTH_DEFAULT (60)
#define VPE20_CDC_VREADY_OFFSET_DEFAULT (150)
/* Some HW registers have been renamed, and even though there are only few exceptions, all have
* to be copied and set individually. The order is the same as in VPE10 so it's easy to compare,
* but the only thing that matters is that they both have the same set of vars/registers.
*/
#define CDC_BE_REG_LIST_VPE20(id) \
SRIDFVL_CDC(P2B_CONFIG, VPCDC_BE, id), \
SRIDFVL_CDC(GLOBAL_SYNC_CONFIG, VPCDC_BE, id), \
SRIDFVL1(VPCDC_CONTROL)
#define CDC_BE_FIELD_LIST_VPE20(post_fix) \
SFRB(VPCDC_BE0_P2B_XBAR_SEL0, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_XBAR_SEL1, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_XBAR_SEL2, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_XBAR_SEL3, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_FORMAT_SEL, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_TILED, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_X_START_PLANE0, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(VPCDC_BE0_P2B_X_START_PLANE1, VPCDC_BE0_P2B_CONFIG, post_fix), \
SFRB(BE0_VUPDATE_OFFSET, VPCDC_BE0_GLOBAL_SYNC_CONFIG, post_fix), \
SFRB(BE0_VUPDATE_WIDTH, VPCDC_BE0_GLOBAL_SYNC_CONFIG, post_fix), \
SFRB(BE0_VREADY_OFFSET, VPCDC_BE0_GLOBAL_SYNC_CONFIG, post_fix), \
SFRB(VPCDC_FROD_EN, VPCDC_CONTROL, post_fix), \
SFRB(VPCDC_HISTOGRAM0_EN, VPCDC_CONTROL, post_fix), \
SFRB(VPCDC_HISTOGRAM1_EN, VPCDC_CONTROL, post_fix)
#define CDC_BE_REG_VARIABLE_LIST_VPE20 \
CDC_BE_REG_VARIABLE_LIST_VPE10 \
reg_id_val VPCDC_CONTROL;
#define CDC_BE_FIELD_VARIABLE_LIST_VPE20(type) \
CDC_BE_FIELD_VARIABLE_LIST_VPE10(type) \
type VPCDC_BE0_P2B_TILED; \
type VPCDC_BE0_P2B_X_START_PLANE0; \
type VPCDC_BE0_P2B_X_START_PLANE1; \
type VPCDC_FROD_EN; \
type VPCDC_HISTOGRAM0_EN; \
type VPCDC_HISTOGRAM1_EN;
/* Variable list is the same as the one for VPE10 at the moment as it's the same set of registers.
* Note that adding VPE2 specific variables must be done at the bottom so that casting can work.
* See PROGRAM_ENTRY(),the order here matters, VPE1 subset must be in the same order in VPE2 list.
*/
struct vpe20_cdc_be_registers {
CDC_BE_REG_VARIABLE_LIST_VPE20
};
struct vpe20_cdc_be_shift {
CDC_BE_FIELD_VARIABLE_LIST_VPE20(uint8_t)
};
struct vpe20_cdc_be_mask {
CDC_BE_FIELD_VARIABLE_LIST_VPE20(uint32_t)
};
struct vpe20_cdc_be {
struct cdc_be base; // base class, must be the first field
struct vpe20_cdc_be_registers *regs;
const struct vpe20_cdc_be_shift *shift;
const struct vpe20_cdc_be_mask *mask;
};
void vpe20_construct_cdc_be(struct vpe_priv *vpe_priv, struct cdc_be *cdc_be);
void vpe20_cdc_program_global_sync(
struct cdc_be *cdc_be, uint32_t vupdate_offset, uint32_t vupdate_width, uint32_t vready_offset);
void vpe20_cdc_program_p2b_config(struct cdc_be *cdc_be, enum vpe_surface_pixel_format format,
enum vpe_swizzle_mode_values swizzle, const struct vpe_rect *viewport,
const struct vpe_rect *viewport_c);
void vpe20_cdc_program_control(struct cdc_be *cdc_be, uint8_t enable_frod, uint32_t hist_dsets[]);
void vpe20_cdc_program_histo(struct cdc_be *cdc_be);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,150 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "cdc.h"
#include "reg_helper.h"
#include "vpe10_cdc_fe.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Some HW registers have been renamed, and even though there are only few exceptions, all have
* to be copied and set individually. The order is the same as in VPE10 so it's easy to compare,
* but the only thing that matters is that they both have the same set of vars/registers.
*/
#define CDC_FE_REG_LIST_VPE20(id) \
SRIDFVL1(VPEP_MGCG_CNTL), SRIDFVL1(VPCDC_SOFT_RESET), \
SRIDFVL_CDC(SURFACE_CONFIG, VPCDC_FE, id), SRIDFVL_CDC(CROSSBAR_CONFIG, VPCDC_FE, id), \
SRIDFVL_CDC(VIEWPORT_START_CONFIG, VPCDC_FE, id), \
SRIDFVL_CDC(VIEWPORT_DIMENSION_CONFIG, VPCDC_FE, id), \
SRIDFVL_CDC(VIEWPORT_START_C_CONFIG, VPCDC_FE, id), \
SRIDFVL_CDC(VIEWPORT_DIMENSION_C_CONFIG, VPCDC_FE, id), \
SRIDFVL1(VPCDC_GLOBAL_SYNC_TRIGGER), SRIDFVL1(VPEP_MEM_GLOBAL_PWR_REQ_CNTL), \
SRIDFVL2(MEM_PWR_CNTL, VPFE, id), SRIDFVL2(MEM_PWR_CNTL, VPBE, id), \
SRIDFVL1(VPCDC_3DLUT_FL_CONFIG)
#define CDC_FE_FIELD_LIST_VPE20_COMMON(post_fix) \
SFRB(VPDPP0_CLK_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPMPC_CLK_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPOPP_CLK_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPCDC_SOCCLK_G_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPCDC_SOCCLK_R_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPCDC_VPECLK_G_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPCDC_VPECLK_R_GATE_DIS, VPEP_MGCG_CNTL, post_fix), \
SFRB(VPCDC_SOCCLK_SOFT_RESET, VPCDC_SOFT_RESET, post_fix), \
SFRB(VPCDC_VPECLK_SOFT_RESET, VPCDC_SOFT_RESET, post_fix), \
SFRB(SURFACE_PIXEL_FORMAT_FE0, VPCDC_FE0_SURFACE_CONFIG, post_fix), \
SFRB(ROTATION_ANGLE_FE0, VPCDC_FE0_SURFACE_CONFIG, post_fix), \
SFRB(H_MIRROR_EN_FE0, VPCDC_FE0_SURFACE_CONFIG, post_fix), \
SFRB(PIX_SURFACE_LINEAR_FE0, VPCDC_FE0_SURFACE_CONFIG, post_fix), \
SFRB(CROSSBAR_SRC_ALPHA_FE0, VPCDC_FE0_CROSSBAR_CONFIG, post_fix), \
SFRB(CROSSBAR_SRC_Y_G_FE0, VPCDC_FE0_CROSSBAR_CONFIG, post_fix), \
SFRB(CROSSBAR_SRC_CB_B_FE0, VPCDC_FE0_CROSSBAR_CONFIG, post_fix), \
SFRB(CROSSBAR_SRC_CR_R_FE0, VPCDC_FE0_CROSSBAR_CONFIG, post_fix), \
SFRB(VIEWPORT_X_START_FE0, VPCDC_FE0_VIEWPORT_START_CONFIG, post_fix), \
SFRB(VIEWPORT_Y_START_FE0, VPCDC_FE0_VIEWPORT_START_CONFIG, post_fix), \
SFRB(VIEWPORT_WIDTH_FE0, VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG, post_fix), \
SFRB(VIEWPORT_HEIGHT_FE0, VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG, post_fix), \
SFRB(VIEWPORT_X_START_C_FE0, VPCDC_FE0_VIEWPORT_START_C_CONFIG, post_fix), \
SFRB(VIEWPORT_Y_START_C_FE0, VPCDC_FE0_VIEWPORT_START_C_CONFIG, post_fix), \
SFRB(VIEWPORT_WIDTH_C_FE0, VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG, post_fix), \
SFRB(VIEWPORT_HEIGHT_C_FE0, VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG, post_fix), \
SFRB(VPBE_GS_TRIG, VPCDC_GLOBAL_SYNC_TRIGGER, post_fix), \
SFRB(VPFE_VR_STATUS, VPCDC_VREADY_STATUS, post_fix), \
SFRB(MEM_GLOBAL_PWR_REQ_DIS, VPEP_MEM_GLOBAL_PWR_REQ_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_FORCE, VPFE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_MODE, VPFE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_STATE, VPFE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_DIS, VPFE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_FORCE, VPBE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_MODE, VPBE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_STATE, VPBE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_DIS, VPBE0_MEM_PWR_CNTL, post_fix), \
SFRB(VPCDC_3DLUT_FL_CROSSBAR_SRC_G, VPCDC_3DLUT_FL_CONFIG, post_fix), \
SFRB(VPCDC_3DLUT_FL_CROSSBAR_SRC_B, VPCDC_3DLUT_FL_CONFIG, post_fix), \
SFRB(VPCDC_3DLUT_FL_CROSSBAR_SRC_R, VPCDC_3DLUT_FL_CONFIG, post_fix)
#define CDC_FE_FIELD_LIST_VPE20(post_fix) \
CDC_FE_FIELD_LIST_VPE20_COMMON(post_fix), \
SFRB(VPCDC_3DLUT_FL_MODE, VPCDC_3DLUT_FL_CONFIG, post_fix), \
SFRB(VPCDC_3DLUT_FL_SIZE, VPCDC_3DLUT_FL_CONFIG, post_fix)
#define CDC_FE_REG_VARIABLE_LIST_VPE20_COMMON \
CDC_FE_REG_VARIABLE_LIST_VPE10 \
reg_id_val VPCDC_3DLUT_FL_CONFIG;
#define CDC_FE_REG_VARIABLE_LIST_VPE20 CDC_FE_REG_VARIABLE_LIST_VPE20_COMMON
#define CDC_FE_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
CDC_FE_FIELD_VARIABLE_LIST_VPE10(type) \
type VPCDC_3DLUT_FL_CROSSBAR_SRC_G; \
type VPCDC_3DLUT_FL_CROSSBAR_SRC_B; \
type VPCDC_3DLUT_FL_CROSSBAR_SRC_R;
#define CDC_FE_FIELD_VARIABLE_LIST_VPE20(type) \
CDC_FE_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
type VPCDC_3DLUT_FL_MODE; \
type VPCDC_3DLUT_FL_SIZE;
/* Variable list is the same as the one for VPE10 at the moment as it's the same set of registers.
* Note that adding VPE2 specific variables must be done at the bottom so that casting can work.
* See PROGRAM_ENTRY(),the order here matters, VPE1 subset must be in the same order in VPE2 list.
*/
struct vpe20_cdc_fe_registers {
CDC_FE_REG_VARIABLE_LIST_VPE20
};
struct vpe20_cdc_fe_shift {
CDC_FE_FIELD_VARIABLE_LIST_VPE20(uint8_t)
};
struct vpe20_cdc_fe_mask {
CDC_FE_FIELD_VARIABLE_LIST_VPE20(uint32_t)
};
struct vpe20_cdc_fe {
struct cdc_fe base; // base class, must be the first field
struct vpe20_cdc_fe_registers *regs;
const struct vpe20_cdc_fe_shift *shift;
const struct vpe20_cdc_fe_mask *mask;
};
void vpe20_construct_cdc_fe(struct vpe_priv *vpe_priv, struct cdc_fe *cdc_fe);
void vpe20_cdc_program_surface_config(struct cdc_fe *cdc_fe, enum vpe_surface_pixel_format format,
enum vpe_rotation_angle rotation, bool horizontal_mirror, enum vpe_swizzle_mode_values swizzle);
void vpe20_cdc_program_crossbar_config(struct cdc_fe *cdc_fe, enum vpe_surface_pixel_format format);
void vpe20_cdc_program_viewport(
struct cdc_fe *cdc_fe, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c);
void vpe20_program_3dlut_fl_config(
struct cdc_fe *cdc_fe, enum lut_dimension lut_dimension, struct vpe_3dlut *lut_3d);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,38 @@
/* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "color.h"
#include "hw_shared.h"
#include "vpe10/inc/vpe10_cm_common.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe20_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,42 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "cmd_builder.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe20_construct_cmd_builder(struct vpe_priv *vpe_priv, struct cmd_builder *cmd_builder);
enum vpe_status vpe20_build_plane_descriptor(
struct vpe_priv *vpe_priv, struct vpe_buf *buf, uint32_t cmd_idx);
enum vpe_status vpe20_build_vpe_cmd(
struct vpe_priv *vpe_priv, struct vpe_build_bufs *cur_bufs, uint32_t cmd_idx);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,189 @@
/* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/** Generic Command Header
* Generic Commands include:
* Noop, Fence, Trap,
* RegisterWrite, PollRegisterWriteMemory,
* SetLocalTimestamp, GetLocalTimestamp
* GetGlobalGPUTimestamp */
#define VPE_HEADER_SUB_OPCODE__SHIFT 8
#define VPE_HEADER_SUB_OPCODE_MASK 0x0000FF00
#define VPE_HEADER_OPCODE__SHIFT 0
#define VPE_HEADER_OPCODE_MASK 0x000000FF
#define VPE_CMD_HEADER(op, subop) \
(((subop << VPE_HEADER_SUB_OPCODE__SHIFT) & VPE_HEADER_SUB_OPCODE_MASK) | \
((op << VPE_HEADER_OPCODE__SHIFT) & VPE_HEADER_OPCODE_MASK))
/***************************
* VPE Descriptor
***************************/
#define VPE_DESC_CD__SHIFT 16
#define VPE_DESC_CD_MASK 0x00FF0000
#define VPE_DESC_ADDR__SHIFT 32
#define VPE_DESC_HIGH_ADDR_MASK 0xFFFFFFFF00000000
/* The lowest bits are reuse and tmz as bit 1 and bit 0.
Smibs will substract the address with emb gpuva to
get offset and then reuse bit will be preserved
So as long as the embedded buffer is allocated
at correct alignment (currently low addr is [31:2]
which means we need a 4 byte(2 bit) alignment),
the offset generated will still cover the
reuse bit as part of it.
Ex : Address : 0x200036 GPU Virtual Address : 0x200000
offset is 0x36 which keeps the reuse bit */
#define VPE_DESC_LOW_ADDR_MASK 0x00000000FFFFFFFF
#define VPE_DESC_REUSE_TMZ_MASK 0x000000000000003F
#define VPE_DESC_NUM_CONFIG_DESCRIPTOR__SHIFT 0
#define VPE_DESC_NUM_CONFIG_DESCRIPTOR_MASK 0x000000FF
#define VPE_DESC_REUSE__MASK 0x00000010
#define VPE_DESC_CMD_HEADER(cd) \
(VPE_CMD_HEADER(VPE_CMD_OPCODE_VPE_DESC, 0) | (((cd) << VPE_DESC_CD__SHIFT) & VPE_DESC_CD_MASK))
/***************************
* VPE Plane Config
***************************/
enum VPE_PLANE_CFG_SUBOP {
VPE_PLANE_CFG_SUBOP_1_TO_1 = 0x0,
VPE_PLANE_CFG_SUBOP_2_TO_1 = 0x1,
VPE_PLANE_CFG_SUBOP_2_TO_2 = 0x2
};
#define VPE_PLANE_ADDR_ALIGNMENT_MASK 0x3F
#define VPE_PLANE_CFG_ONE_PLANE 0
#define VPE_PLANE_CFG_TWO_PLANES 1
#define VPE_PLANE_CFG_THREE_PLANES 2
#define VPE_PLANE_CFG_NPS0__SHIFT 16
#define VPE_PLANE_CFG_NPS0_MASK 0x00030000
#define VPE_PLANE_CFG_NPD0__SHIFT 18
#define VPE_PLANE_CFG_NPD0_MASK 0x000C0000
#define VPE_PLANE_CFG_NPS1__SHIFT 20
#define VPE_PLANE_CFG_NPS1_MASK 0x00300000
#define VPE_PLANE_CFG_NPD1__SHIFT 22
#define VPE_PLANE_CFG_NPD1_MASK 0x00C00000
#define VPE_PLANE_CFG_DCOMP0__SHIFT 24
#define VPE_PLANE_CFG_DCOMP0_MASK 0x01000000
#define VPE_PLANE_CFG_DCOMP1__SHIFT 25
#define VPE_PLANE_CFG_DCOMP1_MASK 0x02000000
#define VPE_PLANE_CFG_FROD__SHIFT 27
#define VPE_PLANE_CFG_FROD_MASK 0x08000000
#define VPE_PLANE_CFG_HIST0_DSETS__SHIFT 28
#define VPE_PLANE_CFG_HIST0_DSETS_MASK 0x30000000
#define VPE_PLANE_CFG_HIST1_DSETS__SHIFT 30
#define VPE_PLANE_CFG_HIST1_DSETS_MASK 0xC0000000
#define VPE_PLANE_CFG_SCAN_PATTERN__SHIFT 0
#define VPE_PLANE_CFG_SCAN_PATTERN_MASK 0x00000007
#define VPE_PLANE_CFG_SWIZZLE_MODE__SHIFT 3
#define VPE_PLANE_CFG_SWIZZLE_MODE_MASK 0x000000F8
#define VPE_PLANE_CFG_TMZ__SHIFT 16
#define VPE_PLANE_CFG_TMZ_MASK 0x000F0000
#define VPE_PLANE_CFG_SRC_COMP_MODE__SHIFT 0
#define VPE_PLANE_CFG_SRC_COMP_MODE_MASK 0x00000001
#define VPE_META_ADDR__SHIFT 32
#define VPE_META_HIGH_ADDR_MASK 0xFFFFFFFF00000000
#define VPE_META_LOW_ADDR_MASK 0x00000000FFFFFFFF
#define VPE_PLANE_CFG_META_TMZ__SHIFT 0
#define VPE_PLANE_CFG_META_TMZ_MASK 0x0000000F
#define VPE_PLANE_CFG_META_PITCH__SHIFT 0
#define VPE_PLANE_CFG_META_PITCH_MASK 0x00003FFF
#define VPE_PLANE_CFG_PIXEL_FORMAT__SHIFT 16
#define VPE_PLANE_CFG_PIXEL_FORMAT_MASK 0x007F0000
#define VPE_PLANE_CFG_INDEPENDENT_BLOCKS__SHIFT 23
#define VPE_PLANE_CFG_INDEPENDENT_BLOCKS_MASK 0x01800000
#define VPE_PLANE_CFG_PA__SHIFT 31
#define VPE_PLANE_CFG_PA_MASK 0x80000000
#define VPE_PLANE_CFG_DST_COMP_MODE__SHIFT 0
#define VPE_PLANE_CFG_DST_COMP_MODE_MASK 0x00000003
#define VPE_PLANE_CFG_UTILE_MODE__SHIFT 4
#define VPE_PLANE_CFG_UTILE_MODE_MASK 0x00000030
#define VPE_PLANE_CFG_DATA_FORMAT__SHIFT 8
#define VPE_PLANE_CFG_DATA_FORMAT_MASK 0x00001F00
#define VPE_PLANE_CFG_VID_NUM_ENABLE__SHIFT 16
#define VPE_PLANE_CFG_VID_NUM_ENABLE_MASK 0x00010000
#define VPE_PLANE_CFG_NUM_TYPE__SHIFT 20
#define VPE_PLANE_CFG_NUM_TYPE_MASK 0x00700000
#define VPE_PLANE_CFG_MAX_COMP_BLOCK_SIZE__SHIFT 24
#define VPE_PLANE_CFG_MAX_COMP_BLOCK_SIZE_MASK 0x01000000
#define VPE_PLANE_CFG_MAX_UNCOMP_BLOCK_SIZE__SHIFT 25
#define VPE_PLANE_CFG_MAX_UNCOMP_BLOCK_SIZE_MASK 0x06000000
#define VPE_PLANE_CFG_DSET_SIZE__SHIFT 0
#define VPE_PLANE_CFG_DSET_SIZE_MASK 0x00000003
#define VPE_PLANE_ADDR__SHIFT 32
#define VPE_PLANE_HIGH_ADDR_MASK 0xFFFFFFFF00000000
#define VPE_PLANE_LOW_ADDR_MASK 0x00000000FFFFFF00
#define VPE_PLANE_CFG_PITCH__SHIFT 0
#define VPE_PLANE_CFG_PITCH_MASK 0x0000FFFF
#define VPE_PLANE_CFG_VIEWPORT_Y__SHIFT 16
#define VPE_PLANE_CFG_VIEWPORT_Y_MASK 0xFFFF0000
#define VPE_PLANE_CFG_VIEWPORT_X__SHIFT 0
#define VPE_PLANE_CFG_VIEWPORT_X_MASK 0x0000FFFF
#define VPE_PLANE_CFG_VIEWPORT_HEIGHT__SHIFT 16
#define VPE_PLANE_CFG_VIEWPORT_HEIGHT_MASK 0x3FFF0000
#define VPE_PLANE_CFG_VIEWPORT_WIDTH__SHIFT 0
#define VPE_PLANE_CFG_VIEWPORT_WIDTH_MASK 0x00003FFF
#define VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE__SHIFT 29
#define VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE_MASK 0xE0000000
#define VPE_HIST_ADDR__SHIFT 32
#define VPE_HIST_HIGH_ADDR_MASK 0xFFFFFFFF00000000
#define VPE_HIST_LOW_ADDR_MASK 0x00000000FFFFFFFF
enum VPE_PLANE_CFG_ELEMENT_SIZE {
VPE_PLANE_CFG_ELEMENT_SIZE_8BPE = 0,
VPE_PLANE_CFG_ELEMENT_SIZE_16BPE = 1,
VPE_PLANE_CFG_ELEMENT_SIZE_32BPE = 2,
VPE_PLANE_CFG_ELEMENT_SIZE_64BPE = 3
};
#define VPE_PLANE_CFG_CMD_HEADER( \
subop, nps0, npd0, nps1, npd1, dcomp0, dcomp1, frod, hist0_dsets, hist1_dsets) \
(VPE_CMD_HEADER(VPE_CMD_OPCODE_PLANE_CFG, subop) | \
(((nps0) << VPE_PLANE_CFG_NPS0__SHIFT) & VPE_PLANE_CFG_NPS0_MASK) | \
(((npd0) << VPE_PLANE_CFG_NPD0__SHIFT) & VPE_PLANE_CFG_NPD0_MASK) | \
(((nps1) << VPE_PLANE_CFG_NPS1__SHIFT) & VPE_PLANE_CFG_NPS1_MASK) | \
(((npd1) << VPE_PLANE_CFG_NPD1__SHIFT) & VPE_PLANE_CFG_NPD1_MASK) | \
(((dcomp0) << VPE_PLANE_CFG_DCOMP0__SHIFT) & VPE_PLANE_CFG_DCOMP0_MASK) | \
(((dcomp1) << VPE_PLANE_CFG_DCOMP1__SHIFT) & VPE_PLANE_CFG_DCOMP1_MASK) | \
(((frod) << VPE_PLANE_CFG_FROD__SHIFT) & VPE_PLANE_CFG_FROD_MASK) | \
(((hist0_dsets) << VPE_PLANE_CFG_HIST0_DSETS__SHIFT) & VPE_PLANE_CFG_HIST0_DSETS_MASK) | \
(((hist1_dsets) << VPE_PLANE_CFG_HIST1_DSETS__SHIFT) & VPE_PLANE_CFG_HIST1_DSETS_MASK))
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,26 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "config_writer.h"
void vpe20_config_writer_init(struct config_writer *writer);

View file

@ -0,0 +1,634 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "dpp.h"
#include "vpe10_dpp.h"
#include "transform.h"
#include "reg_helper.h"
#include "vpe_types.h"
#include "color_table.h"
#ifdef __cplusplus
extern "C" {
#endif
// Used to resolve corner case
#define DPP_SFRB(field_name, reg_name, post_fix) .field_name = reg_name##_##field_name##post_fix
#define DPP_REG_LIST_VPE20_COMMON(id) \
DPP_REG_LIST_VPE10_COMMON(id), SRIDFVL(VPCNVC_ALPHA_2BIT_LUT01, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_ALPHA_2BIT_LUT23, VPCNVC_CFG, id), SRIDFVL(VPDSCL_SC_MODE, VPDSCL, id), \
SRIDFVL(VPDSCL_SC_MATRIX_C0C1, VPDSCL, id), SRIDFVL(VPDSCL_SC_MATRIX_C2C3, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_MODE, VPDSCL, id), SRIDFVL(VPDSCL_EASF_V_MODE, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF_CNTL, VPDSCL, id), SRIDFVL(VPDSCL_EASF_V_BF_CNTL, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF_FINAL_MAX_MIN, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF_FINAL_MAX_MIN, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG0, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG1, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG2, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG3, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG4, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG5, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG6, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF1_PWL_SEG7, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG0, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG1, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG2, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG3, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG4, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_H_BF3_PWL_SEG5, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG0, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG1, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG2, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG3, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG4, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG5, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG6, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF1_PWL_SEG7, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG0, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG1, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG2, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG3, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG4, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_BF3_PWL_SEG5, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_RINGEST_FORCE, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_RINGEST_3TAP_CNTL1, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_RINGEST_3TAP_CNTL2, VPDSCL, id), \
SRIDFVL(VPDSCL_EASF_V_RINGEST_3TAP_CNTL3, VPDSCL, id), SRIDFVL(VPISHARP_MODE, VPDSCL, id), \
SRIDFVL(VPISHARP_DELTA_CTRL, VPDSCL, id), SRIDFVL(VPISHARP_DELTA_INDEX, VPDSCL, id), \
SRIDFVL(VPISHARP_DELTA_DATA, VPDSCL, id), SRIDFVL(VPISHARP_LBA_PWL_SEG0, VPDSCL, id), \
SRIDFVL(VPISHARP_LBA_PWL_SEG1, VPDSCL, id), SRIDFVL(VPISHARP_LBA_PWL_SEG2, VPDSCL, id), \
SRIDFVL(VPISHARP_LBA_PWL_SEG3, VPDSCL, id), SRIDFVL(VPISHARP_LBA_PWL_SEG4, VPDSCL, id), \
SRIDFVL(VPISHARP_LBA_PWL_SEG5, VPDSCL, id), \
SRIDFVL(VPISHARP_DELTA_LUT_MEM_PWR_CTRL, VPDSCL, id), \
SRIDFVL(VPISHARP_NLDELTA_SOFT_CLIP, VPDSCL, id), \
SRIDFVL(VPISHARP_NOISEDET_THRESHOLD, VPDSCL, id), \
SRIDFVL(VPISHARP_NOISE_GAIN_PWL, VPDSCL, id), SRIDFVL(VPCM_HIST_CNTL, VPCM, id), \
SRIDFVL(VPCM_HIST_SCALE_SRC1, VPCM, id), SRIDFVL(VPCM_HIST_SCALE_SRC3, VPCM, id), \
SRIDFVL(VPCM_HIST_BIAS_SRC1, VPCM, id), SRIDFVL(VPCM_HIST_BIAS_SRC2, VPCM, id), \
SRIDFVL(VPCM_HIST_BIAS_SRC3, VPCM, id), SRIDFVL(VPCM_HIST_COEFA_SRC2, VPCM, id), \
SRIDFVL(VPCM_HIST_COEFB_SRC2, VPCM, id), SRIDFVL(VPCM_HIST_COEFC_SRC2, VPCM, id)
#define DPP_REG_LIST_VPE20(id) \
DPP_REG_LIST_VPE20_COMMON(id), SRIDFVL(VPDSCL_VERT_FILTER_INIT_BOT, VPDSCL, id), \
SRIDFVL(VPDSCL_VERT_FILTER_INIT_BOT_C, VPDSCL, id), \
SRIDFVL(VPCNVC_PRE_DEGAM, VPCNVC_CFG, id)
#define DPP_FIELD_LIST_VPE20_COMMON(post_fix) \
DPP_FIELD_LIST_VPE10_COMMON(post_fix), \
SFRB(ALPHA_2BIT_LUT0, VPCNVC_ALPHA_2BIT_LUT01, post_fix), \
SFRB(ALPHA_2BIT_LUT1, VPCNVC_ALPHA_2BIT_LUT01, post_fix), \
SFRB(ALPHA_2BIT_LUT2, VPCNVC_ALPHA_2BIT_LUT23, post_fix), \
SFRB(ALPHA_2BIT_LUT3, VPCNVC_ALPHA_2BIT_LUT23, post_fix), \
SFRB(SCL_SC_MATRIX_MODE, VPDSCL_SC_MODE, post_fix), \
SFRB(SCL_SC_MATRIX_C0, VPDSCL_SC_MATRIX_C0C1, post_fix), \
SFRB(SCL_SC_MATRIX_C1, VPDSCL_SC_MATRIX_C0C1, post_fix), \
SFRB(SCL_SC_MATRIX_C2, VPDSCL_SC_MATRIX_C2C3, post_fix), \
SFRB(SCL_SC_MATRIX_C3, VPDSCL_SC_MATRIX_C2C3, post_fix), \
SFRB(SCL_SC_LTONL_EN, VPDSCL_SC_MODE, post_fix), \
SFRB(SCL_EASF_H_EN, VPDSCL_EASF_H_MODE, post_fix), \
SFRB(SCL_EASF_H_RINGEST_FORCE_EN, VPDSCL_EASF_H_MODE, post_fix), \
SFRB(SCL_EASF_H_2TAP_SHARP_FACTOR, VPDSCL_EASF_H_MODE, post_fix), \
SFRB(SCL_EASF_V_EN, VPDSCL_EASF_V_MODE, post_fix), \
SFRB(SCL_EASF_V_RINGEST_FORCE_EN, VPDSCL_EASF_V_MODE, post_fix), \
SFRB(SCL_EASF_V_2TAP_SHARP_FACTOR, VPDSCL_EASF_V_MODE, post_fix), \
SFRB(SCL_EASF_H_BF1_EN, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_BF2_MODE, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_BF3_MODE, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_BF2_FLAT1_GAIN, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_BF2_FLAT2_GAIN, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_BF2_ROC_GAIN, VPDSCL_EASF_H_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF1_EN, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF2_MODE, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF3_MODE, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF2_FLAT1_GAIN, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF2_FLAT2_GAIN, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_V_BF2_ROC_GAIN, VPDSCL_EASF_V_BF_CNTL, post_fix), \
SFRB(SCL_EASF_H_RINGEST_EVENTAP_GAIN1, VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN, post_fix), \
SFRB(SCL_EASF_H_RINGEST_EVENTAP_GAIN2, VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN, post_fix), \
SFRB(SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE, post_fix), \
SFRB(SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE, post_fix), \
SFRB(SCL_EASF_V_RINGEST_EVENTAP_GAIN1, VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN, post_fix), \
SFRB(SCL_EASF_V_RINGEST_EVENTAP_GAIN2, VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN, post_fix), \
SFRB(SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE, post_fix), \
SFRB(SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE, post_fix), \
SFRB(SCL_EASF_H_BF_MAXA, VPDSCL_EASF_H_BF_FINAL_MAX_MIN, post_fix), \
SFRB(SCL_EASF_H_BF_MAXB, VPDSCL_EASF_H_BF_FINAL_MAX_MIN, post_fix), \
SFRB(SCL_EASF_H_BF_MINA, VPDSCL_EASF_H_BF_FINAL_MAX_MIN, post_fix), \
SFRB(SCL_EASF_H_BF_MINB, VPDSCL_EASF_H_BF_FINAL_MAX_MIN, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG0, VPDSCL_EASF_H_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG0, VPDSCL_EASF_H_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG0, VPDSCL_EASF_H_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG1, VPDSCL_EASF_H_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG1, VPDSCL_EASF_H_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG1, VPDSCL_EASF_H_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG2, VPDSCL_EASF_H_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG2, VPDSCL_EASF_H_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG2, VPDSCL_EASF_H_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG3, VPDSCL_EASF_H_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG3, VPDSCL_EASF_H_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG3, VPDSCL_EASF_H_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG4, VPDSCL_EASF_H_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG4, VPDSCL_EASF_H_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG4, VPDSCL_EASF_H_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG5, VPDSCL_EASF_H_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG5, VPDSCL_EASF_H_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG5, VPDSCL_EASF_H_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG6, VPDSCL_EASF_H_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG6, VPDSCL_EASF_H_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_SLOPE_SEG6, VPDSCL_EASF_H_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_IN_SEG7, VPDSCL_EASF_H_BF1_PWL_SEG7, post_fix), \
SFRB(SCL_EASF_H_BF1_PWL_BASE_SEG7, VPDSCL_EASF_H_BF1_PWL_SEG7, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG0, VPDSCL_EASF_H_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG0, VPDSCL_EASF_H_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_SLOPE_SEG0, VPDSCL_EASF_H_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG1, VPDSCL_EASF_H_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG1, VPDSCL_EASF_H_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_SLOPE_SEG1, VPDSCL_EASF_H_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG2, VPDSCL_EASF_H_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG2, VPDSCL_EASF_H_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_SLOPE_SEG2, VPDSCL_EASF_H_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG3, VPDSCL_EASF_H_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG3, VPDSCL_EASF_H_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_SLOPE_SEG3, VPDSCL_EASF_H_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG4, VPDSCL_EASF_H_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG4, VPDSCL_EASF_H_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_SLOPE_SEG4, VPDSCL_EASF_H_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_IN_SEG5, VPDSCL_EASF_H_BF3_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_H_BF3_PWL_BASE_SEG5, VPDSCL_EASF_H_BF3_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG0, VPDSCL_EASF_V_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG0, VPDSCL_EASF_V_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG0, VPDSCL_EASF_V_BF1_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG1, VPDSCL_EASF_V_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG1, VPDSCL_EASF_V_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG1, VPDSCL_EASF_V_BF1_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG2, VPDSCL_EASF_V_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG2, VPDSCL_EASF_V_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG2, VPDSCL_EASF_V_BF1_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG3, VPDSCL_EASF_V_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG3, VPDSCL_EASF_V_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG3, VPDSCL_EASF_V_BF1_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG4, VPDSCL_EASF_V_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG4, VPDSCL_EASF_V_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG4, VPDSCL_EASF_V_BF1_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG5, VPDSCL_EASF_V_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG5, VPDSCL_EASF_V_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG5, VPDSCL_EASF_V_BF1_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG6, VPDSCL_EASF_V_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG6, VPDSCL_EASF_V_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_SLOPE_SEG6, VPDSCL_EASF_V_BF1_PWL_SEG6, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_IN_SEG7, VPDSCL_EASF_V_BF1_PWL_SEG7, post_fix), \
SFRB(SCL_EASF_V_BF1_PWL_BASE_SEG7, VPDSCL_EASF_V_BF1_PWL_SEG7, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG0, VPDSCL_EASF_V_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG0, VPDSCL_EASF_V_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_SLOPE_SEG0, VPDSCL_EASF_V_BF3_PWL_SEG0, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG1, VPDSCL_EASF_V_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG1, VPDSCL_EASF_V_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_SLOPE_SEG1, VPDSCL_EASF_V_BF3_PWL_SEG1, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG2, VPDSCL_EASF_V_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG2, VPDSCL_EASF_V_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_SLOPE_SEG2, VPDSCL_EASF_V_BF3_PWL_SEG2, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG3, VPDSCL_EASF_V_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG3, VPDSCL_EASF_V_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_SLOPE_SEG3, VPDSCL_EASF_V_BF3_PWL_SEG3, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG4, VPDSCL_EASF_V_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG4, VPDSCL_EASF_V_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_SLOPE_SEG4, VPDSCL_EASF_V_BF3_PWL_SEG4, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_IN_SEG5, VPDSCL_EASF_V_BF3_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_V_BF3_PWL_BASE_SEG5, VPDSCL_EASF_V_BF3_PWL_SEG5, post_fix), \
SFRB(SCL_EASF_H_RINGEST_FORCE, VPDSCL_EASF_RINGEST_FORCE, post_fix), \
SFRB(SCL_EASF_V_RINGEST_FORCE, VPDSCL_EASF_RINGEST_FORCE, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, VPDSCL_EASF_V_RINGEST_3TAP_CNTL1, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, VPDSCL_EASF_V_RINGEST_3TAP_CNTL1, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, VPDSCL_EASF_V_RINGEST_3TAP_CNTL2, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, VPDSCL_EASF_V_RINGEST_3TAP_CNTL2, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, VPDSCL_EASF_V_RINGEST_3TAP_CNTL3, post_fix), \
SFRB(SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, VPDSCL_EASF_V_RINGEST_3TAP_CNTL3, post_fix), \
SFRB(ISHARP_EN, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_NOISEDET_EN, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_NOISEDET_MODE, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_LBA_MODE, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_DELTA_LUT_SELECT_CURRENT, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_FMT_MODE, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_FMT_NORM, VPISHARP_MODE, post_fix), \
SFRB(ISHARP_DELTA_LUT_HOST_SELECT, VPISHARP_DELTA_CTRL, post_fix), \
SFRB(ISHARP_DELTA_INDEX, VPISHARP_DELTA_INDEX, post_fix), \
SFRB(ISHARP_DELTA_DATA, VPISHARP_DELTA_DATA, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG0, VPISHARP_LBA_PWL_SEG0, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG0, VPISHARP_LBA_PWL_SEG0, post_fix), \
SFRB(ISHARP_LBA_PWL_SLOPE_SEG0, VPISHARP_LBA_PWL_SEG0, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG1, VPISHARP_LBA_PWL_SEG1, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG1, VPISHARP_LBA_PWL_SEG1, post_fix), \
SFRB(ISHARP_LBA_PWL_SLOPE_SEG1, VPISHARP_LBA_PWL_SEG1, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG2, VPISHARP_LBA_PWL_SEG2, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG2, VPISHARP_LBA_PWL_SEG2, post_fix), \
SFRB(ISHARP_LBA_PWL_SLOPE_SEG2, VPISHARP_LBA_PWL_SEG2, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG3, VPISHARP_LBA_PWL_SEG3, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG3, VPISHARP_LBA_PWL_SEG3, post_fix), \
SFRB(ISHARP_LBA_PWL_SLOPE_SEG3, VPISHARP_LBA_PWL_SEG3, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG4, VPISHARP_LBA_PWL_SEG4, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG4, VPISHARP_LBA_PWL_SEG4, post_fix), \
SFRB(ISHARP_LBA_PWL_SLOPE_SEG4, VPISHARP_LBA_PWL_SEG4, post_fix), \
SFRB(ISHARP_LBA_PWL_IN_SEG5, VPISHARP_LBA_PWL_SEG5, post_fix), \
SFRB(ISHARP_LBA_PWL_BASE_SEG5, VPISHARP_LBA_PWL_SEG5, post_fix), \
SFRB(ISHARP_DELTA_LUT_MEM_PWR_FORCE, VPISHARP_DELTA_LUT_MEM_PWR_CTRL, post_fix), \
SFRB(ISHARP_DELTA_LUT_MEM_PWR_DIS, VPISHARP_DELTA_LUT_MEM_PWR_CTRL, post_fix), \
SFRB(ISHARP_DELTA_LUT_MEM_PWR_STATE, VPISHARP_DELTA_LUT_MEM_PWR_CTRL, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_EN_P, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_PIVOT_P, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_SLOPE_P, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_EN_N, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_PIVOT_N, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NLDELTA_SCLIP_SLOPE_N, VPISHARP_NLDELTA_SOFT_CLIP, post_fix), \
SFRB(ISHARP_NOISEDET_UTHRE, VPISHARP_NOISEDET_THRESHOLD, post_fix), \
SFRB(ISHARP_NOISEDET_DTHRE, VPISHARP_NOISEDET_THRESHOLD, post_fix), \
SFRB(ISHARP_NOISEDET_PWL_START_IN, VPISHARP_NOISE_GAIN_PWL, post_fix), \
SFRB(ISHARP_NOISEDET_PWL_END_IN, VPISHARP_NOISE_GAIN_PWL, post_fix), \
SFRB(ISHARP_NOISEDET_PWL_SLOPE, VPISHARP_NOISE_GAIN_PWL, post_fix), \
SFRB(LUMA_KEYER_EN, VPCNVC_COLOR_KEYER_CONTROL, post_fix), \
SFRB(VPCM_HIST_CH_EN, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_SRC1_SEL, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_SRC2_SEL, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_SRC3_SEL, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_SEL, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_CH1_XBAR, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_CH2_XBAR, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_CH3_XBAR, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_FORMAT, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_READ_CHANNEL_MASK, VPCM_HIST_CNTL, post_fix), \
SFRB(VPCM_HIST_SCALE_SRC1, VPCM_HIST_SCALE_SRC1, post_fix), \
SFRB(VPCM_HIST_SCALE_SRC3, VPCM_HIST_SCALE_SRC3, post_fix), \
SFRB(VPCM_HIST_BIAS_SRC1, VPCM_HIST_BIAS_SRC1, post_fix), \
SFRB(VPCM_HIST_BIAS_SRC2, VPCM_HIST_BIAS_SRC2, post_fix), \
SFRB(VPCM_HIST_BIAS_SRC3, VPCM_HIST_BIAS_SRC3, post_fix), \
SFRB(VPCM_HIST_COEFA_SRC2, VPCM_HIST_COEFA_SRC2, post_fix), \
SFRB(VPCM_HIST_COEFB_SRC2, VPCM_HIST_COEFB_SRC2, post_fix), \
SFRB(VPCM_HIST_COEFC_SRC2, VPCM_HIST_COEFC_SRC2, post_fix)
#define DPP_FIELD_LIST_VPE20(post_fix) \
DPP_FIELD_LIST_VPE20_COMMON(post_fix), \
SFRB(VPCM_GAMCOR_LUT_CONFIG_MODE, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(SCL_V_INIT_FRAC_BOT, VPDSCL_VERT_FILTER_INIT_BOT, post_fix), \
SFRB(SCL_V_INIT_INT_BOT, VPDSCL_VERT_FILTER_INIT_BOT, post_fix), \
SFRB(SCL_V_INIT_FRAC_BOT_C, VPDSCL_VERT_FILTER_INIT_BOT_C, post_fix), \
SFRB(SCL_V_INIT_INT_BOT_C, VPDSCL_VERT_FILTER_INIT_BOT_C, post_fix), \
SFRB(PRE_DEGAM_MODE, VPCNVC_PRE_DEGAM, post_fix), \
SFRB(PRE_DEGAM_SELECT, VPCNVC_PRE_DEGAM, post_fix)
#define DPP_REG_VARIABLE_LIST_VPE20_COMMON \
DPP_REG_VARIABLE_LIST_VPE10_COMMON \
reg_id_val VPCNVC_ALPHA_2BIT_LUT01; \
reg_id_val VPCNVC_ALPHA_2BIT_LUT23; \
reg_id_val VPDSCL_SC_MODE; \
reg_id_val VPDSCL_SC_MATRIX_C0C1; \
reg_id_val VPDSCL_SC_MATRIX_C2C3; \
reg_id_val VPDSCL_EASF_H_MODE; \
reg_id_val VPDSCL_EASF_V_MODE; \
reg_id_val VPDSCL_EASF_H_BF_CNTL; \
reg_id_val VPDSCL_EASF_V_BF_CNTL; \
reg_id_val VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN; \
reg_id_val VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE; \
reg_id_val VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN; \
reg_id_val VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE; \
reg_id_val VPDSCL_EASF_H_BF_FINAL_MAX_MIN; \
reg_id_val VPDSCL_EASF_V_BF_FINAL_MAX_MIN; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG0; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG1; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG2; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG3; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG4; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG5; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG6; \
reg_id_val VPDSCL_EASF_H_BF1_PWL_SEG7; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG0; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG1; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG2; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG3; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG4; \
reg_id_val VPDSCL_EASF_H_BF3_PWL_SEG5; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG0; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG1; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG2; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG3; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG4; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG5; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG6; \
reg_id_val VPDSCL_EASF_V_BF1_PWL_SEG7; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG0; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG1; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG2; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG3; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG4; \
reg_id_val VPDSCL_EASF_V_BF3_PWL_SEG5; \
reg_id_val VPDSCL_EASF_RINGEST_FORCE; \
reg_id_val VPDSCL_EASF_V_RINGEST_3TAP_CNTL1; \
reg_id_val VPDSCL_EASF_V_RINGEST_3TAP_CNTL2; \
reg_id_val VPDSCL_EASF_V_RINGEST_3TAP_CNTL3; \
reg_id_val VPISHARP_MODE; \
reg_id_val VPISHARP_DELTA_CTRL; \
reg_id_val VPISHARP_DELTA_INDEX; \
reg_id_val VPISHARP_DELTA_DATA; \
reg_id_val VPISHARP_LBA_PWL_SEG0; \
reg_id_val VPISHARP_LBA_PWL_SEG1; \
reg_id_val VPISHARP_LBA_PWL_SEG2; \
reg_id_val VPISHARP_LBA_PWL_SEG3; \
reg_id_val VPISHARP_LBA_PWL_SEG4; \
reg_id_val VPISHARP_LBA_PWL_SEG5; \
reg_id_val VPISHARP_DELTA_LUT_MEM_PWR_CTRL; \
reg_id_val VPISHARP_NLDELTA_SOFT_CLIP; \
reg_id_val VPISHARP_NOISEDET_THRESHOLD; \
reg_id_val VPISHARP_NOISE_GAIN_PWL; \
reg_id_val VPCM_HIST_CNTL; \
reg_id_val VPCM_HIST_SCALE_SRC1; \
reg_id_val VPCM_HIST_SCALE_SRC3; \
reg_id_val VPCM_HIST_BIAS_SRC1; \
reg_id_val VPCM_HIST_BIAS_SRC2; \
reg_id_val VPCM_HIST_BIAS_SRC3; \
reg_id_val VPCM_HIST_COEFA_SRC2; \
reg_id_val VPCM_HIST_COEFB_SRC2; \
reg_id_val VPCM_HIST_COEFC_SRC2;
#define DPP_REG_VARIABLE_LIST_VPE20 \
DPP_REG_VARIABLE_LIST_VPE20_COMMON \
reg_id_val VPDSCL_VERT_FILTER_INIT_BOT; \
reg_id_val VPDSCL_VERT_FILTER_INIT_BOT_C; \
reg_id_val VPCNVC_PRE_DEGAM;
#define DPP_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
DPP_FIELD_VARIABLE_LIST_VPE10_COMMON(type) \
type SCL_SC_MATRIX_MODE; \
type SCL_SC_LTONL_EN; \
type SCL_SC_MATRIX_C0; \
type SCL_SC_MATRIX_C1; \
type SCL_SC_MATRIX_C2; \
type SCL_SC_MATRIX_C3; \
type SCL_EASF_H_EN; \
type SCL_EASF_H_RINGEST_FORCE_EN; \
type SCL_EASF_H_2TAP_SHARP_FACTOR; \
type SCL_EASF_V_EN; \
type SCL_EASF_V_RINGEST_FORCE_EN; \
type SCL_EASF_V_2TAP_SHARP_FACTOR; \
type SCL_EASF_H_BF1_EN; \
type SCL_EASF_H_BF2_MODE; \
type SCL_EASF_H_BF3_MODE; \
type SCL_EASF_H_BF2_FLAT1_GAIN; \
type SCL_EASF_H_BF2_FLAT2_GAIN; \
type SCL_EASF_H_BF2_ROC_GAIN; \
type SCL_EASF_V_BF1_EN; \
type SCL_EASF_V_BF2_MODE; \
type SCL_EASF_V_BF3_MODE; \
type SCL_EASF_V_BF2_FLAT1_GAIN; \
type SCL_EASF_V_BF2_FLAT2_GAIN; \
type SCL_EASF_V_BF2_ROC_GAIN; \
type SCL_EASF_H_RINGEST_EVENTAP_GAIN1; \
type SCL_EASF_H_RINGEST_EVENTAP_GAIN2; \
type SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1; \
type SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2; \
type SCL_EASF_V_RINGEST_EVENTAP_GAIN1; \
type SCL_EASF_V_RINGEST_EVENTAP_GAIN2; \
type SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1; \
type SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2; \
type SCL_EASF_H_BF_MAXA; \
type SCL_EASF_H_BF_MAXB; \
type SCL_EASF_H_BF_MINA; \
type SCL_EASF_H_BF_MINB; \
type SCL_EASF_V_BF_MAXA; \
type SCL_EASF_V_BF_MAXB; \
type SCL_EASF_V_BF_MINA; \
type SCL_EASF_V_BF_MINB; \
type SCL_EASF_H_BF1_PWL_IN_SEG0; \
type SCL_EASF_H_BF1_PWL_BASE_SEG0; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG0; \
type SCL_EASF_H_BF1_PWL_IN_SEG1; \
type SCL_EASF_H_BF1_PWL_BASE_SEG1; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG1; \
type SCL_EASF_H_BF1_PWL_IN_SEG2; \
type SCL_EASF_H_BF1_PWL_BASE_SEG2; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG2; \
type SCL_EASF_H_BF1_PWL_IN_SEG3; \
type SCL_EASF_H_BF1_PWL_BASE_SEG3; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG3; \
type SCL_EASF_H_BF1_PWL_IN_SEG4; \
type SCL_EASF_H_BF1_PWL_BASE_SEG4; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG4; \
type SCL_EASF_H_BF1_PWL_IN_SEG5; \
type SCL_EASF_H_BF1_PWL_BASE_SEG5; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG5; \
type SCL_EASF_H_BF1_PWL_IN_SEG6; \
type SCL_EASF_H_BF1_PWL_BASE_SEG6; \
type SCL_EASF_H_BF1_PWL_SLOPE_SEG6; \
type SCL_EASF_H_BF1_PWL_IN_SEG7; \
type SCL_EASF_H_BF1_PWL_BASE_SEG7; \
type SCL_EASF_H_BF3_PWL_IN_SEG0; \
type SCL_EASF_H_BF3_PWL_BASE_SEG0; \
type SCL_EASF_H_BF3_PWL_SLOPE_SEG0; \
type SCL_EASF_H_BF3_PWL_IN_SEG1; \
type SCL_EASF_H_BF3_PWL_BASE_SEG1; \
type SCL_EASF_H_BF3_PWL_SLOPE_SEG1; \
type SCL_EASF_H_BF3_PWL_IN_SEG2; \
type SCL_EASF_H_BF3_PWL_BASE_SEG2; \
type SCL_EASF_H_BF3_PWL_SLOPE_SEG2; \
type SCL_EASF_H_BF3_PWL_IN_SEG3; \
type SCL_EASF_H_BF3_PWL_BASE_SEG3; \
type SCL_EASF_H_BF3_PWL_SLOPE_SEG3; \
type SCL_EASF_H_BF3_PWL_IN_SEG4; \
type SCL_EASF_H_BF3_PWL_BASE_SEG4; \
type SCL_EASF_H_BF3_PWL_SLOPE_SEG4; \
type SCL_EASF_H_BF3_PWL_IN_SEG5; \
type SCL_EASF_H_BF3_PWL_BASE_SEG5; \
type SCL_EASF_V_BF1_PWL_IN_SEG0; \
type SCL_EASF_V_BF1_PWL_BASE_SEG0; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG0; \
type SCL_EASF_V_BF1_PWL_IN_SEG1; \
type SCL_EASF_V_BF1_PWL_BASE_SEG1; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG1; \
type SCL_EASF_V_BF1_PWL_IN_SEG2; \
type SCL_EASF_V_BF1_PWL_BASE_SEG2; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG2; \
type SCL_EASF_V_BF1_PWL_IN_SEG3; \
type SCL_EASF_V_BF1_PWL_BASE_SEG3; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG3; \
type SCL_EASF_V_BF1_PWL_IN_SEG4; \
type SCL_EASF_V_BF1_PWL_BASE_SEG4; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG4; \
type SCL_EASF_V_BF1_PWL_IN_SEG5; \
type SCL_EASF_V_BF1_PWL_BASE_SEG5; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG5; \
type SCL_EASF_V_BF1_PWL_IN_SEG6; \
type SCL_EASF_V_BF1_PWL_BASE_SEG6; \
type SCL_EASF_V_BF1_PWL_SLOPE_SEG6; \
type SCL_EASF_V_BF1_PWL_IN_SEG7; \
type SCL_EASF_V_BF1_PWL_BASE_SEG7; \
type SCL_EASF_V_BF3_PWL_IN_SEG0; \
type SCL_EASF_V_BF3_PWL_BASE_SEG0; \
type SCL_EASF_V_BF3_PWL_SLOPE_SEG0; \
type SCL_EASF_V_BF3_PWL_IN_SEG1; \
type SCL_EASF_V_BF3_PWL_BASE_SEG1; \
type SCL_EASF_V_BF3_PWL_SLOPE_SEG1; \
type SCL_EASF_V_BF3_PWL_IN_SEG2; \
type SCL_EASF_V_BF3_PWL_BASE_SEG2; \
type SCL_EASF_V_BF3_PWL_SLOPE_SEG2; \
type SCL_EASF_V_BF3_PWL_IN_SEG3; \
type SCL_EASF_V_BF3_PWL_BASE_SEG3; \
type SCL_EASF_V_BF3_PWL_SLOPE_SEG3; \
type SCL_EASF_V_BF3_PWL_IN_SEG4; \
type SCL_EASF_V_BF3_PWL_BASE_SEG4; \
type SCL_EASF_V_BF3_PWL_SLOPE_SEG4; \
type SCL_EASF_V_BF3_PWL_IN_SEG5; \
type SCL_EASF_V_BF3_PWL_BASE_SEG5; \
type SCL_EASF_H_RINGEST_FORCE; \
type SCL_EASF_V_RINGEST_FORCE; \
type SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT; \
type SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL; \
type SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE; \
type SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE; \
type SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE; \
type SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET; \
type ISHARP_EN; \
type ISHARP_NOISEDET_EN; \
type ISHARP_NOISEDET_MODE; \
type ISHARP_LBA_MODE; \
type ISHARP_DELTA_LUT_SELECT; \
type ISHARP_FMT_MODE; \
type ISHARP_FMT_NORM; \
type ISHARP_DELTA_LUT_SELECT_CURRENT; \
type ISHARP_DELTA_LUT_HOST_SELECT; \
type ISHARP_DELTA_INDEX; \
type ISHARP_DELTA_DATA; \
type ISHARP_LBA_PWL_IN_SEG0; \
type ISHARP_LBA_PWL_BASE_SEG0; \
type ISHARP_LBA_PWL_SLOPE_SEG0; \
type ISHARP_LBA_PWL_IN_SEG1; \
type ISHARP_LBA_PWL_BASE_SEG1; \
type ISHARP_LBA_PWL_SLOPE_SEG1; \
type ISHARP_LBA_PWL_IN_SEG2; \
type ISHARP_LBA_PWL_BASE_SEG2; \
type ISHARP_LBA_PWL_SLOPE_SEG2; \
type ISHARP_LBA_PWL_IN_SEG3; \
type ISHARP_LBA_PWL_BASE_SEG3; \
type ISHARP_LBA_PWL_SLOPE_SEG3; \
type ISHARP_LBA_PWL_IN_SEG4; \
type ISHARP_LBA_PWL_BASE_SEG4; \
type ISHARP_LBA_PWL_SLOPE_SEG4; \
type ISHARP_LBA_PWL_IN_SEG5; \
type ISHARP_LBA_PWL_BASE_SEG5; \
type ISHARP_DELTA_LUT_MEM_PWR_FORCE; \
type ISHARP_DELTA_LUT_MEM_PWR_DIS; \
type ISHARP_DELTA_LUT_MEM_PWR_STATE; \
type ISHARP_NLDELTA_SCLIP_EN_P; \
type ISHARP_NLDELTA_SCLIP_PIVOT_P; \
type ISHARP_NLDELTA_SCLIP_SLOPE_P; \
type ISHARP_NLDELTA_SCLIP_EN_N; \
type ISHARP_NLDELTA_SCLIP_PIVOT_N; \
type ISHARP_NLDELTA_SCLIP_SLOPE_N; \
type ISHARP_NOISEDET_UTHRE; \
type ISHARP_NOISEDET_DTHRE; \
type ISHARP_NOISEDET_PWL_START_IN; \
type ISHARP_NOISEDET_PWL_END_IN; \
type ISHARP_NOISEDET_PWL_SLOPE; \
type LUMA_KEYER_EN; \
type VPCM_HIST_SEL; \
type VPCM_HIST_CH_EN; \
type VPCM_HIST_SRC1_SEL; \
type VPCM_HIST_SRC2_SEL; \
type VPCM_HIST_SRC3_SEL; \
type VPCM_HIST_CH1_XBAR; \
type VPCM_HIST_CH2_XBAR; \
type VPCM_HIST_CH3_XBAR; \
type VPCM_HIST_FORMAT; \
type VPCM_HIST_READ_CHANNEL_MASK; \
type VPCM_HIST_SCALE_SRC1; \
type VPCM_HIST_SCALE_SRC3; \
type VPCM_HIST_BIAS_SRC1; \
type VPCM_HIST_BIAS_SRC2; \
type VPCM_HIST_BIAS_SRC3; \
type VPCM_HIST_COEFA_SRC2; \
type VPCM_HIST_COEFB_SRC2; \
type VPCM_HIST_COEFC_SRC2; \
type VPCNVC_FORMAT_CROSSBAR_R; \
type VPCNVC_FORMAT_CROSSBAR_G; \
type VPCNVC_FORMAT_CROSSBAR_B;
#define DPP_FIELD_VARIABLE_LIST_VPE20(type) \
DPP_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
type VPCM_GAMCOR_LUT_CONFIG_MODE; \
type SCL_V_INIT_FRAC_BOT; \
type SCL_V_INIT_INT_BOT; \
type SCL_V_INIT_FRAC_BOT_C; \
type SCL_V_INIT_INT_BOT_C; \
type PRE_DEGAM_MODE; \
type PRE_DEGAM_SELECT;
struct vpe20_dpp_registers {
DPP_REG_VARIABLE_LIST_VPE20
};
struct vpe20_dpp_shift {
DPP_FIELD_VARIABLE_LIST_VPE20(uint8_t)
};
struct vpe20_dpp_mask {
DPP_FIELD_VARIABLE_LIST_VPE20(uint32_t)
};
struct vpe20_dpp {
struct dpp base; // base class, must be the 1st field
struct vpe20_dpp_registers *regs;
const struct vpe20_dpp_shift *shift;
const struct vpe20_dpp_mask *mask;
};
enum vpe10_dscl_mode_sel vpe20_dpp_dscl_get_dscl_mode(const struct scaler_data *data);
void vpe20_construct_dpp(struct vpe_priv *vpe_priv, struct dpp *dpp);
void vpe20_dpp_set_segment_scaler(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe20_dpp_dscl_set_scaler_position(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe20_dpp_set_frame_scaler(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe20_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf);
void vpe20_dscl_program_easf(struct dpp *dpp_base, const struct scaler_data *scl_data);
void vpe20_dscl_disable_easf(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe20_dscl_program_isharp(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe20_dpp_enable_clocks(struct dpp *dpp, bool enable);
void vpe20_dpp_cnv_program_alpha_keyer(
struct dpp *dpp, const struct cnv_keyer_params *keyer_params);
void vpe20_dpp_program_cnv(
struct dpp *dpp, enum vpe_surface_pixel_format format, enum vpe_expansion_mode mode);
void vpe20_dpp_program_histo(struct dpp* dpp, struct vpe_histogram_param* hist_para, enum color_space csm);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,709 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "mpc.h"
#include "reg_helper.h"
#include "vpe10_mpc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RMCM_MPCC_DISCONNECTED 0xf
#define MPC_REG_LIST_VPE20_COMMON(id) \
MPC_REG_LIST_VPE10_COMMON(id), \
SRIDFVL(VPMPCC_MCM_FIRST_GAMUT_REMAP_COEF_FORMAT, VPMPCC_MCM, id), \
SRIDFVL(VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C11_C12_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C13_C14_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C21_C22_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C23_C24_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C31_C32_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_FIRST_GAMUT_REMAP_C33_C34_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPCC_MCM_SECOND_GAMUT_REMAP_COEF_FORMAT, VPMPCC_MCM, id), \
SRIDFVL(VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C11_C12_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C13_C14_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C21_C22_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C23_C24_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C31_C32_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPC_MCM_SECOND_GAMUT_REMAP_C33_C34_SETA, VPMPCC_MCM, id), \
SRIDFVL(VPMPCC_CONTROL2, VPMPCC, id)
#define MPC_REG_LIST_VPE20(id) \
MPC_REG_LIST_VPE20_COMMON(id), SRIDFVL3(SHAPER_CONTROL, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_OFFSET_R, VPMPC_RMCM, id), SRIDFVL3(SHAPER_OFFSET_G, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_OFFSET_B, VPMPC_RMCM, id), SRIDFVL3(SHAPER_SCALE_R, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_SCALE_G_B, VPMPC_RMCM, id), SRIDFVL3(SHAPER_LUT_INDEX, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_LUT_DATA, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_LUT_WRITE_EN_MASK, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_START_CNTL_B, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_START_CNTL_G, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_START_CNTL_R, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_END_CNTL_B, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_END_CNTL_G, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_END_CNTL_R, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_0_1, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_2_3, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_4_5, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_6_7, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_8_9, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_10_11, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_12_13, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_14_15, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_16_17, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_18_19, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_20_21, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_22_23, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_24_25, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_26_27, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_28_29, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_30_31, VPMPC_RMCM, id), \
SRIDFVL3(SHAPER_RAMA_REGION_32_33, VPMPC_RMCM, id), SRIDFVL3(3DLUT_MODE, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_INDEX, VPMPC_RMCM, id), SRIDFVL3(3DLUT_DATA, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_DATA_30BIT, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_READ_WRITE_CONTROL, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_OUT_NORM_FACTOR, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_OUT_OFFSET_R, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_OUT_OFFSET_G, VPMPC_RMCM, id), \
SRIDFVL3(3DLUT_OUT_OFFSET_B, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_COEF_FORMAT, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_MODE, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C11_C12_SETA, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C13_C14_SETA, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C21_C22_SETA, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C23_C24_SETA, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C31_C32_SETA, VPMPC_RMCM, id), \
SRIDFVL3(GAMUT_REMAP_C33_C34_SETA, VPMPC_RMCM, id), \
SRIDFVL3(MEM_PWR_CTRL, VPMPC_RMCM, id), SRIDFVL3(3DLUT_FAST_LOAD_SELECT, VPMPC_RMCM, id), \
SRIDFVL3(CNTL, VPMPC_RMCM, id), SRIDFVL1(VPMPC_VPCDC0_3DLUT_FL_CONFIG), \
SRIDFVL1(VPMPC_VPCDC0_3DLUT_FL_BIAS_SCALE)
#define MPC_FIELD_LIST_VPE20_COMMON(post_fix) \
MPC_FIELD_LIST_VPE10_COMMON(post_fix), SFRB(VPMPC_RMCM_CNTL, VPMPC_RMCM_CNTL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_LUT_MODE, VPMPC_RMCM_SHAPER_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_MODE_CURRENT, VPMPC_RMCM_SHAPER_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_SELECT_CURRENT, VPMPC_RMCM_SHAPER_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_OFFSET_R, VPMPC_RMCM_SHAPER_OFFSET_R, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_OFFSET_G, VPMPC_RMCM_SHAPER_OFFSET_G, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_OFFSET_B, VPMPC_RMCM_SHAPER_OFFSET_B, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_SCALE_R, VPMPC_RMCM_SHAPER_SCALE_R, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_LUT_INDEX, VPMPC_RMCM_SHAPER_LUT_INDEX, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_LUT_DATA, VPMPC_RMCM_SHAPER_LUT_DATA, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK, VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_LUT_WRITE_SEL, VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_B, VPMPC_RMCM_SHAPER_RAMA_START_CNTL_B, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, \
VPMPC_RMCM_SHAPER_RAMA_START_CNTL_B, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_G, VPMPC_RMCM_SHAPER_RAMA_START_CNTL_G, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, \
VPMPC_RMCM_SHAPER_RAMA_START_CNTL_G, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_R, VPMPC_RMCM_SHAPER_RAMA_START_CNTL_R, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, \
VPMPC_RMCM_SHAPER_RAMA_START_CNTL_R, post_fix), \
SFRB( \
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_B, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_B, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_B, \
post_fix), \
SFRB( \
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_G, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_G, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_G, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_G, \
post_fix), \
SFRB( \
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_R, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_R, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_R, VPMPC_RMCM_SHAPER_RAMA_END_CNTL_R, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_0_1, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_0_1, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_0_1, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_0_1, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_2_3, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_2_3, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_2_3, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_2_3, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_4_5, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_4_5, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_4_5, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_4_5, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_6_7, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_6_7, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_6_7, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_6_7, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_8_9, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_8_9, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_8_9, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, VPMPC_RMCM_SHAPER_RAMA_REGION_8_9, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_10_11, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_10_11, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_10_11, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_10_11, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_12_13, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_12_13, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_12_13, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_12_13, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_14_15, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_14_15, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_14_15, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_14_15, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_16_17, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_16_17, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_16_17, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_16_17, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_18_19, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_18_19, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_18_19, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_18_19, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_20_21, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_20_21, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_20_21, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_20_21, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_22_23, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_22_23, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_22_23, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_22_23, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_24_25, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_24_25, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_24_25, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_24_25, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_26_27, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_26_27, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_26_27, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_26_27, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_28_29, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_28_29, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_28_29, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_28_29, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_30_31, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_30_31, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_30_31, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_30_31, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_32_33, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_32_33, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, VPMPC_RMCM_SHAPER_RAMA_REGION_32_33, \
post_fix), \
SFRB(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, \
VPMPC_RMCM_SHAPER_RAMA_REGION_32_33, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MODE, VPMPC_RMCM_3DLUT_MODE, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_SIZE, VPMPC_RMCM_3DLUT_MODE, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MODE_CURRENT, VPMPC_RMCM_3DLUT_MODE, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_SELECT_CURRENT, VPMPC_RMCM_3DLUT_MODE, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_INDEX, VPMPC_RMCM_3DLUT_INDEX, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_DATA0, VPMPC_RMCM_3DLUT_DATA, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_DATA1, VPMPC_RMCM_3DLUT_DATA, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_DATA_30BIT, VPMPC_RMCM_3DLUT_DATA_30BIT, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_WRITE_EN_MASK, VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_RAM_SEL, VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_30BIT_EN, VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_READ_SEL, VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_NORM_FACTOR, VPMPC_RMCM_3DLUT_OUT_NORM_FACTOR, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_OFFSET_R, VPMPC_RMCM_3DLUT_OUT_OFFSET_R, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_SCALE_R, VPMPC_RMCM_3DLUT_OUT_OFFSET_R, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_OFFSET_G, VPMPC_RMCM_3DLUT_OUT_OFFSET_G, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_SCALE_G, VPMPC_RMCM_3DLUT_OUT_OFFSET_G, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_OFFSET_B, VPMPC_RMCM_3DLUT_OUT_OFFSET_B, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_OUT_SCALE_B, VPMPC_RMCM_3DLUT_OUT_OFFSET_B, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_MEM_PWR_FORCE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_MEM_PWR_DIS, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_MEM_LOW_PWR_MODE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MEM_PWR_FORCE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MEM_PWR_DIS, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MEM_LOW_PWR_MODE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_MEM_PWR_STATE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_MEM_PWR_STATE, VPMPC_RMCM_MEM_PWR_CTRL, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_COEF_FORMAT, VPMPC_RMCM_GAMUT_REMAP_COEF_FORMAT, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_MODE, VPMPC_RMCM_GAMUT_REMAP_MODE, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_MODE_CURRENT, VPMPC_RMCM_GAMUT_REMAP_MODE, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C11_SETA, VPMPC_RMCM_GAMUT_REMAP_C11_C12_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C12_SETA, VPMPC_RMCM_GAMUT_REMAP_C11_C12_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C13_SETA, VPMPC_RMCM_GAMUT_REMAP_C13_C14_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C14_SETA, VPMPC_RMCM_GAMUT_REMAP_C13_C14_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C21_SETA, VPMPC_RMCM_GAMUT_REMAP_C21_C22_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C22_SETA, VPMPC_RMCM_GAMUT_REMAP_C21_C22_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C23_SETA, VPMPC_RMCM_GAMUT_REMAP_C23_C24_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C24_SETA, VPMPC_RMCM_GAMUT_REMAP_C23_C24_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C31_SETA, VPMPC_RMCM_GAMUT_REMAP_C31_C32_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C32_SETA, VPMPC_RMCM_GAMUT_REMAP_C31_C32_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C33_SETA, VPMPC_RMCM_GAMUT_REMAP_C33_C34_SETA, post_fix), \
SFRB(VPMPC_RMCM_GAMUT_REMAP_C34_SETA, VPMPC_RMCM_GAMUT_REMAP_C33_C34_SETA, post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_COEF_FORMAT, VPMPCC_MCM_FIRST_GAMUT_REMAP_COEF_FORMAT, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C11_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C11_C12_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C12_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C11_C12_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C13_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C13_C14_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C14_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C13_C14_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C21_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C21_C22_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C22_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C21_C22_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C23_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C23_C24_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C24_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C23_C24_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C31_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C31_C32_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C32_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C31_C32_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C33_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C33_C34_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_FIRST_GAMUT_REMAP_C34_SETA, VPMPC_MCM_FIRST_GAMUT_REMAP_C33_C34_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_COEF_FORMAT, VPMPCC_MCM_SECOND_GAMUT_REMAP_COEF_FORMAT, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C11_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C11_C12_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C12_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C11_C12_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C13_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C13_C14_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C14_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C13_C14_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C21_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C21_C22_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C22_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C21_C22_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C23_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C23_C24_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C24_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C23_C24_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C31_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C31_C32_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C32_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C31_C32_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C33_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C33_C34_SETA, \
post_fix), \
SFRB(VPMPCC_MCM_SECOND_GAMUT_REMAP_C34_SETA, VPMPC_MCM_SECOND_GAMUT_REMAP_C33_C34_SETA, \
post_fix), \
SFRB(VPMPCC_GLOBAL_ALPHA, VPMPCC_CONTROL2, post_fix), \
SFRB(VPMPCC_GLOBAL_GAIN, VPMPCC_CONTROL2, post_fix)
#define MPC_FIELD_LIST_VPE20(post_fix) \
MPC_FIELD_LIST_VPE20_COMMON(post_fix), \
SFRB(VPMPC_RMCM_SHAPER_SCALE_G, VPMPC_RMCM_SHAPER_SCALE_G_B, post_fix), \
SFRB(VPMPC_RMCM_SHAPER_SCALE_B, VPMPC_RMCM_SHAPER_SCALE_G_B, post_fix), \
SFRB(VPMPC_RMCM_3DLUT_FL_SEL, VPMPC_RMCM_3DLUT_FAST_LOAD_SELECT, post_fix), \
SFRB(VPCDC0_3DLUT_FL_MODE, VPMPC_VPCDC0_3DLUT_FL_CONFIG, post_fix), \
SFRB(VPCDC0_3DLUT_FL_FORMAT, VPMPC_VPCDC0_3DLUT_FL_CONFIG, post_fix), \
SFRB(VPCDC0_3DLUT_FL_BIAS, VPMPC_VPCDC0_3DLUT_FL_BIAS_SCALE, post_fix), \
SFRB(VPCDC0_3DLUT_FL_SCALE, VPMPC_VPCDC0_3DLUT_FL_BIAS_SCALE, post_fix)
#define MPC_REG_VARIABLE_LIST_VPE20_COMMON \
MPC_REG_VARIABLE_LIST_VPE10_COMMON \
reg_id_val VPMPC_RMCM_CNTL; \
reg_id_val VPMPC_RMCM_SHAPER_CONTROL; \
reg_id_val VPMPC_RMCM_SHAPER_OFFSET_R; \
reg_id_val VPMPC_RMCM_SHAPER_OFFSET_G; \
reg_id_val VPMPC_RMCM_SHAPER_OFFSET_B; \
reg_id_val VPMPC_RMCM_SHAPER_SCALE_R; \
reg_id_val VPMPC_RMCM_SHAPER_LUT_INDEX; \
reg_id_val VPMPC_RMCM_SHAPER_LUT_DATA; \
reg_id_val VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_START_CNTL_B; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_START_CNTL_G; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_START_CNTL_R; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_END_CNTL_B; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_END_CNTL_G; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_END_CNTL_R; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_0_1; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_2_3; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_4_5; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_6_7; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_8_9; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_10_11; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_12_13; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_14_15; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_16_17; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_18_19; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_20_21; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_22_23; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_24_25; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_26_27; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_28_29; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_30_31; \
reg_id_val VPMPC_RMCM_SHAPER_RAMA_REGION_32_33; \
reg_id_val VPMPC_RMCM_3DLUT_MODE; \
reg_id_val VPMPC_RMCM_3DLUT_INDEX; \
reg_id_val VPMPC_RMCM_3DLUT_DATA; \
reg_id_val VPMPC_RMCM_3DLUT_DATA_30BIT; \
reg_id_val VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL; \
reg_id_val VPMPC_RMCM_3DLUT_OUT_NORM_FACTOR; \
reg_id_val VPMPC_RMCM_3DLUT_OUT_OFFSET_R; \
reg_id_val VPMPC_RMCM_3DLUT_OUT_OFFSET_G; \
reg_id_val VPMPC_RMCM_3DLUT_OUT_OFFSET_B; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_COEF_FORMAT; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_MODE; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C11_C12_SETA; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C13_C14_SETA; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C21_C22_SETA; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C23_C24_SETA; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C31_C32_SETA; \
reg_id_val VPMPC_RMCM_GAMUT_REMAP_C33_C34_SETA; \
reg_id_val VPMPCC_MCM_FIRST_GAMUT_REMAP_COEF_FORMAT; \
reg_id_val VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C11_C12_SETA; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C13_C14_SETA; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C21_C22_SETA; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C23_C24_SETA; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C31_C32_SETA; \
reg_id_val VPMPC_MCM_FIRST_GAMUT_REMAP_C33_C34_SETA; \
reg_id_val VPMPCC_MCM_SECOND_GAMUT_REMAP_COEF_FORMAT; \
reg_id_val VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C11_C12_SETA; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C13_C14_SETA; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C21_C22_SETA; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C23_C24_SETA; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C31_C32_SETA; \
reg_id_val VPMPC_MCM_SECOND_GAMUT_REMAP_C33_C34_SETA; \
reg_id_val VPMPC_RMCM_MEM_PWR_CTRL; \
reg_id_val VPMPCC_CONTROL2; \
reg_id_val VPCM_HIST_INDEX;
#define MPC_REG_VARIABLE_LIST_VPE20 \
MPC_REG_VARIABLE_LIST_VPE20_COMMON \
reg_id_val VPMPC_RMCM_SHAPER_SCALE_G_B; \
reg_id_val VPMPC_RMCM_3DLUT_FAST_LOAD_SELECT; \
reg_id_val VPMPC_VPCDC0_3DLUT_FL_CONFIG; \
reg_id_val VPMPC_VPCDC0_3DLUT_FL_BIAS_SCALE;
#define MPC_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
MPC_FIELD_VARIABLE_LIST_VPE10_COMMON(type) \
type VPMPC_RMCM_CNTL; \
type VPMPC_RMCM_SHAPER_LUT_MODE; \
type VPMPC_RMCM_SHAPER_MODE_CURRENT; \
type VPMPC_RMCM_SHAPER_SELECT_CURRENT; \
type VPMPC_RMCM_SHAPER_OFFSET_R; \
type VPMPC_RMCM_SHAPER_OFFSET_G; \
type VPMPC_RMCM_SHAPER_OFFSET_B; \
type VPMPC_RMCM_SHAPER_SCALE_R; \
type VPMPC_RMCM_SHAPER_LUT_INDEX; \
type VPMPC_RMCM_SHAPER_LUT_DATA; \
type VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK; \
type VPMPC_RMCM_SHAPER_LUT_WRITE_SEL; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_B; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_G; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_R; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_B; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_B; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_G; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_G; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_R; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_R; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET; \
type VPMPC_RMCM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type VPMPC_RMCM_3DLUT_MODE; \
type VPMPC_RMCM_3DLUT_SIZE; \
type VPMPC_RMCM_3DLUT_MODE_CURRENT; \
type VPMPC_RMCM_3DLUT_SELECT_CURRENT; \
type VPMPC_RMCM_3DLUT_INDEX; \
type VPMPC_RMCM_3DLUT_DATA0; \
type VPMPC_RMCM_3DLUT_DATA1; \
type VPMPC_RMCM_3DLUT_DATA_30BIT; \
type VPMPC_RMCM_3DLUT_WRITE_EN_MASK; \
type VPMPC_RMCM_3DLUT_RAM_SEL; \
type VPMPC_RMCM_3DLUT_30BIT_EN; \
type VPMPC_RMCM_3DLUT_READ_SEL; \
type VPMPC_RMCM_3DLUT_OUT_NORM_FACTOR; \
type VPMPC_RMCM_3DLUT_OUT_OFFSET_R; \
type VPMPC_RMCM_3DLUT_OUT_SCALE_R; \
type VPMPC_RMCM_3DLUT_OUT_OFFSET_G; \
type VPMPC_RMCM_3DLUT_OUT_SCALE_G; \
type VPMPC_RMCM_3DLUT_OUT_OFFSET_B; \
type VPMPC_RMCM_3DLUT_OUT_SCALE_B; \
type VPMPC_RMCM_GAMUT_REMAP_COEF_FORMAT; \
type VPMPC_RMCM_GAMUT_REMAP_MODE; \
type VPMPC_RMCM_GAMUT_REMAP_MODE_CURRENT; \
type VPMPC_RMCM_GAMUT_REMAP_C11_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C12_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C13_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C14_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C21_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C22_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C23_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C24_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C31_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C32_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C33_SETA; \
type VPMPC_RMCM_GAMUT_REMAP_C34_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_COEF_FORMAT; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C11_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C12_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C13_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C14_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C21_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C22_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C23_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C24_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C31_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C32_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C33_SETA; \
type VPMPCC_MCM_FIRST_GAMUT_REMAP_C34_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_COEF_FORMAT; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C11_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C12_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C13_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C14_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C21_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C22_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C23_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C24_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C31_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C32_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C33_SETA; \
type VPMPCC_MCM_SECOND_GAMUT_REMAP_C34_SETA; \
type VPMPC_RMCM_SHAPER_MEM_PWR_STATE; \
type VPMPC_RMCM_3DLUT_MEM_PWR_STATE; \
type VPMPC_RMCM_SHAPER_MEM_PWR_FORCE; \
type VPMPC_RMCM_SHAPER_MEM_PWR_DIS; \
type VPMPC_RMCM_SHAPER_MEM_LOW_PWR_MODE; \
type VPMPC_RMCM_3DLUT_MEM_PWR_FORCE; \
type VPMPC_RMCM_3DLUT_MEM_PWR_DIS; \
type VPMPC_RMCM_3DLUT_MEM_LOW_PWR_MODE;
#define MPC_FIELD_VARIABLE_LIST_VPE20(type) \
MPC_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
type VPMPC_RMCM_SHAPER_SCALE_G; \
type VPMPC_RMCM_SHAPER_SCALE_B; \
type VPMPC_RMCM_3DLUT_FL_SEL; \
type VPCDC0_3DLUT_FL_MODE; \
type VPCDC0_3DLUT_FL_FORMAT; \
type VPCDC0_3DLUT_FL_BIAS; \
type VPCDC0_3DLUT_FL_SCALE;
struct vpe20_mpc_registers {
MPC_REG_VARIABLE_LIST_VPE20
};
struct vpe20_mpc_shift {
MPC_FIELD_VARIABLE_LIST_VPE20(uint8_t)
};
struct vpe20_mpc_mask {
MPC_FIELD_VARIABLE_LIST_VPE20(uint32_t)
};
struct vpe20_mpc {
struct mpc base;
struct vpe20_mpc_registers *regs;
const struct vpe20_mpc_shift *shift;
const struct vpe20_mpc_mask *mask;
};
void vpe20_construct_mpc(struct vpe_priv *vpe_priv, struct mpc *mpc);
void vpe20_mpc_program_mpcc_mux(struct mpc *mpc, enum mpc_mpccid mpcc_idx,
enum mpc_mux_topsel topsel, enum mpc_mux_botsel botsel, enum mpc_mux_outmux outmux,
enum mpc_mux_oppid oppid);
void vpe20_mpc_program_mpcc_blending(
struct mpc *mpc, enum mpc_mpccid mpcc_idx, struct mpcc_blnd_cfg *blnd_cfg);
void vpe20_mpc_power_on_1dlut_shaper_3dlut(struct mpc *mpc, bool power_on);
void vpe20_mpc_shaper_bypass(struct mpc *mpc, bool bypass);
bool vpe20_mpc_program_shaper(struct mpc *mpc, const struct pwl_params *params);
// using direct config to program the 3dlut specified in params
void vpe20_mpc_program_3dlut(struct mpc *mpc, const struct tetrahedral_params *params);
void vpe20_mpc_set_mpc_shaper_3dlut(
struct mpc *mpc, struct transfer_func *func_shaper, struct vpe_3dlut *lut3d_func);
// using indirect config to configure the 3DLut
// note that we still need direct config to switch the mask between lut0 - lut3
bool vpe20_mpc_program_3dlut_indirect(struct mpc *mpc,
struct vpe_buf *lut0_3_buf, // 3d lut buf which contains the data for lut0-lut3
bool use_tetrahedral_17, bool use_12bits);
void vpe20_attach_3dlut_to_mpc_inst(struct mpc *mpc, enum mpc_mpccid mpcc_idx);
bool vpe20_mpc_program_movable_cm(struct mpc *mpc, struct transfer_func *func_shaper,
struct vpe_3dlut *lut3d_func, struct transfer_func *blend_tf, bool afterblend);
void vpe20_mpc_set_gamut_remap2(struct mpc *mpc, struct colorspace_transform *gamut_remap,
enum mpcc_gamut_remap_id mpcc_gamut_remap_block_id);
void vpe20_update_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale);
void vpe20_mpc_program_3dlut_fl_config(struct mpc *mpc, enum vpe_3dlut_mem_layout layout,
enum vpe_3dlut_mem_format format, bool enable);
void vpe20_mpc_program_3dlut_fl(struct mpc *mpc, enum lut_dimension lut_dimension, bool use_12bit);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,222 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "opp.h"
#include "reg_helper.h"
#include "vpe10_opp.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Some HW registers have been renamed, and even though there are only few exceptions, all have
* to be copied and set individually. The order is the same as in VPE10 so it's easy to compare,
* but the only thing that matters is that they both have the same set of vars/registers.
*/
#define OPP_REG_LIST_VPE20(id) \
OPP_REG_LIST_VPE10_COMMON(id), \
SRIDFVL1(VPOPP_TOP_CLK_CONTROL), \
SRIDFVL(VPFMT_SUBSAMPLER_MEMORY_CONTROL, VPFMT, id), \
SRIDFVL(VPOPP_PIPE_OUTBG_EXT1, VPOPP_PIPE, id), \
SRIDFVL(VPOPP_PIPE_OUTBG_EXT2, VPOPP_PIPE, id), \
SRIDFVL(VPOPP_PIPE_OUTBG_COL1, VPOPP_PIPE, id), \
SRIDFVL(VPOPP_PIPE_OUTBG_COL2, VPOPP_PIPE, id), \
SRIDFVL1(VPOPP_CRC_CONTROL), \
SRIDFVL1(VPOPP_CRC_RESULT_RG), \
SRIDFVL1(VPOPP_CRC_RESULT_BC), \
SRIDFVL1(VPOPP_FROD_CONTROL), \
SRIDFVL1(VPOPP_FROD_MEM_PWR_CONTROL)
#define OPP_FIELD_LIST_VPE20_COMMON(post_fix) \
OPP_FIELD_LIST_VPE10_COMMON(post_fix), \
SFRB(VPFMT_PIXEL_ENCODING, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_HTAPS, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_LEFT_EDGE, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_RIGHT_EDGE, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_VTAPS, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_TOP_EDGE, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLE_BOTTOM_EDGE, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLER_MEM_PWR_FORCE, VPFMT_SUBSAMPLER_MEMORY_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLER_MEM_PWR_DIS, VPFMT_SUBSAMPLER_MEMORY_CONTROL, post_fix), \
SFRB(VPFMT_SUBSAMPLER_MEM_PWR_STATE, VPFMT_SUBSAMPLER_MEMORY_CONTROL, post_fix), \
SFRB(VPFMT_DEFAULT_MEM_LOW_POWER_STATE, VPFMT_SUBSAMPLER_MEMORY_CONTROL, post_fix), \
SFRB(OUTBG_EXT_TOP, VPOPP_PIPE_OUTBG_EXT1, post_fix), \
SFRB(OUTBG_EXT_BOT, VPOPP_PIPE_OUTBG_EXT1, post_fix), \
SFRB(OUTBG_EXT_LEFT, VPOPP_PIPE_OUTBG_EXT2, post_fix), \
SFRB(OUTBG_EXT_RIGHT, VPOPP_PIPE_OUTBG_EXT2, post_fix), \
SFRB(OUTBG_R_CR, VPOPP_PIPE_OUTBG_COL1, post_fix), \
SFRB(OUTBG_B_CB, VPOPP_PIPE_OUTBG_COL1, post_fix), \
SFRB(OUTBG_Y, VPOPP_PIPE_OUTBG_COL2, post_fix), \
SFRB(VPOPP_CRC_EN, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_CONT_EN, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_PIXEL_SELECT, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_SOURCE_SELECT, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_PIPE_SELECT, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_MASK, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_ONE_SHOT_PENDING, VPOPP_CRC_CONTROL, post_fix), \
SFRB(VPOPP_CRC_RESULT_R, VPOPP_CRC_RESULT_RG, post_fix), \
SFRB(VPOPP_CRC_RESULT_G, VPOPP_CRC_RESULT_RG, post_fix), \
SFRB(VPOPP_CRC_RESULT_B, VPOPP_CRC_RESULT_BC, post_fix), \
SFRB(VPOPP_CRC_RESULT_C, VPOPP_CRC_RESULT_BC, post_fix), \
SFRB(FROD_EN, VPOPP_FROD_CONTROL, post_fix), \
SFRB(FROD_MEM_PWR_FORCE, VPOPP_FROD_MEM_PWR_CONTROL, post_fix), \
SFRB(FROD_MEM_PWR_DIS, VPOPP_FROD_MEM_PWR_CONTROL, post_fix), \
SFRB(FROD_MEM_PWR_STATE, VPOPP_FROD_MEM_PWR_CONTROL, post_fix), \
SFRB(FROD_MEM_DEFAULT_LOW_PWR_STATE, VPOPP_FROD_MEM_PWR_CONTROL, post_fix)
#define OPP_FIELD_LIST_VPE20(post_fix) \
OPP_FIELD_LIST_VPE20_COMMON(post_fix), \
SFRB(VPFMT_SPATIAL_DITHER_EN, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_SPATIAL_DITHER_MODE, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_SPATIAL_DITHER_DEPTH, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_FRAME_RANDOM_ENABLE, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_RGB_RANDOM_ENABLE, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_HIGHPASS_RANDOM_ENABLE, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_RAND_R_SEED, VPFMT_DITHER_RAND_R_SEED, post_fix), \
SFRB(VPFMT_RAND_G_SEED, VPFMT_DITHER_RAND_G_SEED, post_fix), \
SFRB(VPFMT_RAND_B_SEED, VPFMT_DITHER_RAND_B_SEED, post_fix), \
SFRB(VPOPP_PIPE_ALPHA_SEL, VPOPP_PIPE_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_ALPHA, VPOPP_PIPE_CONTROL, post_fix)
#define OPP_REG_VARIABLE_LIST_VPE20 \
OPP_REG_VARIABLE_LIST_VPE10_COMMON \
reg_id_val VPFMT_SUBSAMPLER_MEMORY_CONTROL; \
reg_id_val VPOPP_PIPE_OUTBG_EXT1; \
reg_id_val VPOPP_PIPE_OUTBG_EXT2; \
reg_id_val VPOPP_PIPE_OUTBG_COL1; \
reg_id_val VPOPP_PIPE_OUTBG_COL2; \
reg_id_val VPOPP_CRC_CONTROL; \
reg_id_val VPOPP_CRC_RESULT_RG; \
reg_id_val VPOPP_CRC_RESULT_BC; \
reg_id_val VPOPP_FROD_CONTROL; \
reg_id_val VPOPP_FROD_MEM_PWR_CONTROL;
#define OPP_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
OPP_FIELD_VARIABLE_LIST_VPE10_COMMON(type) \
type VPFMT_PIXEL_ENCODING; \
type VPFMT_SUBSAMPLE_HTAPS; \
type VPFMT_SUBSAMPLE_LEFT_EDGE; \
type VPFMT_SUBSAMPLE_RIGHT_EDGE; \
type VPFMT_SUBSAMPLE_VTAPS; \
type VPFMT_SUBSAMPLE_TOP_EDGE; \
type VPFMT_SUBSAMPLE_BOTTOM_EDGE; \
type VPFMT_SUBSAMPLER_MEM_PWR_FORCE; \
type VPFMT_SUBSAMPLER_MEM_PWR_DIS; \
type VPFMT_SUBSAMPLER_MEM_PWR_STATE; \
type VPFMT_DEFAULT_MEM_LOW_POWER_STATE; \
type OUTBG_EXT_TOP; \
type OUTBG_EXT_BOT; \
type OUTBG_EXT_LEFT; \
type OUTBG_EXT_RIGHT; \
type OUTBG_R_CR; \
type OUTBG_B_CB; \
type OUTBG_Y; \
type VPOPP_CRC_EN; \
type VPOPP_CRC_CONT_EN; \
type VPOPP_CRC_PIXEL_SELECT; \
type VPOPP_CRC_SOURCE_SELECT; \
type VPOPP_CRC_PIPE_SELECT; \
type VPOPP_CRC_MASK; \
type VPOPP_CRC_ONE_SHOT_PENDING; \
type VPOPP_CRC_RESULT_R; \
type VPOPP_CRC_RESULT_G; \
type VPOPP_CRC_RESULT_B; \
type VPOPP_CRC_RESULT_C; \
type FROD_EN; \
type FROD_MEM_PWR_FORCE; \
type FROD_MEM_PWR_DIS; \
type FROD_MEM_PWR_STATE; \
type FROD_MEM_DEFAULT_LOW_PWR_STATE;
#define OPP_FIELD_VARIABLE_LIST_VPE20(type) \
OPP_FIELD_VARIABLE_LIST_VPE20_COMMON(type) \
type VPFMT_SPATIAL_DITHER_EN; \
type VPFMT_SPATIAL_DITHER_MODE; \
type VPFMT_SPATIAL_DITHER_DEPTH; \
type VPFMT_FRAME_RANDOM_ENABLE; \
type VPFMT_RGB_RANDOM_ENABLE; \
type VPFMT_HIGHPASS_RANDOM_ENABLE; \
type VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \
type VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \
type VPFMT_RAND_R_SEED; \
type VPFMT_RAND_G_SEED; \
type VPFMT_RAND_B_SEED; \
type VPOPP_PIPE_ALPHA; \
type VPOPP_PIPE_ALPHA_SEL;
/* Variable list is the same as the one for VPE10 at the moment as it's the same set of registers.
* Note that adding VPE2 specific variables must be done at the bottom so that casting can work.
* See PROGRAM_ENTRY(),the order here matters, VPE1 subset must be in the same order in VPE2 list.
*/
struct vpe20_opp_registers {
OPP_REG_VARIABLE_LIST_VPE20
};
struct vpe20_opp_shift {
OPP_FIELD_VARIABLE_LIST_VPE20(uint8_t)
};
struct vpe20_opp_mask {
OPP_FIELD_VARIABLE_LIST_VPE20(uint32_t)
};
struct vpe20_opp {
struct opp base; // base class, must be the first field
struct vpe20_opp_registers *regs;
const struct vpe20_opp_shift *shift;
const struct vpe20_opp_mask *mask;
};
void vpe20_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp);
void vpe20_opp_build_fmt_subsample_params(struct opp *opp, enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_boundary_mode boundary_mode, struct fmt_subsampling_params *subsample_params);
void vpe20_opp_program_fmt_control(struct opp *opp, struct fmt_control_params *fmt_ctrl);
void vpe20_opp_program_bit_depth_reduction(
struct opp *opp, const struct bit_depth_reduction_params *params);
void vpe20_opp_set_bg(struct opp* opp, struct vpe_rect target_rect, struct vpe_rect dst_rect,
enum vpe_surface_pixel_format format, struct vpe_color bgcolor);
void vpe20_opp_program_pipe_crc(struct opp *opp, bool enable);
void vpe20_opp_program_frod(struct opp *opp, struct opp_frod_param *frod_param);
void vpe20_opp_get_fmt_extra_pixel(enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_extra_pixel_info *extra_pixel);
void vpe20_opp_program_pipe_control(struct opp *opp, const struct opp_pipe_control_params *params);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,110 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "vpe_types.h"
#include "plane_desc_writer.h"
#include "vpe_priv.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe20_plane_desc_header {
int32_t nps0;
int32_t npd0;
int32_t nps1;
int32_t npd1;
int32_t subop;
int32_t dcomp0;
int32_t dcomp1;
uint8_t hist0_dsets;
uint8_t hist1_dsets;
int32_t frod;
};
struct vpe20_plane_desc_src {
uint8_t tmz;
enum vpe_swizzle_mode_values swizzle;
uint32_t base_addr_lo;
uint32_t base_addr_hi;
uint16_t pitch;
uint16_t viewport_x;
uint16_t viewport_y;
uint16_t viewport_w;
uint16_t viewport_h;
uint8_t elem_size;
enum vpe_scan_direction scan;
bool comp_mode;
uint32_t meta_base_addr_lo;
uint32_t meta_base_addr_hi;
uint16_t meta_pitch;
uint8_t dcc_ind_blk;
uint32_t format;
};
struct vpe20_plane_desc_dst {
uint8_t tmz;
enum vpe_swizzle_mode_values swizzle;
uint32_t base_addr_lo;
uint32_t base_addr_hi;
uint16_t pitch;
uint16_t viewport_x;
uint16_t viewport_y;
uint16_t viewport_w;
uint16_t viewport_h;
uint8_t elem_size;
bool comp_mode;
};
void vpe20_construct_plane_desc_writer(struct plane_desc_writer *writer);
/** initialize the plane descriptor writer.
* Calls right before building any plane descriptor
*
* /param writer writer instance
* /param buf points to the current buf,
* /param plane_desc_header header
*/
void vpe20_plane_desc_writer_init(
struct plane_desc_writer *writer, struct vpe_buf *buf, void *p_header);
/** fill the value to the embedded buffer. */
void vpe20_plane_desc_writer_add_source(
struct plane_desc_writer *writer, void *p_source, bool is_plane0);
/** fill the value to the embedded buffer. */
void vpe20_plane_desc_writer_add_destination(
struct plane_desc_writer *writer, void *p_destination, bool is_plane0);
void vpe20_plane_desc_writer_add_meta(struct plane_desc_writer *writer, void *p_source);
/** fill the value to the embedded buffer for histogram collection. */
void vpe20_plane_desc_writer_add_hist_destination(struct plane_desc_writer *writer,
void *p_destination, uint32_t hist_idx, uint8_t hist_dsets_array[]);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,160 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "resource.h"
#ifdef __cplusplus
extern "C" {
#endif
enum vpe_status vpe20_construct_resource(struct vpe_priv *vpe_priv, struct resource *res);
void vpe20_update_recout_dst_viewport(struct scaler_data *data,
enum vpe_surface_pixel_format format, struct spl_opp_adjust *opp_adjust,
bool opp_background_gen);
void vpe20_update_src_viewport(struct scaler_data *data, enum vpe_surface_pixel_format format);
void vpe20_calculate_dst_viewport_and_active(
struct segment_ctx* segment_ctx, uint32_t max_seg_width);
bool vpe20_check_h_mirror_support(bool* input_mirror, bool* output_mirror);
void vpe20_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res);
bool vpe20_check_input_format(enum vpe_surface_pixel_format format);
bool vpe20_check_output_format(enum vpe_surface_pixel_format format);
bool vpe20_check_output_color_space(
enum vpe_surface_pixel_format format, const struct vpe_color_space *vcs);
void vpe20_set_lls_pref(struct vpe_priv *vpe_priv, struct spl_in *spl_input,
enum color_transfer_func tf, enum vpe_surface_pixel_format pixel_format);
enum vpe_status vpe20_check_bg_color_support(struct vpe_priv* vpe_priv, struct vpe_color* bg_color);
void vpe20_bg_color_convert(enum color_space output_cs, struct transfer_func *output_tf,
enum vpe_surface_pixel_format pixel_format, struct vpe_color *mpc_bg_color,
struct vpe_color *opp_bg_color, bool enable_3dlut);
int32_t vpe20_program_backend(struct vpe_priv* vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx, bool seg_only);
uint16_t vpe20_get_bg_stream_idx(struct vpe_priv *vpe_priv);
uint32_t vpe20_get_hw_surface_format(enum vpe_surface_pixel_format format);
enum vpe_status vpe20_calculate_segments(
struct vpe_priv *vpe_priv, const struct vpe_build_param *params);
int32_t vpe20_program_frontend(struct vpe_priv* vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx,
uint32_t cmd_input_idx, bool seg_only);
bool vpe20_get_dcc_compression_output_cap(
const struct vpe_dcc_surface_param *params, struct vpe_surface_dcc_cap *cap);
bool vpe20_get_dcc_compression_input_cap(
const struct vpe_dcc_surface_param *params, struct vpe_surface_dcc_cap *cap);
void vpe20_create_stream_ops_config(struct vpe_priv *vpe_priv, uint32_t pipe_idx,
uint32_t cmd_input_idx, struct stream_ctx *stream_ctx, struct vpe_cmd_info *cmd_info);
enum vpe_status vpe20_populate_cmd_info(struct vpe_priv *vpe_priv);
enum vpe_status vpe20_set_num_segments(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx,
struct scaler_data *scl_data, struct vpe_rect *src_rect, struct vpe_rect *dst_rect,
uint32_t *max_seg_width, uint32_t recout_width_alignment);
void vpe20_get_bufs_req(struct vpe_priv *vpe_priv, struct vpe_bufs_req *req);
enum vpe_status vpe20_check_mirror_rotation_support(const struct vpe_stream *stream);
enum vpe_status vpe20_update_blnd_gamma(struct vpe_priv *vpe_priv,
const struct vpe_build_param *param, const struct vpe_stream *stream,
struct transfer_func *blnd_tf);
enum vpe_status vpe20_update_output_gamma(struct vpe_priv *vpe_priv,
const struct vpe_build_param *param, struct transfer_func *output_tf, bool geometric_scaling);
struct cdc_fe *vpe20_cdc_fe_create(struct vpe_priv *vpe_priv, int inst);
struct cdc_be *vpe20_cdc_be_create(struct vpe_priv *vpe_priv, int inst);
struct dpp *vpe20_dpp_create(struct vpe_priv *vpe_priv, int inst);
struct opp *vpe20_opp_create(struct vpe_priv *vpe_priv, int inst);
struct mpc *vpe20_mpc_create(struct vpe_priv *vpe_priv, int inst);
void vpe20_fill_bg_cmd_scaler_data(
struct stream_ctx *stream_ctx, struct vpe_rect *dst_viewport, struct scaler_data *scaler_data);
void vpe20_create_bg_segments(
struct vpe_priv *vpe_priv, struct vpe_rect *gaps, uint16_t gaps_cnt, enum vpe_cmd_ops ops);
uint32_t vpe20_get_max_seg_width(struct output_ctx *output_ctx,
enum vpe_surface_pixel_format format, enum vpe_scan_direction scan);
enum vpe_status vpe20_fill_alpha_through_luma_cmd_info(
struct vpe_priv *vpe_priv, uint16_t alpha_stream_idx);
enum vpe_status vpe20_fill_non_performance_mode_cmd_info(
struct vpe_priv *vpe_priv, uint16_t stream_idx);
enum vpe_status vpe20_fill_performance_mode_cmd_info(
struct vpe_priv *vpe_priv, uint16_t stream_idx, uint16_t avail_pipe_count);
enum vpe_status vpe20_fill_blending_cmd_info(
struct vpe_priv *vpe_priv, uint16_t top_stream_idx, uint16_t bot_stream_idx);
uint32_t vpe20_get_num_pipes_available(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx);
void vpe20_set_frod_output_viewport(struct vpe_cmd_output *dst_output,
struct vpe_cmd_output *src_output, uint32_t viewport_divider,
enum vpe_surface_pixel_format format);
void vpe20_reset_pipes(struct vpe_priv *vpe_priv);
enum vpe_status vpe20_populate_frod_param(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
void vpe20_update_opp_adjust_and_boundary(struct stream_ctx *stream_ctx, uint16_t seg_idx,
bool dst_subsampled, const struct vpe_rect *src_rect, const struct vpe_rect *dst_rect,
struct output_ctx *output_ctx, struct spl_opp_adjust *opp_recout_adjust);
bool vpe20_set_dst_cmd_info_scaler(struct stream_ctx *dst_stream_ctx,
struct scaler_data *dst_scaler_data, struct vpe_rect recout, struct vpe_rect dst_viewport,
struct fmt_boundary_mode *boundary_mode, struct spl_opp_adjust *opp_adjust);
bool vpe20_validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
void vpe20_program_3dlut_fl(struct vpe_priv *vpe_priv, uint32_t cmd_idx);
const struct vpe_caps *vpe20_get_capability(void);
void vpe20_setup_check_funcs(struct vpe_check_support_funcs *funcs);
enum vpe_status vpe20_check_lut3d_compound(
const struct vpe_stream *stream, const struct vpe_build_param *param);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,46 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "vpe_desc_writer.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe20_construct_vpe_desc_writer(struct vpe_desc_writer *writer);
enum vpe_status vpe20_vpe_desc_writer_init(
struct vpe_desc_writer *writer, struct vpe_buf *buf, int cd);
void vpe20_vpe_desc_writer_add_plane_desc(
struct vpe_desc_writer *writer, uint64_t plane_desc_addr, uint8_t tmz);
void vpe20_vpe_desc_writer_add_config_desc(
struct vpe_desc_writer *writer, uint64_t config_desc_addr, bool reuse, uint8_t tmz);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,407 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "common.h"
#include "vpe_priv.h"
#include "vpe20_cdc_be.h"
#define CTX_BASE cdc_be
#define CTX vpe20_cdc_be
enum mux_sel {
MUX_SEL_ALPHA = 0,
MUX_SEL_Y_G = 1,
MUX_SEL_CB_B = 2,
MUX_SEL_CR_R = 3
};
static struct cdc_be_funcs cdc_func = {
.program_cdc_control = vpe20_cdc_program_control,
.program_global_sync = vpe20_cdc_program_global_sync,
.program_p2b_config = vpe20_cdc_program_p2b_config,
};
void vpe20_cdc_program_control(struct cdc_be *cdc_be, uint8_t enable_frod, uint32_t hist_dsets[])
{
PROGRAM_ENTRY();
REG_SET_3(VPCDC_CONTROL, 0, VPCDC_FROD_EN, enable_frod, VPCDC_HISTOGRAM0_EN, hist_dsets[0],
VPCDC_HISTOGRAM1_EN, hist_dsets[1]);
}
void vpe20_cdc_program_global_sync(
struct cdc_be *cdc_be, uint32_t vupdate_offset, uint32_t vupdate_width, uint32_t vready_offset)
{
PROGRAM_ENTRY();
REG_SET_3(VPCDC_BE0_GLOBAL_SYNC_CONFIG, 0, BE0_VUPDATE_OFFSET, vupdate_offset,
BE0_VUPDATE_WIDTH, vupdate_width, BE0_VREADY_OFFSET, vready_offset);
}
void vpe20_cdc_program_p2b_config(struct cdc_be *cdc_be, enum vpe_surface_pixel_format format,
enum vpe_swizzle_mode_values swizzle, const struct vpe_rect *viewport,
const struct vpe_rect *viewport_c)
{
uint32_t bar_sel0 = (uint32_t)MUX_SEL_CB_B;
uint32_t bar_sel1 = (uint32_t)MUX_SEL_Y_G;
uint32_t bar_sel2 = (uint32_t)MUX_SEL_CR_R;
uint32_t bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
uint32_t p2b_format_sel = 0;
uint32_t tile_mode = swizzle == VPE_SW_LINEAR ? 0 : 1;
uint32_t x_start_plane0 = 0;
uint32_t x_start_plane1 = 0;
PROGRAM_ENTRY();
if (viewport != NULL) {
x_start_plane0 = viewport->x;
}
if (viewport_c != NULL) {
x_start_plane1 = viewport_c->x;
}
// Conversion to the element coordinate of x_start_plane0 is only required for packed 422
// formats as only these formats' pixel sizes and element sizes differ among supported formats
if (vpe_is_yuv422(format) && vpe_is_yuv_packed(format)) {
x_start_plane0 = x_start_plane0 / 2;
}
switch (tile_mode) {
case VPE_SW_LINEAR:
tile_mode = 0;
x_start_plane0 = x_start_plane0 % (32 / (uint32_t)vpe_get_element_size_in_bytes(format, 0));
x_start_plane1 = x_start_plane1 % (32 / (uint32_t)vpe_get_element_size_in_bytes(format, 1));
// Pre-divided by 2
break;
default:
tile_mode = 1;
x_start_plane0 = x_start_plane0 % 4;
x_start_plane1 = x_start_plane1 % 4;
}
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
p2b_format_sel = 8;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
p2b_format_sel = 10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
p2b_format_sel = 11;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
p2b_format_sel = 20;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
p2b_format_sel = 21;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
p2b_format_sel = 26;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
p2b_format_sel = 27;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
p2b_format_sel = 28;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
p2b_format_sel = 29;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
p2b_format_sel = 24;
break;
// Planar YUV formats
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
p2b_format_sel = 0x40;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
p2b_format_sel = 0x41;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
p2b_format_sel = 0x42;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
p2b_format_sel = 0x43;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
p2b_format_sel = 0x44;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
p2b_format_sel = 0x45;
break;
// Packed YUV formats
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
p2b_format_sel = 0x48;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
p2b_format_sel = 0x49;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
p2b_format_sel = 0x4a;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
p2b_format_sel = 0x4b;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
p2b_format_sel = 0x4c;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
p2b_format_sel = 0x4d;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
p2b_format_sel = 0x4e;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
p2b_format_sel = 0x4f;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
p2b_format_sel = 0x50;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
p2b_format_sel = 0x51;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
p2b_format_sel = 0x52;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
p2b_format_sel = 0x53;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
p2b_format_sel = 0x70;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
p2b_format_sel = 0x71;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
p2b_format_sel = 0x76;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
p2b_format_sel = 0x77;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
p2b_format_sel = 0x78;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
p2b_format_sel = 0x7D;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
p2b_format_sel = 0x109;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
p2b_format_sel = 0x10D;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
p2b_format_sel = 0x115;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
p2b_format_sel = 0x118;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
p2b_format_sel = 0x12A;
break;
default:
VPE_ASSERT(0);
break;
}
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
bar_sel3 = (uint32_t)MUX_SEL_CB_B;
bar_sel2 = (uint32_t)MUX_SEL_CR_R;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
bar_sel3 = (uint32_t)MUX_SEL_CB_B;
bar_sel2 = (uint32_t)MUX_SEL_CR_R;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_Y_G;
bar_sel1 = (uint32_t)MUX_SEL_CB_B;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
bar_sel0 = (uint32_t)MUX_SEL_CR_R;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
bar_sel3 = (uint32_t)MUX_SEL_CB_B;
bar_sel2 = (uint32_t)MUX_SEL_Y_G;
bar_sel1 = (uint32_t)MUX_SEL_CR_R;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
bar_sel2 = (uint32_t)MUX_SEL_CR_R;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
bar_sel0 = (uint32_t)MUX_SEL_CB_B;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
bar_sel0 = (uint32_t)MUX_SEL_CR_R;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_Y_G;
bar_sel1 = (uint32_t)MUX_SEL_CB_B;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
bar_sel3 = (uint32_t)MUX_SEL_CR_R;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
bar_sel2 = (uint32_t)MUX_SEL_Y_G;
bar_sel1 = (uint32_t)MUX_SEL_CR_R;
bar_sel0 = (uint32_t)MUX_SEL_CB_B;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
bar_sel3 = (uint32_t)MUX_SEL_Y_G;
bar_sel2 = (uint32_t)MUX_SEL_CR_R;
bar_sel1 = (uint32_t)MUX_SEL_CB_B;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
bar_sel2 = (uint32_t)MUX_SEL_CR_R;
bar_sel1 = (uint32_t)MUX_SEL_Y_G;
bar_sel0 = (uint32_t)MUX_SEL_CB_B;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
bar_sel2 = (uint32_t)MUX_SEL_Y_G;
bar_sel1 = (uint32_t)MUX_SEL_CB_B;
bar_sel0 = (uint32_t)MUX_SEL_CR_R;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
bar_sel3 = (uint32_t)MUX_SEL_Y_G;
bar_sel2 = (uint32_t)MUX_SEL_CB_B;
bar_sel1 = (uint32_t)MUX_SEL_CR_R;
bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
break;
default:
break;
}
REG_SET_8(VPCDC_BE0_P2B_CONFIG, 0, VPCDC_BE0_P2B_XBAR_SEL0, bar_sel0, VPCDC_BE0_P2B_XBAR_SEL1,
bar_sel1, VPCDC_BE0_P2B_XBAR_SEL2, bar_sel2, VPCDC_BE0_P2B_XBAR_SEL3, bar_sel3,
VPCDC_BE0_P2B_FORMAT_SEL, p2b_format_sel, VPCDC_BE0_P2B_TILED, tile_mode,
VPCDC_BE0_P2B_X_START_PLANE0, x_start_plane0, VPCDC_BE0_P2B_X_START_PLANE1, x_start_plane1);
}
void vpe20_construct_cdc_be(struct vpe_priv *vpe_priv, struct cdc_be *cdc_be)
{
cdc_be->vpe_priv = vpe_priv;
cdc_be->funcs = &cdc_func;
}

View file

@ -0,0 +1,154 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "common.h"
#include "vpe_priv.h"
#include "vpe20_cdc_fe.h"
#include "vpe20_resource.h"
#define CTX_BASE cdc_fe
#define CTX vpe20_cdc_fe
enum mux_sel {
MUX_SEL_ALPHA = 0,
MUX_SEL_Y_G = 1,
MUX_SEL_CB_B = 2,
MUX_SEL_CR_R = 3
};
static struct cdc_fe_funcs cdc_fe_func = {
.program_surface_config = vpe20_cdc_program_surface_config,
.program_crossbar_config = vpe20_cdc_program_crossbar_config,
.program_3dlut_fl_config = vpe20_program_3dlut_fl_config,
.program_viewport = vpe20_cdc_program_viewport,
};
void vpe20_construct_cdc_fe(struct vpe_priv *vpe_priv, struct cdc_fe *cdc_fe)
{
cdc_fe->vpe_priv = vpe_priv;
cdc_fe->funcs = &cdc_fe_func;
}
void vpe20_cdc_program_surface_config(struct cdc_fe *cdc_fe, enum vpe_surface_pixel_format format,
enum vpe_rotation_angle rotation, bool horizontal_mirror, enum vpe_swizzle_mode_values swizzle)
{
uint32_t surface_linear = 0;
uint32_t rotation_angle = 0;
uint32_t surf_format = 8;
PROGRAM_ENTRY();
/* Program rotation angle and horz mirror - no mirror */
if (rotation == VPE_ROTATION_ANGLE_0)
rotation_angle = 0;
else if (rotation == VPE_ROTATION_ANGLE_90)
rotation_angle = 1;
else if (rotation == VPE_ROTATION_ANGLE_180)
rotation_angle = 2;
else if (rotation == VPE_ROTATION_ANGLE_270)
rotation_angle = 3;
if (swizzle == VPE_SW_LINEAR)
surface_linear = 1;
else
surface_linear = 0;
surf_format = vpe20_get_hw_surface_format(format);
REG_SET_4(VPCDC_FE0_SURFACE_CONFIG, 0, SURFACE_PIXEL_FORMAT_FE0, surf_format,
ROTATION_ANGLE_FE0, rotation_angle, H_MIRROR_EN_FE0, (unsigned)horizontal_mirror,
PIX_SURFACE_LINEAR_FE0, surface_linear);
}
void vpe20_cdc_program_crossbar_config(struct cdc_fe *cdc_fe, enum vpe_surface_pixel_format format)
{
uint32_t alpha_bar = (uint32_t)MUX_SEL_ALPHA;
uint32_t green_bar = (uint32_t)MUX_SEL_Y_G;
uint32_t red_bar = (uint32_t)MUX_SEL_CR_R;
uint32_t blue_bar = (uint32_t)MUX_SEL_CB_B;
PROGRAM_ENTRY();
if (format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM ||
format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888) {
red_bar = MUX_SEL_CB_B;
blue_bar = MUX_SEL_CR_R;
}
if (format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888) {
blue_bar = MUX_SEL_Y_G;
green_bar = MUX_SEL_CB_B;
}
REG_SET_4(VPCDC_FE0_CROSSBAR_CONFIG, 0, CROSSBAR_SRC_ALPHA_FE0, alpha_bar,
CROSSBAR_SRC_CR_R_FE0, red_bar, CROSSBAR_SRC_Y_G_FE0, green_bar, CROSSBAR_SRC_CB_B_FE0,
blue_bar);
}
void vpe20_cdc_program_viewport(
struct cdc_fe *cdc_fe, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c)
{
PROGRAM_ENTRY();
REG_SET_2(VPCDC_FE0_VIEWPORT_START_CONFIG, 0, VIEWPORT_X_START_FE0, viewport->x,
VIEWPORT_Y_START_FE0, viewport->y);
REG_SET_2(VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG, 0, VIEWPORT_WIDTH_FE0, viewport->width,
VIEWPORT_HEIGHT_FE0, viewport->height);
REG_SET_2(VPCDC_FE0_VIEWPORT_START_C_CONFIG, 0, VIEWPORT_X_START_C_FE0, viewport_c->x,
VIEWPORT_Y_START_C_FE0, viewport_c->y);
REG_SET_2(VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG, 0, VIEWPORT_WIDTH_C_FE0, viewport_c->width,
VIEWPORT_HEIGHT_C_FE0, viewport_c->height);
}
void vpe20_program_3dlut_fl_config(
struct cdc_fe *cdc_fe, enum lut_dimension lut_dimension, struct vpe_3dlut *lut_3d)
{
PROGRAM_ENTRY();
REG_SET_5(VPCDC_3DLUT_FL_CONFIG, 0,
VPCDC_3DLUT_FL_CROSSBAR_SRC_G, lut_3d->dma_params.crossbar_g,
VPCDC_3DLUT_FL_CROSSBAR_SRC_B, lut_3d->dma_params.crossbar_b,
VPCDC_3DLUT_FL_CROSSBAR_SRC_R, lut_3d->dma_params.crossbar_r,
VPCDC_3DLUT_FL_MODE, lut_3d->dma_params.layout,
VPCDC_3DLUT_FL_SIZE, lut_dimension == LUT_DIM_33 ? 1 : 0);
}

View file

@ -0,0 +1,742 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_assert.h"
#include "common.h"
#include "vpe_priv.h"
#include "vpe20_command.h"
#include "vpe20_plane_desc_writer.h"
#include "vpe10_cmd_builder.h"
#include "vpe20_cmd_builder.h"
#include "vpe20_resource.h"
#define LOG_INPUT_PLANE 1
#define LOG_OUTPUT_PLANE 0
static void get_np_and_subop(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info,
struct vpe20_plane_desc_header *header);
static enum VPE_PLANE_CFG_ELEMENT_SIZE vpe_get_element_size(
enum vpe_surface_pixel_format format, int plane_idx);
static void log_plane_desc_event(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info,
struct vpe20_plane_desc_header *header, struct vpe20_plane_desc_src *src,
struct vpe20_plane_desc_dst *dst, uint32_t cmd_idx, uint32_t io_idx, uint32_t plane_idx,
bool input_flag);
void vpe20_construct_cmd_builder(struct vpe_priv *vpe_priv, struct cmd_builder *builder)
{
builder->build_noops = vpe10_build_noops;
builder->build_vpe_cmd = vpe20_build_vpe_cmd;
builder->build_plane_descriptor = vpe20_build_plane_descriptor;
}
enum vpe_status vpe20_build_vpe_cmd(
struct vpe_priv *vpe_priv, struct vpe_build_bufs *cur_bufs, uint32_t cmd_idx)
{
struct cmd_builder *builder = &vpe_priv->resource.cmd_builder;
struct vpe_desc_writer *vpe_desc_writer = &vpe_priv->vpe_desc_writer;
struct vpe_buf *emb_buf = &cur_bufs->emb_buf;
struct output_ctx *output_ctx;
struct pipe_ctx *pipe_ctx = NULL;
uint32_t pipe_idx, config_idx;
struct vpe_vector *config_vector;
struct config_record *config;
struct vpe_cmd_info *cmd_info = vpe_vector_get(vpe_priv->vpe_cmd_vector, cmd_idx);
enum vpe_status status = VPE_STATUS_OK;
VPE_ASSERT(cmd_info);
if (!cmd_info)
return VPE_STATUS_ERROR;
vpe_desc_writer->init(vpe_desc_writer, &cur_bufs->cmd_buf, cmd_info->cd);
// plane descriptor
builder->build_plane_descriptor(vpe_priv, emb_buf, cmd_idx);
vpe_desc_writer->add_plane_desc(
vpe_desc_writer, vpe_priv->plane_desc_writer.base_gpu_va, (uint8_t)emb_buf->tmz);
// reclaim any pipe if the owner no longer presents
vpe_pipe_reclaim(vpe_priv, cmd_info);
config_writer_init(&vpe_priv->config_writer, emb_buf);
vpe_priv->resource.reset_pipes(vpe_priv);
/* 3D LUT FL programming */
vpe_priv->resource.program_fastload(vpe_priv, cmd_idx);
// frontend programming
for (pipe_idx = 0; pipe_idx < cmd_info->num_inputs; pipe_idx++) {
bool reuse;
struct stream_ctx *stream_ctx;
uint16_t stream_idx;
enum vpe_cmd_type cmd_type = VPE_CMD_TYPE_COUNT;
// keep using the same pipe whenever possible
// this would allow reuse of the previous register configs
stream_idx = cmd_info->inputs[pipe_idx].stream_idx;
pipe_ctx = &vpe_priv->pipe_ctx[pipe_idx];
reuse = (pipe_ctx->owner == stream_idx);
VPE_ASSERT(pipe_ctx->owner == PIPE_CTX_NO_OWNER || pipe_ctx->owner == stream_idx);
pipe_ctx->owner = stream_idx;
stream_ctx = &vpe_priv->stream_ctx[cmd_info->inputs[pipe_idx].stream_idx];
if (!reuse) {
vpe_priv->resource.program_frontend(
vpe_priv, pipe_ctx->pipe_idx, cmd_idx, pipe_idx, false);
} else {
if (vpe_priv->init.debug.disable_reuse_bit)
reuse = false;
// frame specific for same type of command
switch (cmd_info->ops) {
case VPE_CMD_OPS_BG:
cmd_type = VPE_CMD_TYPE_BG;
break;
case VPE_CMD_OPS_COMPOSITING:
cmd_type = VPE_CMD_TYPE_COMPOSITING;
break;
case VPE_CMD_OPS_BLENDING:
cmd_type = VPE_CMD_TYPE_BLENDING;
break;
case VPE_CMD_OPS_BG_VSCF_INPUT:
cmd_type = VPE_CMD_TYPE_BG_VSCF_INPUT;
break;
case VPE_CMD_OPS_BG_VSCF_OUTPUT:
cmd_type = VPE_CMD_TYPE_BG_VSCF_OUTPUT;
break;
case VPE_CMD_OPS_BG_VSCF_PIPE0:
cmd_type = VPE_CMD_TYPE_BG_VSCF_PIPE0;
break;
case VPE_CMD_OPS_BG_VSCF_PIPE1:
cmd_type = VPE_CMD_TYPE_BG_VSCF_PIPE1;
break;
case VPE_CMD_OPS_ALPHA_THROUGH_LUMA:
cmd_type = VPE_CMD_TYPE_ALPHA_THROUGH_LUMA;
break;
default:
VPE_ASSERT(0);
status = VPE_STATUS_ERROR;
break;
}
// follow the same order of config generation in "non-reuse" case
// stream sharing
config_vector = stream_ctx->configs[pipe_idx];
VPE_ASSERT(config_vector->num_elements);
for (config_idx = 0; config_idx < config_vector->num_elements; config_idx++) {
config = (struct config_record *)vpe_vector_get(config_vector, config_idx);
if (!config) {
status = VPE_STATUS_ERROR;
break;
}
vpe_desc_writer->add_config_desc(
vpe_desc_writer, config->config_base_addr, reuse, (uint8_t)emb_buf->tmz);
}
if (status != VPE_STATUS_OK)
break;
// stream-op sharing
config_vector = stream_ctx->stream_op_configs[pipe_idx][cmd_type];
for (config_idx = 0; config_idx < config_vector->num_elements; config_idx++) {
config = (struct config_record *)vpe_vector_get(config_vector, config_idx);
if (!config) {
status = VPE_STATUS_ERROR;
break;
}
vpe_desc_writer->add_config_desc(
vpe_desc_writer, config->config_base_addr, false, (uint8_t)emb_buf->tmz);
}
if (status != VPE_STATUS_OK)
break;
// command specific
vpe_priv->resource.program_frontend(
vpe_priv, pipe_ctx->pipe_idx, cmd_idx, pipe_idx, true);
}
}
// If config writer has been crashed due to buffer overflow
if ((status == VPE_STATUS_OK) && (vpe_priv->config_writer.status != VPE_STATUS_OK)) {
status = vpe_priv->config_writer.status;
}
// Back End Programming
if (status == VPE_STATUS_OK) {
// backend programming
output_ctx = &vpe_priv->output_ctx;
for (pipe_idx = 0; pipe_idx < cmd_info->num_outputs; pipe_idx++) {
config_vector = output_ctx->configs[pipe_idx];
bool seg_only;
if (!config_vector->num_elements) {
seg_only = false;
} else {
seg_only = true;
bool reuse = !vpe_priv->init.debug.disable_reuse_bit;
// re-use output register configs
for (config_idx = 0; config_idx < config_vector->num_elements; config_idx++) {
config = (struct config_record *)vpe_vector_get(
output_ctx->configs[pipe_idx], config_idx);
if (!config) {
status = VPE_STATUS_ERROR;
break;
}
vpe_desc_writer->add_config_desc(
vpe_desc_writer, config->config_base_addr, reuse, (uint8_t)emb_buf->tmz);
}
if (status != VPE_STATUS_OK)
break;
}
vpe_priv->resource.program_backend(vpe_priv, pipe_idx, cmd_idx, seg_only);
}
}
// If config writer has been crashed due to buffer overflow
if ((status == VPE_STATUS_OK) && (vpe_priv->config_writer.status != VPE_STATUS_OK)) {
status = vpe_priv->config_writer.status;
}
/* If writer crashed due to buffer overflow */
if ((status == VPE_STATUS_OK) && (vpe_desc_writer->status != VPE_STATUS_OK)) {
status = vpe_desc_writer->status;
}
if (status == VPE_STATUS_OK) {
vpe_desc_writer->complete(vpe_desc_writer);
}
return status;
}
enum vpe_status vpe20_build_plane_descriptor(
struct vpe_priv *vpe_priv, struct vpe_buf *buf, uint32_t cmd_idx)
{
struct stream_ctx *stream_ctx;
struct vpe_surface_info *surface_info;
int32_t stream_idx;
struct vpe_cmd_info *cmd_info;
PHYSICAL_ADDRESS_LOC *addrloc;
PHYSICAL_ADDRESS_LOC addrhist;
struct vpe20_plane_desc_src src;
struct vpe20_plane_desc_dst dst;
struct vpe20_plane_desc_header header = {0};
struct cmd_builder *builder = &vpe_priv->resource.cmd_builder;
struct plane_desc_writer *plane_desc_writer = &vpe_priv->plane_desc_writer;
uint32_t viewport_divider = FROD_DOWNSAMPLING_RATIO;
const uint32_t hist_size = 1024; // 256 bins, each 4 bytes
uint32_t hist_dsets = 0;
uint32_t line_offset;
uint32_t num_pipes = 1;
uint32_t performance_mode_offset;
cmd_info = vpe_vector_get(vpe_priv->vpe_cmd_vector, cmd_idx);
VPE_ASSERT(plane_desc_writer);
VPE_ASSERT(cmd_info);
if (!cmd_info)
return VPE_STATUS_ERROR;
VPE_ASSERT(cmd_info->num_inputs <= 2);
// obtains number of planes for each source/destination stream
for (int i = 0; i < cmd_info->num_inputs; i++) {
stream_idx = cmd_info->inputs[i].stream_idx;
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
src.scan = stream_ctx->scan;
surface_info = &stream_ctx->stream.surface_info;
if (i == 0)
header.dcomp0 = surface_info->dcc.enable ? 1 : 0;
else if (i == 1)
header.dcomp1 = surface_info->dcc.enable ? 1 : 0;
}
get_np_and_subop(vpe_priv, cmd_info, &header);
if (cmd_info->frod_param.enable_frod) {
header.frod = 1;
}
for (int i = 0; i < cmd_info->num_inputs; i++) {
stream_idx = cmd_info->inputs[i].stream_idx;
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
cmd_info->histo_dsets[i] = stream_ctx->stream.hist_params.hist_dsets;
if ((cmd_info->histo_dsets[i] > 0) && (cmd_info->histo_dsets[i] <= MAX_HISTO_SETS)) {
if (i == 0) {
header.hist0_dsets = (uint8_t)stream_ctx->stream.hist_params.hist_dsets;
}
else {
header.hist1_dsets = (uint8_t)stream_ctx->stream.hist_params.hist_dsets;
}
}
}
plane_desc_writer->init(&vpe_priv->plane_desc_writer, buf, &header);
for (int i = 0; i < cmd_info->num_inputs && i < MAX_INPUT_PIPE; i++) {
struct dscl_prog_data* dscl_data = &cmd_info->inputs[i].scaler_data.dscl_prog_data;
stream_idx = cmd_info->inputs[i].stream_idx;
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
surface_info = &stream_ctx->stream.surface_info;
src.tmz = surface_info->address.tmz_surface;
src.swizzle = surface_info->swizzle;
src.scan = stream_ctx->scan;
src.format = 0;
if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
addrloc = &surface_info->address.video_progressive.luma_addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
src.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
addrloc = &surface_info->address.video_progressive.luma_meta_addr;
src.meta_base_addr_lo = addrloc->u.low_part;
src.meta_base_addr_hi = (uint32_t)addrloc->u.high_part;
src.meta_pitch = (uint16_t)surface_info->dcc.src.meta_pitch;
src.dcc_ind_blk = surface_info->dcc.src.dcc_ind_blk_c;
src.comp_mode = surface_info->dcc.enable;
src.viewport_x = (uint16_t)dscl_data->viewport.x;
src.viewport_y = (uint16_t)dscl_data->viewport.y;
src.viewport_w = (uint16_t)dscl_data->viewport.width;
src.viewport_h = (uint16_t)dscl_data->viewport.height;
src.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 0));
if (vpe_is_yuv_packed(surface_info->format) && vpe_is_yuv422(surface_info->format)) {
if (dscl_data->viewport_c.x < (dscl_data->viewport.x / 2))
src.viewport_x = (uint16_t)dscl_data->viewport_c.x;
else
src.viewport_x = (uint16_t)dscl_data->viewport.x / 2;
if ((dscl_data->viewport_c.width * 2) > dscl_data->viewport.width)
src.viewport_w = (uint16_t)dscl_data->viewport_c.width;
else
src.viewport_w = (uint16_t)dscl_data->viewport.width / 2;
src.pitch = (uint16_t)surface_info->plane_size.surface_pitch / 2;
}
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_INPUT_PLANE);
if (vpe_is_dual_plane_format(surface_info->format)) {
addrloc = &surface_info->address.video_progressive.chroma_addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
src.pitch = (uint16_t)surface_info->plane_size.chroma_pitch;
src.viewport_x = (uint16_t)dscl_data->viewport_c.x;
src.viewport_y = (uint16_t)dscl_data->viewport_c.y;
src.viewport_w = (uint16_t)dscl_data->viewport_c.width;
src.viewport_h = (uint16_t)dscl_data->viewport_c.height;
src.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 1));
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, false);
// log vpe event - plane1
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 1, LOG_INPUT_PLANE);
}
} else if (surface_info->address.type == VPE_PLN_ADDR_TYPE_PLANAR) {
/* Planar Formats always packed into VPEC as:
PLane0 = Y_g
Plane1 = Cb_b
Plane2 = Cr_r
*/
// assuming all planes have the same rect/pitch properties
src.viewport_x = (uint16_t)cmd_info->inputs[i].scaler_data.dscl_prog_data.viewport.x;
src.viewport_y = (uint16_t)cmd_info->inputs[i].scaler_data.dscl_prog_data.viewport.y;
src.viewport_w =
(uint16_t)cmd_info->inputs[i].scaler_data.dscl_prog_data.viewport.width;
src.viewport_h =
(uint16_t)cmd_info->inputs[i].scaler_data.dscl_prog_data.viewport.height;
src.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 0));
src.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
// Y_g
addrloc = &surface_info->address.planar.y_g_addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_INPUT_PLANE);
// Cb_b
addrloc = &surface_info->address.planar.cb_b_addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, false);
// log vpe event - plane1
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 1, LOG_INPUT_PLANE);
// Cr_r
addrloc = &surface_info->address.planar.cr_r_addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, false);
// log vpe event - plane2
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 2, LOG_INPUT_PLANE);
} else {
addrloc = &surface_info->address.grph.addr;
src.base_addr_lo = addrloc->u.low_part;
src.base_addr_hi = (uint32_t)addrloc->u.high_part;
src.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
src.viewport_x = (uint16_t)dscl_data->viewport.x;
src.viewport_y = (uint16_t)dscl_data->viewport.y;
src.viewport_w = (uint16_t)dscl_data->viewport.width;
src.viewport_h = (uint16_t)dscl_data->viewport.height;
src.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 0));
plane_desc_writer->add_source(&vpe_priv->plane_desc_writer, &src, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_INPUT_PLANE);
}
}
if (plane_desc_writer->add_meta && (header.dcomp0 || header.dcomp1)) {
for (int i = 0; i < cmd_info->num_inputs && i < MAX_INPUT_PIPE; i++) {
if ((header.dcomp0 && i == 0) || (header.dcomp1 && i == 1)) {
stream_idx = cmd_info->inputs[i].stream_idx;
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
surface_info = &stream_ctx->stream.surface_info;
addrloc = &surface_info->address.video_progressive.luma_meta_addr;
src.meta_base_addr_lo = addrloc->u.low_part;
src.meta_base_addr_hi = (uint32_t)addrloc->u.high_part;
src.meta_pitch = (uint16_t)surface_info->dcc.src.meta_pitch;
src.dcc_ind_blk = surface_info->dcc.src.dcc_ind_blk_c;
src.comp_mode = surface_info->dcc.enable;
src.format = vpe20_get_hw_surface_format(surface_info->format);
plane_desc_writer->add_meta(&vpe_priv->plane_desc_writer, &src);
}
}
}
for (int i = 0; i < cmd_info->num_outputs && i < MAX_OUTPUT_PIPE; i++) {
surface_info = &vpe_priv->output_ctx.surface;
if ((cmd_info->frod_param.enable_frod) && (i > 0)) {
surface_info = &vpe_priv->output_ctx.frod_surface[i-1];
vpe_priv->resource.set_frod_output_viewport(&cmd_info->outputs[i],
&cmd_info->outputs[0], viewport_divider, surface_info->format);
viewport_divider *= FROD_DOWNSAMPLING_RATIO;
}
if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
addrloc = &surface_info->address.video_progressive.luma_addr;
dst.tmz = surface_info->address.tmz_surface;
dst.swizzle = surface_info->swizzle;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
dst.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
dst.viewport_x = (uint16_t)cmd_info->outputs[i].dst_viewport.x;
dst.viewport_y = (uint16_t)cmd_info->outputs[i].dst_viewport.y;
dst.viewport_w = (uint16_t)cmd_info->outputs[i].dst_viewport.width;
dst.viewport_h = (uint16_t)cmd_info->outputs[i].dst_viewport.height;
dst.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 0));
if (vpe_is_yuv_packed(surface_info->format) && vpe_is_yuv422(surface_info->format)) {
dst.viewport_x = (uint16_t)cmd_info->outputs[i].dst_viewport.x / 2;
dst.viewport_w = (uint16_t)cmd_info->outputs[i].dst_viewport.width / 2;
dst.pitch = (uint16_t)surface_info->plane_size.surface_pitch / 2;
}
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_OUTPUT_PLANE);
if (vpe_is_dual_plane_format(surface_info->format)) {
addrloc = &surface_info->address.video_progressive.chroma_addr;
dst.tmz = surface_info->address.tmz_surface;
dst.swizzle = surface_info->swizzle;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
dst.pitch = (uint16_t)surface_info->plane_size.chroma_pitch;
dst.viewport_x = (uint16_t)cmd_info->outputs[i].dst_viewport_c.x;
dst.viewport_y = (uint16_t)cmd_info->outputs[i].dst_viewport_c.y;
dst.viewport_w = (uint16_t)cmd_info->outputs[i].dst_viewport_c.width;
dst.viewport_h = (uint16_t)cmd_info->outputs[i].dst_viewport_c.height;
dst.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 1));
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, false);
// log vpe event - plane1
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 1, LOG_OUTPUT_PLANE);
}
} else if (surface_info->address.type == VPE_PLN_ADDR_TYPE_PLANAR) {
/* Planar Formats always packed as:
PLane0 = Y_g
Plane1 = Cb_b
Plane2 = Cr_r
*/
// assuming all planes have the same rect/pitch/tmz/swizzle properties
dst.tmz = surface_info->address.tmz_surface;
dst.swizzle = surface_info->swizzle;
dst.viewport_x = (uint16_t)cmd_info->outputs[i].dst_viewport_c.x;
dst.viewport_y = (uint16_t)cmd_info->outputs[i].dst_viewport_c.y;
dst.viewport_w = (uint16_t)cmd_info->outputs[i].dst_viewport_c.width;
dst.viewport_h = (uint16_t)cmd_info->outputs[i].dst_viewport_c.height;
dst.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 1));
dst.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
// Y_g
addrloc = &surface_info->address.planar.y_g_addr;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_OUTPUT_PLANE);
// Cb_b
addrloc = &surface_info->address.planar.cb_b_addr;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, false);
// log vpe event - plane1
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 1, LOG_OUTPUT_PLANE);
// Cr_r
addrloc = &surface_info->address.planar.cr_r_addr;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, false);
// log vpe event - plane2
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 2, LOG_OUTPUT_PLANE);
} else {
addrloc = &surface_info->address.grph.addr;
dst.tmz = surface_info->address.tmz_surface;
dst.swizzle = surface_info->swizzle;
dst.base_addr_lo = addrloc->u.low_part;
dst.base_addr_hi = (uint32_t)addrloc->u.high_part;
dst.pitch = (uint16_t)surface_info->plane_size.surface_pitch;
dst.viewport_x = (uint16_t)cmd_info->outputs[i].dst_viewport.x;
dst.viewport_y = (uint16_t)cmd_info->outputs[i].dst_viewport.y;
dst.viewport_w = (uint16_t)cmd_info->outputs[i].dst_viewport.width;
dst.viewport_h = (uint16_t)cmd_info->outputs[i].dst_viewport.height;
dst.elem_size = (uint8_t)(vpe_get_element_size(surface_info->format, 0));
plane_desc_writer->add_destination(&vpe_priv->plane_desc_writer, &dst, true);
// log vpe event - plane0
log_plane_desc_event(
vpe_priv, cmd_info, &header, &src, &dst, cmd_idx, i, 0, LOG_OUTPUT_PLANE);
}
}
for (int i = 0; i < cmd_info->num_inputs && i < MAX_INPUT_PIPE; i++) {
if ((header.hist0_dsets > 0) || (header.hist1_dsets > 0)) {
stream_idx = cmd_info->inputs[i].stream_idx;
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
num_pipes = vpe_priv->resource.get_num_pipes_available(vpe_priv, stream_ctx);
hist_dsets = header.hist0_dsets;
if(i > 0)
hist_dsets = header.hist1_dsets;
for (uint32_t histIndex = 0; histIndex < hist_dsets; histIndex++) {
surface_info = &stream_ctx->stream.hist_params.hist_collection_param[histIndex].hist_output;
if ((surface_info != NULL) &&
((cmd_info->cd * num_pipes) <
surface_info->plane_size.surface_size
.height)) { // writing to valid address within surface
performance_mode_offset = (num_pipes > 1) ? i : 0;
line_offset =
hist_size * ((cmd_info->cd * num_pipes) + performance_mode_offset);
addrhist.quad_part = surface_info->address.video_progressive.luma_addr.quad_part;
addrhist.quad_part += line_offset; // count down value on segments
dst.base_addr_lo = addrhist.u.low_part;
dst.base_addr_hi = (uint32_t)addrhist.u.high_part;
plane_desc_writer->add_histo(
&vpe_priv->plane_desc_writer, &dst, histIndex, NULL);
}
}
}
}
return vpe_priv->plane_desc_writer.status;
}
// Function logs plane descriptor information like number of planes, plane
// descriptor type, base address, pitch, viewport, swizzle, etc. to etw events
static void log_plane_desc_event(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info,
struct vpe20_plane_desc_header *header, struct vpe20_plane_desc_src *src,
struct vpe20_plane_desc_dst *dst, uint32_t cmd_idx, uint32_t io_idx, uint32_t plane_idx,
bool input_flag)
{
// check if event is for input or output plane
if (input_flag) {
vpe_event(VPE_EVENT_PLANE_DESC_INPUT, vpe_priv->pub.level,
vpe_priv->vpe_cmd_vector->num_elements, cmd_idx, cmd_info->num_inputs, io_idx,
(header->nps0 + 1), (header->nps1 + 1), 0, plane_idx, 0, 0, 0, src->base_addr_lo,
src->base_addr_hi, src->viewport_x, src->viewport_y, src->viewport_w, src->viewport_h,
src->swizzle, header->dcomp0, header->dcomp1);
} else {
vpe_event(VPE_EVENT_PLANE_DESC_OUTPUT, vpe_priv->pub.level,
vpe_priv->vpe_cmd_vector->num_elements, cmd_idx, cmd_info->num_outputs, io_idx,
(header->npd0 + 1), (header->npd1 + 1), plane_idx, dst->base_addr_lo, dst->base_addr_hi,
dst->viewport_x, dst->viewport_y, dst->viewport_w, dst->viewport_h, dst->swizzle);
}
}
static void get_np_and_subop(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info,
struct vpe20_plane_desc_header *header)
{
// Init second pipe src and destination plane count to 0
header->nps1 = 0;
header->npd1 = 0;
// Populate number of planes for source 0.
if (vpe_is_planar_format(
vpe_priv->stream_ctx[cmd_info->inputs[0].stream_idx].stream.surface_info.format))
header->nps0 = VPE_PLANE_CFG_THREE_PLANES;
else if (vpe_is_dual_plane_format(
vpe_priv->stream_ctx[cmd_info->inputs[0].stream_idx].stream.surface_info.format))
header->nps0 = VPE_PLANE_CFG_TWO_PLANES;
else
header->nps0 = VPE_PLANE_CFG_ONE_PLANE;
// Populate number of planes for source 1 if it exists.
if (cmd_info->num_inputs == 2) {
if (vpe_is_planar_format(
vpe_priv->stream_ctx[cmd_info->inputs[1].stream_idx].stream.surface_info.format))
header->nps1 = VPE_PLANE_CFG_THREE_PLANES;
else if (vpe_is_dual_plane_format(vpe_priv->stream_ctx[cmd_info->inputs[1].stream_idx]
.stream.surface_info.format))
header->nps1 = VPE_PLANE_CFG_TWO_PLANES;
else
header->nps1 = VPE_PLANE_CFG_ONE_PLANE;
}
// Populate number of planes for destination 0.
if (vpe_is_planar_format(vpe_priv->output_ctx.surface.format))
header->npd0 = VPE_PLANE_CFG_THREE_PLANES;
else if (vpe_is_dual_plane_format(vpe_priv->output_ctx.surface.format))
header->npd0 = VPE_PLANE_CFG_TWO_PLANES;
else
header->npd0 = VPE_PLANE_CFG_ONE_PLANE;
// Populate number of planes for destination 1 if it exists.
if (cmd_info->num_outputs == 2) {
if (vpe_is_planar_format(vpe_priv->output_ctx.surface.format))
header->npd1 = VPE_PLANE_CFG_THREE_PLANES;
else if (vpe_is_dual_plane_format(vpe_priv->output_ctx.surface.format))
header->npd1 = VPE_PLANE_CFG_TWO_PLANES;
else
header->npd1 = VPE_PLANE_CFG_ONE_PLANE;
}
/*
* Populate subop.
* Note: In the FROD case, num_outputs will be four but sub_op is expected to be x_TO_1
*/
if (cmd_info->num_inputs == 1)
header->subop = VPE_PLANE_CFG_SUBOP_1_TO_1;
else if (cmd_info->num_outputs == 2)
header->subop = VPE_PLANE_CFG_SUBOP_2_TO_2;
else
header->subop = VPE_PLANE_CFG_SUBOP_2_TO_1;
}
static enum VPE_PLANE_CFG_ELEMENT_SIZE vpe_get_element_size(
enum vpe_surface_pixel_format format, int plane_idx)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8: /* Monochrome 8BPE (R8)*/
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB: /* Planar RGB 8BPE */
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr: /* Planar YCbCr 8BPE */
return VPE_PLANE_CFG_ELEMENT_SIZE_8BPE;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: /* Semi-Planar 420 8BPE (NV12 + NV12) */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb: /* Semi-Planar 422 8BPE (YUY2)*/
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
if (plane_idx == 0)
return VPE_PLANE_CFG_ELEMENT_SIZE_8BPE;
else
return VPE_PLANE_CFG_ELEMENT_SIZE_16BPE;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: /* Semi-Planar 420 (P010 & P016) */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb: /* Semi-Planar 422 16BPE (Y210, Y216) */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
if (plane_idx == 0)
return VPE_PLANE_CFG_ELEMENT_SIZE_16BPE;
else
return VPE_PLANE_CFG_ELEMENT_SIZE_32BPE;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16: /* Monochrome 16BPE (R16)*/
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB: /* Planar RGB 16BPE */
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr: /* Planar YCbCr 16BPE */
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT: /* Planar FP16 */
return VPE_PLANE_CFG_ELEMENT_SIZE_16BPE;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb: /* Packed 422 16BPE (Y210, Y216) */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: /* RGB 16BPE */
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212: /* Packed YUV444 16BPE (Y416) */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
return VPE_PLANE_CFG_ELEMENT_SIZE_64BPE;
default:
break;
}
return VPE_PLANE_CFG_ELEMENT_SIZE_32BPE;
}

View file

@ -0,0 +1,29 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe20_config_writer.h"
void vpe20_config_writer_init(struct config_writer *writer)
{
writer->gpu_addr_alignment = 0x3F;
}

View file

@ -0,0 +1,351 @@
/* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include <string.h>
#include "common.h"
#include "vpe_priv.h"
#include "vpe10_dpp.h"
#include "vpe20_dpp.h"
#include "color.h"
#include "hw_shared.h"
#include "reg_helper.h"
#define CTX_BASE dpp
#define CTX vpe20_dpp
static struct dpp_funcs vpe20_dpp_funcs = {
.enable_clocks = vpe20_dpp_enable_clocks,
// cnv
.program_cnv = vpe20_dpp_program_cnv,
.program_pre_dgam = vpe10_dpp_cnv_program_pre_dgam,
.program_cnv_bias_scale = vpe10_dpp_program_cnv_bias_scale,
.build_keyer_params = vpe10_dpp_build_keyer_params,
.program_alpha_keyer = vpe20_dpp_cnv_program_alpha_keyer,
.program_crc = vpe10_dpp_program_crc,
// cm
.program_input_transfer_func = vpe20_dpp_program_input_transfer_func,
.program_gamut_remap = NULL,
.program_post_csc = vpe10_dpp_program_post_csc,
.set_hdr_multiplier = vpe10_dpp_set_hdr_multiplier,
.program_histogram = vpe20_dpp_program_histo,
// scaler
.get_optimal_number_of_taps = vpe10_dpp_get_optimal_number_of_taps,
.dscl_calc_lb_num_partitions = vpe10_dscl_calc_lb_num_partitions,
.set_segment_scaler = vpe20_dpp_set_segment_scaler,
.dscl_set_scaler_position = vpe20_dpp_dscl_set_scaler_position,
.set_frame_scaler = vpe20_dpp_set_frame_scaler,
.get_line_buffer_size = vpe10_get_line_buffer_size,
.validate_number_of_taps = vpe10_dpp_validate_number_of_taps,
.dscl_program_easf = vpe20_dscl_program_easf,
.dscl_disable_easf = vpe20_dscl_disable_easf,
.dscl_program_isharp = vpe20_dscl_program_isharp,
};
void vpe20_construct_dpp(struct vpe_priv *vpe_priv, struct dpp *dpp)
{
dpp->vpe_priv = vpe_priv;
dpp->funcs = &vpe20_dpp_funcs;
}
/* Not used as we do not have special 2bit LUT currently
* Can skip for optimize performance and use default val
*/
static void vpe20_dpp_program_alpha_2bit_lut(
struct dpp *dpp, struct cnv_alpha_2bit_lut *alpha_2bit_lut)
{
PROGRAM_ENTRY();
if (alpha_2bit_lut != NULL) {
REG_SET_2(VPCNVC_ALPHA_2BIT_LUT01, 0, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0,
ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
REG_SET_2(VPCNVC_ALPHA_2BIT_LUT23, 0, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2,
ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
} else { // restore to default
REG_SET_DEFAULT(VPCNVC_ALPHA_2BIT_LUT01);
REG_SET_DEFAULT(VPCNVC_ALPHA_2BIT_LUT23);
}
}
void vpe20_dpp_enable_clocks(struct dpp *dpp, bool enable)
{
PROGRAM_ENTRY();
REG_SET(VPDPP_CONTROL, REG_DEFAULT(VPDPP_CONTROL), VPECLK_G_GATE_DISABLE, enable);
}
void vpe20_dpp_cnv_program_alpha_keyer(struct dpp *dpp, const struct cnv_keyer_params *keyer_params)
{
PROGRAM_ENTRY();
if (keyer_params->keyer_en) {
uint8_t keyer_mode = 0;
switch (keyer_params->keyer_mode) {
case VPE_KEYER_MODE_FORCE_00:
keyer_mode = 0;
break;
case VPE_KEYER_MODE_FORCE_FF:
keyer_mode = 1;
break;
case VPE_KEYER_MODE_RANGE_FF:
keyer_mode = 2;
break;
case VPE_KEYER_MODE_RANGE_00:
default:
keyer_mode = 3;
break;
}
if (!keyer_params->is_color_key) { // Luma Keying
REG_SET_3(VPCNVC_COLOR_KEYER_CONTROL, 0, COLOR_KEYER_EN, 0, LUMA_KEYER_EN, 1,
COLOR_KEYER_MODE, keyer_mode);
REG_SET_2(VPCNVC_COLOR_KEYER_GREEN, 0, COLOR_KEYER_GREEN_LOW,
keyer_params->luma_keyer.lower_luma_bound, COLOR_KEYER_GREEN_HIGH,
keyer_params->luma_keyer.upper_luma_bound);
} else { // Color Keying
REG_SET_3(VPCNVC_COLOR_KEYER_CONTROL, 0, COLOR_KEYER_EN, 1, LUMA_KEYER_EN, 0,
COLOR_KEYER_MODE, keyer_mode);
REG_SET_2(VPCNVC_COLOR_KEYER_GREEN, 0, COLOR_KEYER_GREEN_LOW,
keyer_params->color_keyer.color_keyer_green_low, COLOR_KEYER_GREEN_HIGH,
keyer_params->color_keyer.color_keyer_green_high);
REG_SET_2(VPCNVC_COLOR_KEYER_BLUE, 0, COLOR_KEYER_BLUE_LOW,
keyer_params->color_keyer.color_keyer_blue_low, COLOR_KEYER_BLUE_HIGH,
keyer_params->color_keyer.color_keyer_blue_high);
REG_SET_2(VPCNVC_COLOR_KEYER_RED, 0, COLOR_KEYER_RED_LOW,
keyer_params->color_keyer.color_keyer_red_low, COLOR_KEYER_RED_HIGH,
keyer_params->color_keyer.color_keyer_red_high);
REG_SET_2(VPCNVC_COLOR_KEYER_ALPHA, 0, COLOR_KEYER_ALPHA_LOW,
keyer_params->color_keyer.color_keyer_alpha_low, COLOR_KEYER_ALPHA_HIGH,
keyer_params->color_keyer.color_keyer_alpha_high);
}
} else {
REG_SET_DEFAULT(VPCNVC_COLOR_KEYER_CONTROL);
}
}
void vpe20_dpp_program_cnv(
struct dpp *dpp, enum vpe_surface_pixel_format format, enum vpe_expansion_mode mode)
{
uint32_t alpha_en = 1;
uint32_t pixel_format = 0;
uint32_t hw_expansion_mode = 0;
PROGRAM_ENTRY();
switch (mode) {
case VPE_EXPANSION_MODE_DYNAMIC:
hw_expansion_mode = 0;
break;
case VPE_EXPANSION_MODE_ZERO:
hw_expansion_mode = 1;
break;
default:
VPE_ASSERT(0);
break;
}
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
pixel_format = 8;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
pixel_format = 8;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
pixel_format = 9;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
pixel_format = 9;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
pixel_format = 10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
pixel_format = 11;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
pixel_format = 64;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
pixel_format = 65;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
pixel_format = 66;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
pixel_format = 67;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /* use crossbar */
pixel_format = 20;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
pixel_format = 21;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
pixel_format = 21;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
pixel_format = 24;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* FP16 */
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: /* used crossbar */
pixel_format = 24;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F: /* FP16 */
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F: /* used crossbar */
pixel_format = 25;
break;
// VPE 2.0 Supported Modes
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888: /* used crossbar */
pixel_format = 12;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
pixel_format = 13;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
pixel_format = 13;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
pixel_format = 14;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
pixel_format = 15;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
pixel_format = 26;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
pixel_format = 27;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
pixel_format = 28;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
pixel_format = 29;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
pixel_format = 42;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212: /* Y416 */
pixel_format = 44; /* 12 bit slice MSB */
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
pixel_format = 46;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb: /* P016 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb: /* P216 */
pixel_format = 68;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr: /* P016 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr: /* P216 */
pixel_format = 69;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
pixel_format = 70;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb: /* YUY12 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr: /* used crossbar */
pixel_format = 72;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY: /* YUY12 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY: /* used crossbar */
pixel_format = 74;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb: /* Y210 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr: /* used crossbar */
pixel_format = 76;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY: /* Y210 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY: /* used crossbar */
pixel_format = 78;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr: /* used crossbar */
pixel_format = 80;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY: /* Y216 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY: // use crossbar
pixel_format = 82;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: /* Y410 */
pixel_format = 114;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102: /* Y410 */
pixel_format = 115;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8: // use crossbar
pixel_format = 120;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16: // use crossbar
pixel_format = 125;
alpha_en = 0;
break;
default:
break;
}
REG_SET(VPCNVC_SURFACE_PIXEL_FORMAT, 0, VPCNVC_SURFACE_PIXEL_FORMAT, pixel_format);
REG_SET_7(VPCNVC_FORMAT_CONTROL, REG_DEFAULT(VPCNVC_FORMAT_CONTROL), FORMAT_EXPANSION_MODE,
hw_expansion_mode, FORMAT_CNV16, 0, FORMAT_CONTROL__ALPHA_EN, alpha_en, VPCNVC_BYPASS,
dpp->vpe_priv->init.debug.vpcnvc_bypass, VPCNVC_BYPASS_MSB_ALIGN, 0, CLAMP_POSITIVE, 0,
CLAMP_POSITIVE_C, 0);
}

View file

@ -0,0 +1,173 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_priv.h"
#include "reg_helper.h"
#include "vpe10/inc/vpe10_cm_common.h"
#include "vpe20/inc/vpe20_cm_common.h"
#include "vpe10_dpp.h"
#include "vpe20_dpp.h"
#include "custom_float.h"
#include "fixed31_32.h"
#include "conversion.h"
#define CTX vpe20_dpp
#define CTX_BASE dpp
enum histo_xbar {
select_R_Cr_Max = 0,
select_G_Luma,
select_B_Cb_Min
};
#define HIST_SRC1_SET_MAX 1
#define HIST_SRC2_SET_LUMA 1
#define HIST_SRC3_SET_MIN 1
void vpe20_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf)
{
struct pwl_params *params = NULL;
PROGRAM_ENTRY();
struct stream_ctx *stream_ctx = &vpe_priv->stream_ctx[vpe_priv->fe_cb_ctx.stream_idx];
bool bypass;
VPE_ASSERT(input_tf);
// There should always have input_tf
// Only accept either DISTRIBUTED_POINTS or BYPASS
// No support for PREDEFINED case
VPE_ASSERT(input_tf->type == TF_TYPE_DISTRIBUTED_POINTS || input_tf->type == TF_TYPE_BYPASS);
// VPE always do NL scaling using gamcor, thus skipping dgam (default bypass)
// dpp->funcs->program_pre_dgam(dpp, tf);
if (input_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
vpe10_cm_helper_translate_curve_to_degamma_hw_format(input_tf, &dpp->degamma_params, input_tf->dirty[dpp->inst]);
params = &dpp->degamma_params;
}
bypass = ((input_tf->type == TF_TYPE_BYPASS) || dpp->vpe_priv->init.debug.bypass_gamcor);
CONFIG_CACHE(input_tf, stream_ctx, vpe_priv->init.debug.disable_lut_caching, bypass,
vpe10_dpp_program_gamcor_lut(dpp, params), dpp->inst);
}
static bool calculate_hist_rgb_luma_coeffs(uint32_t * rgbcoff_reg, enum color_space cs)
{
struct fixed31_32 rgb_luma_coeffs[3] = { 0 };
struct custom_float_format const vpefmt = { 12, 6, false };
switch (cs) {
case COLOR_SPACE_RGB601:
case COLOR_SPACE_RGB601_LIMITED:
rgb_luma_coeffs[0] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[1].regval[4]);
rgb_luma_coeffs[1] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[1].regval[5]);
rgb_luma_coeffs[2] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[1].regval[6]);
break;
case COLOR_SPACE_SRGB:
rgb_luma_coeffs[0] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[2].regval[4]);
rgb_luma_coeffs[1] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[2].regval[5]);
rgb_luma_coeffs[2] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[2].regval[6]);
break;
case COLOR_SPACE_2020_RGB_FULLRANGE:
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
rgb_luma_coeffs[0] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[3].regval[4]);
rgb_luma_coeffs[1] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[3].regval[5]);
rgb_luma_coeffs[2] = vpe_convfix31_32(vpe_output_full_csc_matrix_fixed[3].regval[6]);
break;
default:
return false;
break;
}
if( (vpe_convert_to_custom_float_format(rgb_luma_coeffs[0], &vpefmt, &rgbcoff_reg[0])) &&
(vpe_convert_to_custom_float_format(rgb_luma_coeffs[1], &vpefmt, &rgbcoff_reg[1])) &&
(vpe_convert_to_custom_float_format(rgb_luma_coeffs[2], &vpefmt, &rgbcoff_reg[2]))) {
return true;
}
return false;
}
void vpe20_dpp_program_histo(struct dpp* dpp, struct vpe_histogram_param* hist_param, enum color_space cs)
{
uint32_t hist_chan_mask = 0;
uint32_t hist_chan_en = 0;
uint32_t reg_xbar[hist_max_channel] = { 0 };
uint32_t reg_src_sel[hist_max_channel] = { 0 };
uint32_t rgbcoff_reg[3] = { 0 };
const uint32_t tapPoint = 0;
enum hist_channels hist_crt_channel;
bool rgb_luma_transform = false;
PROGRAM_ENTRY();
for (hist_crt_channel = hist_channel1; hist_crt_channel < hist_max_channel; hist_crt_channel++) {
if (hist_param->hist_collection_param[hist_crt_channel].hist_types != VPE_HISTOGRAM_NONE) {
hist_chan_mask |= 1 << hist_crt_channel;
hist_chan_en++;
switch (hist_param->hist_collection_param[hist_crt_channel].hist_types) {
case VPE_HISTOGRAM_MAX_RGB_YCbCr:
reg_xbar[hist_crt_channel] = select_R_Cr_Max;
reg_src_sel[hist_channel1] = HIST_SRC1_SET_MAX;
break;
case VPE_HISTOGRAM_G_Y:
reg_xbar[hist_crt_channel] = select_G_Luma;
break;
case VPE_HISTOGRAM_RGB_TRANSFORMED_Y:
reg_xbar[hist_crt_channel] = select_G_Luma;
reg_src_sel[hist_channel2] = HIST_SRC2_SET_LUMA;
rgb_luma_transform = true;
break;
case VPE_HISTOGRAM_B_CB:
reg_xbar[hist_crt_channel] = select_B_Cb_Min;
break;
case VPE_HISTOGRAM_MIN_RGB_YCbCr:
reg_xbar[hist_crt_channel] = select_B_Cb_Min;
reg_src_sel[hist_channel3] = HIST_SRC3_SET_MIN;
break;
default:
break;
}
}
}
if ( (rgb_luma_transform) &&
(calculate_hist_rgb_luma_coeffs(rgbcoff_reg, cs))) {
REG_SET(VPCM_HIST_COEFA_SRC2, REG_DEFAULT(VPCM_HIST_COEFA_SRC2), VPCM_HIST_COEFA_SRC2, rgbcoff_reg[0]);
REG_SET(VPCM_HIST_COEFB_SRC2, REG_DEFAULT(VPCM_HIST_COEFB_SRC2), VPCM_HIST_COEFB_SRC2, rgbcoff_reg[1]);
REG_SET(VPCM_HIST_COEFC_SRC2, REG_DEFAULT(VPCM_HIST_COEFC_SRC2), VPCM_HIST_COEFC_SRC2, rgbcoff_reg[2]);
}
REG_SET_10(VPCM_HIST_CNTL, REG_DEFAULT(VPCM_HIST_CNTL),
VPCM_HIST_SEL, (uint32_t)tapPoint,
VPCM_HIST_CH_EN, (uint32_t)hist_chan_en,
VPCM_HIST_CH1_XBAR, (uint32_t)reg_xbar[hist_channel1],
VPCM_HIST_CH2_XBAR, (uint32_t)reg_xbar[hist_channel2],
VPCM_HIST_CH3_XBAR, (uint32_t)reg_xbar[hist_channel3],
VPCM_HIST_FORMAT, (uint32_t)hist_param->hist_format,
VPCM_HIST_SRC1_SEL, (uint32_t)reg_src_sel[hist_channel1],
VPCM_HIST_SRC2_SEL, (uint32_t)reg_src_sel[hist_channel2],
VPCM_HIST_SRC3_SEL, (uint32_t)reg_src_sel[hist_channel3],
VPCM_HIST_READ_CHANNEL_MASK, (uint32_t)hist_chan_mask);
}

View file

@ -0,0 +1,566 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_priv.h"
#include "vpe20_dpp.h"
#define CTX vpe20_dpp
#define CTX_BASE dpp
#define LB_MAX_PARTITION 12
#define NUM_PHASES 64
#define NUM_ISHARP_LEVELS 32
enum vpe10_dscl_mode_sel vpe20_dpp_dscl_get_dscl_mode(const struct scaler_data *data)
{
return (enum vpe10_dscl_mode_sel)data->dscl_prog_data.dscl_mode;
}
/**
* vpe20_dscl_program_easf - Program EASF
*
* This is the primary function to program EASF
*
*/
void vpe20_dscl_program_easf(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
REG_SET_2(VPDSCL_SC_MODE, REG_DEFAULT(VPDSCL_SC_MODE),
SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode,
SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
/* DSCL_EASF_V_MODE */
REG_SET_3(VPDSCL_EASF_V_MODE, REG_DEFAULT(VPDSCL_EASF_V_MODE),
SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en,
SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor,
SCL_EASF_V_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_v_ring);
REG_SET_6(VPDSCL_EASF_V_BF_CNTL, REG_DEFAULT(VPDSCL_EASF_V_BF_CNTL),
SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en,
SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode,
SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode,
SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain,
SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain,
SCL_EASF_V_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_v_bf2_roc_gain);
REG_SET_2(VPDSCL_EASF_V_RINGEST_3TAP_CNTL1, REG_DEFAULT(VPDSCL_EASF_V_RINGEST_3TAP_CNTL1),
SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt,
SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt_max);
REG_SET_2(VPDSCL_EASF_V_RINGEST_3TAP_CNTL2, REG_DEFAULT(VPDSCL_EASF_V_RINGEST_3TAP_CNTL2),
SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope,
SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt1_slope);
REG_SET_2(VPDSCL_EASF_V_RINGEST_3TAP_CNTL3, REG_DEFAULT(VPDSCL_EASF_V_RINGEST_3TAP_CNTL3),
SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope,
SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_offset);
REG_SET_2(VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE, REG_DEFAULT(VPDSCL_EASF_V_RINGEST_EVENTAP_REDUCE),
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1,
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg2);
REG_SET_2(VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN, REG_DEFAULT(VPDSCL_EASF_V_RINGEST_EVENTAP_GAIN),
SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1,
SCL_EASF_V_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain2);
REG_SET_4(VPDSCL_EASF_V_BF_FINAL_MAX_MIN, REG_DEFAULT(VPDSCL_EASF_V_BF_FINAL_MAX_MIN),
SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa,
SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb,
SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina,
SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG0, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG0),
SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0,
SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0,
SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG1, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG1),
SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1,
SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1,
SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG2, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG2),
SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2,
SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2,
SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG3, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG3),
SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3,
SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3,
SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG4, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG4),
SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4,
SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4,
SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG5, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG5),
SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5,
SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5,
SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
REG_SET_3(VPDSCL_EASF_V_BF1_PWL_SEG6, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG6),
SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6,
SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6,
SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
REG_SET_2(VPDSCL_EASF_V_BF1_PWL_SEG7, REG_DEFAULT(VPDSCL_EASF_V_BF1_PWL_SEG7),
SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7,
SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
REG_SET_3(VPDSCL_EASF_V_BF3_PWL_SEG0, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG0),
SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0,
SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0,
SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
REG_SET_3(VPDSCL_EASF_V_BF3_PWL_SEG1, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG1),
SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1,
SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1,
SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
REG_SET_3(VPDSCL_EASF_V_BF3_PWL_SEG2, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG2),
SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2,
SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2,
SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
REG_SET_3(VPDSCL_EASF_V_BF3_PWL_SEG3, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG3),
SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3,
SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3,
SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
REG_SET_3(VPDSCL_EASF_V_BF3_PWL_SEG4, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG4),
SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4,
SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4,
SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
REG_SET_2(VPDSCL_EASF_V_BF3_PWL_SEG5, REG_DEFAULT(VPDSCL_EASF_V_BF3_PWL_SEG5),
SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5,
SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
/* DSCL_EASF_H_MODE */
REG_SET_3(VPDSCL_EASF_H_MODE, REG_DEFAULT(VPDSCL_EASF_H_MODE),
SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en,
SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor,
SCL_EASF_H_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_h_ring);
REG_SET_6(VPDSCL_EASF_H_BF_CNTL, REG_DEFAULT(VPDSCL_EASF_H_BF_CNTL),
SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en,
SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode,
SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode,
SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain,
SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain,
SCL_EASF_H_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_h_bf2_roc_gain);
REG_SET_2(VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE, REG_DEFAULT(VPDSCL_EASF_H_RINGEST_EVENTAP_REDUCE),
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1,
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg2);
REG_SET_2(VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN, REG_DEFAULT(VPDSCL_EASF_H_RINGEST_EVENTAP_GAIN),
SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1,
SCL_EASF_H_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain2);
REG_SET_4(VPDSCL_EASF_H_BF_FINAL_MAX_MIN, REG_DEFAULT(VPDSCL_EASF_H_BF_FINAL_MAX_MIN),
SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa,
SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb,
SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina,
SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG0, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG0),
SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0,
SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0,
SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG1, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG1),
SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1,
SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1,
SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG2, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG2),
SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2,
SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2,
SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG3, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG3),
SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3,
SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3,
SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG4, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG4),
SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4,
SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4,
SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG5, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG5),
SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5,
SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5,
SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
REG_SET_3(VPDSCL_EASF_H_BF1_PWL_SEG6, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG6),
SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6,
SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6,
SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
REG_SET_2(VPDSCL_EASF_H_BF1_PWL_SEG7, REG_DEFAULT(VPDSCL_EASF_H_BF1_PWL_SEG7),
SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7,
SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
REG_SET_3(VPDSCL_EASF_H_BF3_PWL_SEG0, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG0),
SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0,
SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0,
SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
REG_SET_3(VPDSCL_EASF_H_BF3_PWL_SEG1, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG1),
SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1,
SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1,
SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
REG_SET_3(VPDSCL_EASF_H_BF3_PWL_SEG2, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG2),
SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2,
SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2,
SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
REG_SET_3(VPDSCL_EASF_H_BF3_PWL_SEG3, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG3),
SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3,
SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3,
SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
REG_SET_3(VPDSCL_EASF_H_BF3_PWL_SEG4, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG4),
SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4,
SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4,
SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
REG_SET_2(VPDSCL_EASF_H_BF3_PWL_SEG5, REG_DEFAULT(VPDSCL_EASF_H_BF3_PWL_SEG5),
SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5,
SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
/* DSCL_EASF_SC_MATRIX_C0C1, DSCL_EASF_SC_MATRIX_C2C3 */
REG_SET_2(VPDSCL_SC_MATRIX_C0C1, REG_DEFAULT(VPDSCL_SC_MATRIX_C0C1),
SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0,
SCL_SC_MATRIX_C1, scl_data->dscl_prog_data.easf_matrix_c1);
REG_SET_2(VPDSCL_SC_MATRIX_C2C3, REG_DEFAULT(VPDSCL_SC_MATRIX_C2C3),
SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2,
SCL_SC_MATRIX_C3, scl_data->dscl_prog_data.easf_matrix_c3);
}
/**
* vpe20_dscl_disable_easf - Disable EASF when no scaling (1:1)
*
*/
void vpe20_dscl_disable_easf(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
/* DSCL_EASF_V_MODE */
REG_SET(VPDSCL_EASF_V_MODE, REG_DEFAULT(VPDSCL_EASF_V_MODE),
SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
/* DSCL_EASF_H_MODE */
REG_SET(VPDSCL_EASF_H_MODE, REG_DEFAULT(VPDSCL_EASF_H_MODE),
SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
/*Set the color conversion matrices even when the scaler is not active*/
REG_SET_2(VPDSCL_SC_MODE, REG_DEFAULT(VPDSCL_SC_MODE), SCL_SC_MATRIX_MODE,
scl_data->dscl_prog_data.easf_matrix_mode, SCL_SC_LTONL_EN,
scl_data->dscl_prog_data.easf_ltonl_en);
REG_SET_2(VPDSCL_SC_MATRIX_C0C1, REG_DEFAULT(VPDSCL_SC_MATRIX_C0C1), SCL_SC_MATRIX_C0,
scl_data->dscl_prog_data.easf_matrix_c0, SCL_SC_MATRIX_C1,
scl_data->dscl_prog_data.easf_matrix_c1);
REG_SET_2(VPDSCL_SC_MATRIX_C2C3, REG_DEFAULT(VPDSCL_SC_MATRIX_C2C3), SCL_SC_MATRIX_C2,
scl_data->dscl_prog_data.easf_matrix_c2, SCL_SC_MATRIX_C3,
scl_data->dscl_prog_data.easf_matrix_c3);
}
static void dpp2_dscl_set_isharp_filter(struct dpp *dpp, const uint32_t *filter)
{
PROGRAM_ENTRY();
uint32_t level = 0;
uint32_t filter_data;
if (filter == NULL)
return;
REG_SET_3(VPISHARP_DELTA_LUT_MEM_PWR_CTRL, REG_DEFAULT(VPISHARP_DELTA_LUT_MEM_PWR_CTRL),
ISHARP_DELTA_LUT_MEM_PWR_FORCE, 0, ISHARP_DELTA_LUT_MEM_PWR_DIS, 1,
ISHARP_DELTA_LUT_MEM_PWR_STATE, 0);
REG_SET(VPISHARP_DELTA_CTRL, REG_DEFAULT(VPISHARP_DELTA_CTRL),
ISHARP_DELTA_LUT_HOST_SELECT, 0);
REG_SET(VPISHARP_DELTA_INDEX, 0,
ISHARP_DELTA_INDEX, level);
for (level = 0; level < NUM_ISHARP_LEVELS; level++) {
filter_data = filter[level];
REG_SET(VPISHARP_DELTA_DATA, REG_DEFAULT(VPISHARP_DELTA_DATA),
ISHARP_DELTA_DATA, filter_data);
}
REG_SET_3(VPISHARP_DELTA_LUT_MEM_PWR_CTRL, REG_DEFAULT(VPISHARP_DELTA_LUT_MEM_PWR_CTRL),
ISHARP_DELTA_LUT_MEM_PWR_FORCE, 0, ISHARP_DELTA_LUT_MEM_PWR_DIS, 0,
ISHARP_DELTA_LUT_MEM_PWR_STATE, 0);
}
/**
* vpe20_dscl_program_isharp - Program isharp
*
* This is the primary function to program isharp
*
*/
void vpe20_dscl_program_isharp(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
/* ISHARP_MDOE */
REG_SET_6(VPISHARP_MODE, REG_DEFAULT(VPISHARP_MODE),
ISHARP_EN, scl_data->dscl_prog_data.isharp_en,
ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable,
ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode,
ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode,
ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode,
ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
if (scl_data->dscl_prog_data.isharp_en == 0)
return;
/* ISHARP_NOISEDET_THRESHOLD */
REG_SET_2(VPISHARP_NOISEDET_THRESHOLD, REG_DEFAULT(VPISHARP_NOISEDET_THRESHOLD),
ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold,
ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
/* ISHARP_NOISE_GAIN_PWL */
REG_SET_3(VPISHARP_NOISE_GAIN_PWL, REG_DEFAULT(VPISHARP_NOISE_GAIN_PWL),
ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in,
ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in,
ISHARP_NOISEDET_PWL_SLOPE, scl_data->dscl_prog_data.isharp_noise_det.pwl_slope);
/* ISHARP_LBA: IN_SEG, BASE_SEG, SLOPE_SEG */
REG_SET_3(VPISHARP_LBA_PWL_SEG0, REG_DEFAULT(VPISHARP_LBA_PWL_SEG0),
ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0],
ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0],
ISHARP_LBA_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.isharp_lba.slope_seg[0]);
REG_SET_3(VPISHARP_LBA_PWL_SEG1, REG_DEFAULT(VPISHARP_LBA_PWL_SEG1),
ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1],
ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1],
ISHARP_LBA_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.isharp_lba.slope_seg[1]);
REG_SET_3(VPISHARP_LBA_PWL_SEG2, REG_DEFAULT(VPISHARP_LBA_PWL_SEG2),
ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2],
ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2],
ISHARP_LBA_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.isharp_lba.slope_seg[2]);
REG_SET_3(VPISHARP_LBA_PWL_SEG3, REG_DEFAULT(VPISHARP_LBA_PWL_SEG3),
ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3],
ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3],
ISHARP_LBA_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.isharp_lba.slope_seg[3]);
REG_SET_3(VPISHARP_LBA_PWL_SEG4, REG_DEFAULT(VPISHARP_LBA_PWL_SEG4),
ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4],
ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4],
ISHARP_LBA_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.isharp_lba.slope_seg[4]);
REG_SET_2(VPISHARP_LBA_PWL_SEG5, REG_DEFAULT(VPISHARP_LBA_PWL_SEG5),
ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5],
ISHARP_LBA_PWL_BASE_SEG5, scl_data->dscl_prog_data.isharp_lba.base_seg[5]);
/* ISHARP_DELTA_LUT */
dpp2_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
/* ISHARP_NLDELTA_SOFT_CLIP */
REG_SET_6(VPISHARP_NLDELTA_SOFT_CLIP, REG_DEFAULT(VPISHARP_NLDELTA_SOFT_CLIP),
ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p,
ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p,
ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p,
ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n,
ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n,
ISHARP_NLDELTA_SCLIP_SLOPE_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_n);
/* Blur and Scale Coefficients - SCL_COEF_RAM_TAP_SELECT */
if (scl_data->dscl_prog_data.isharp_en) {
if (scl_data->dscl_prog_data.filter_blur_scale_v) {
vpe10_dpp_dscl_set_scaler_filter(dpp, scl_data->taps.v_taps,
SCL_COEF_VERTICAL_BLUR_SCALE, scl_data->dscl_prog_data.filter_blur_scale_v);
}
if (scl_data->dscl_prog_data.filter_blur_scale_h) {
vpe10_dpp_dscl_set_scaler_filter(dpp, scl_data->taps.h_taps,
SCL_COEF_HORIZONTAL_BLUR_SCALE, scl_data->dscl_prog_data.filter_blur_scale_h);
}
}
}
static void dpp2_set_recout(struct dpp *dpp, const struct vpe_rect *recout)
{
PROGRAM_ENTRY();
REG_SET_2(VPDSCL_RECOUT_START, 0, RECOUT_START_X, recout->x, RECOUT_START_Y, recout->y);
REG_SET_2(VPDSCL_RECOUT_SIZE, 0, RECOUT_WIDTH, recout->width, RECOUT_HEIGHT, recout->height);
}
static void dpp2_power_on_dscl(struct dpp *dpp, bool power_on)
{
PROGRAM_ENTRY();
if (dpp->vpe_priv->init.debug.enable_mem_low_power.bits.dscl) {
if (power_on) {
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 0,
LUT_MEM_PWR_FORCE, 0);
// introduce a delay by dummy set
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 0,
LUT_MEM_PWR_FORCE, 0);
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 0,
LUT_MEM_PWR_FORCE, 0);
} else {
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 0,
LUT_MEM_PWR_FORCE, 3);
}
} else {
if (power_on) {
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 1,
LUT_MEM_PWR_FORCE, 0);
} else {
REG_SET_2(VPDSCL_MEM_PWR_CTRL, REG_DEFAULT(VPDSCL_MEM_PWR_CTRL), LUT_MEM_PWR_DIS, 0,
LUT_MEM_PWR_FORCE, 0);
}
}
}
static void dpp2_dscl_set_scale_ratio(struct dpp *dpp, const struct scaler_data *data)
{
PROGRAM_ENTRY();
REG_SET(VPDSCL_HORZ_FILTER_SCALE_RATIO, 0,
SCL_H_SCALE_RATIO, data->dscl_prog_data.ratios.h_scale_ratio);
REG_SET(VPDSCL_VERT_FILTER_SCALE_RATIO, 0,
SCL_V_SCALE_RATIO, data->dscl_prog_data.ratios.v_scale_ratio);
REG_SET(VPDSCL_HORZ_FILTER_SCALE_RATIO_C, 0,
SCL_H_SCALE_RATIO_C, data->dscl_prog_data.ratios.h_scale_ratio_c);
REG_SET(VPDSCL_VERT_FILTER_SCALE_RATIO_C, 0,
SCL_V_SCALE_RATIO_C, data->dscl_prog_data.ratios.v_scale_ratio_c);
}
void vpe20_dpp_dscl_set_scaler_position(struct dpp *dpp, const struct scaler_data *data)
{
PROGRAM_ENTRY();
REG_SET_2(VPDSCL_HORZ_FILTER_INIT, 0,
SCL_H_INIT_FRAC, data->dscl_prog_data.init.h_filter_init_frac,
SCL_H_INIT_INT, data->dscl_prog_data.init.h_filter_init_int);
REG_SET_2(VPDSCL_HORZ_FILTER_INIT_C, 0,
SCL_H_INIT_FRAC_C, data->dscl_prog_data.init.h_filter_init_frac_c,
SCL_H_INIT_INT_C, data->dscl_prog_data.init.h_filter_init_int_c);
REG_SET_2(VPDSCL_VERT_FILTER_INIT, 0,
SCL_V_INIT_FRAC, data->dscl_prog_data.init.v_filter_init_frac,
SCL_V_INIT_INT, data->dscl_prog_data.init.v_filter_init_int);
REG_SET_2(VPDSCL_VERT_FILTER_INIT_BOT, 0,
SCL_V_INIT_FRAC_BOT, data->dscl_prog_data.init.v_filter_init_bot_frac,
SCL_V_INIT_INT_BOT, data->dscl_prog_data.init.v_filter_init_bot_int);
REG_SET_2(VPDSCL_VERT_FILTER_INIT_C, 0,
SCL_V_INIT_FRAC_C, data->dscl_prog_data.init.v_filter_init_frac_c,
SCL_V_INIT_INT_C, data->dscl_prog_data.init.v_filter_init_int_c);
REG_SET_2(VPDSCL_VERT_FILTER_INIT_BOT_C, 0,
SCL_V_INIT_FRAC_BOT_C, data->dscl_prog_data.init.v_filter_init_bot_frac_c,
SCL_V_INIT_INT_BOT_C, data->dscl_prog_data.init.v_filter_init_bot_int_c);
}
static void dpp2_dscl_set_scl_filter_and_dscl_mode(struct dpp *dpp,
const struct scaler_data *scl_data, enum vpe10_dscl_mode_sel scl_mode, bool chroma_coef_mode)
{
PROGRAM_ENTRY();
const uint16_t *filter_h = NULL;
const uint16_t *filter_v = NULL;
const uint16_t *filter_h_c = NULL;
const uint16_t *filter_v_c = NULL;
if (scl_mode != DSCL_MODE_DSCL_BYPASS) {
filter_h = scl_data->dscl_prog_data.filter_h;
filter_v = scl_data->dscl_prog_data.filter_v;
filter_h_c = scl_data->dscl_prog_data.filter_h_c;
filter_v_c = scl_data->dscl_prog_data.filter_v_c;
if (filter_h) {
vpe10_dpp_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps, SCL_COEF_LUMA_HORZ_FILTER, filter_h);
}
if (filter_v) {
vpe10_dpp_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps, SCL_COEF_LUMA_VERT_FILTER, filter_v);
}
if (chroma_coef_mode) {
if (filter_h_c) {
vpe10_dpp_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps_c, SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
}
if (filter_v_c) {
vpe10_dpp_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps_c, SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
}
}
}
REG_SET_2(VPDSCL_MODE, 0, VPDSCL_MODE, scl_mode, SCL_CHROMA_COEF_MODE, chroma_coef_mode);
}
static void dpp2_dscl_set_taps(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
/* HTaps/VTaps */
REG_SET_4(VPDSCL_TAP_CONTROL, REG_DEFAULT(VPDSCL_TAP_CONTROL), SCL_V_NUM_TAPS,
scl_data->taps.v_taps - 1, SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, SCL_V_NUM_TAPS_C,
scl_data->taps.v_taps_c - 1, SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
}
void vpe20_dpp_set_segment_scaler(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
const struct vpe_rect *rect =
(struct vpe_rect *)&scl_data->dscl_prog_data.recout;
enum scl_mode dscl_mode =
(enum scl_mode) scl_data->dscl_prog_data.dscl_mode;
uint32_t mpc_width = scl_data->dscl_prog_data.mpc_size.width;
uint32_t mpc_height = scl_data->dscl_prog_data.mpc_size.height;
if (dpp->vpe_priv->init.debug.opp_background_gen) {
// We set the x and y of the DPP rect out to 0, since OPP does the top and left extend
struct vpe_rect new_rect;
new_rect.y = 0;
new_rect.width = rect->width;
new_rect.x = 0;
new_rect.height = rect->height;
dpp2_set_recout(dpp, &new_rect);
} else {
dpp2_set_recout(dpp, rect);
}
REG_SET_2(VPMPC_SIZE, REG_DEFAULT(VPMPC_SIZE), VPMPC_WIDTH, mpc_width,
VPMPC_HEIGHT, mpc_height);
if (dscl_mode == SCL_MODE_DSCL_BYPASS)
return;
dpp->funcs->dscl_set_scaler_position(dpp, scl_data);
}
/**
* vpe20_dpp_set_frame_scaler - program scaler from dscl_prog_data
*
* This is the primary function to program scaler and line buffer in manual
* scaling mode. To execute the required operations for manual scale, we need
* to disable AutoCal first.
*/
void vpe20_dpp_set_frame_scaler(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
enum vpe10_dscl_mode_sel dscl_mode = vpe20_dpp_dscl_get_dscl_mode(scl_data);
bool ycbcr = vpe10_dpp_dscl_is_ycbcr(scl_data->format);
if (dscl_mode == DSCL_MODE_DSCL_BYPASS) {
dpp2_dscl_set_scl_filter_and_dscl_mode(dpp, scl_data, dscl_mode, ycbcr);
vpe20_dscl_program_isharp(dpp, scl_data);
vpe20_dscl_disable_easf(dpp, scl_data);
vpe10_dpp_power_on_dscl(dpp, false);
} else {
vpe10_dpp_power_on_dscl(dpp, true);
vpe10_dpp_dscl_set_lb(dpp, &scl_data->lb_params, LB_MEMORY_CONFIG_0);
dpp2_dscl_set_scale_ratio(dpp, scl_data);
dpp2_dscl_set_taps(dpp, scl_data);
dpp2_dscl_set_scl_filter_and_dscl_mode(dpp, scl_data, dscl_mode, ycbcr);
vpe20_dscl_program_isharp(dpp, scl_data);
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS ||
(!scl_data->dscl_prog_data.easf_v_en && !scl_data->dscl_prog_data.easf_h_en)) {
vpe20_dscl_disable_easf(dpp, scl_data);
} else {
vpe20_dscl_program_easf(dpp, scl_data);
}
}
}

View file

@ -0,0 +1,853 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_assert.h"
#include "common.h"
#include "vpe_priv.h"
#include "vpe10_mpc.h"
#include "vpe20_mpc.h"
#include "reg_helper.h"
#include "vpe10_cm_common.h"
#include "custom_fp16.h"
#include "conversion.h"
#define CTX_BASE mpc
#define CTX vpe20_mpc
#define MPC_RMCM_3DLUT_FL_ENABLE (0x0)
#define MPC_RMCM_3DLUT_FL_DISABLE (0xf)
static struct mpc_funcs mpc_funcs = {
.program_mpcc_mux = vpe20_mpc_program_mpcc_mux,
.program_mpcc_blending = vpe20_mpc_program_mpcc_blending,
.program_mpc_bypass_bg_color = vpe10_mpc_program_mpc_bypass_bg_color,
.power_on_ogam_lut = vpe10_mpc_power_on_ogam_lut,
.set_output_csc = vpe10_mpc_set_output_csc,
.set_ocsc_default = vpe10_mpc_set_ocsc_default,
.program_output_csc = vpe10_program_output_csc,
.set_output_gamma = vpe10_mpc_set_output_gamma,
.set_gamut_remap = NULL,
.set_gamut_remap2 = vpe20_mpc_set_gamut_remap2,
.power_on_1dlut_shaper_3dlut = vpe20_mpc_power_on_1dlut_shaper_3dlut,
.program_shaper = vpe20_mpc_program_shaper,
.program_3dlut = vpe20_mpc_program_3dlut,
.program_3dlut_indirect = vpe20_mpc_program_3dlut_indirect,
.program_1dlut = vpe10_mpc_program_1dlut,
.program_cm_location = vpe10_mpc_program_cm_location,
.set_denorm = vpe10_mpc_set_denorm,
.set_out_float_en = vpe10_mpc_set_out_float_en,
.program_mpc_out = vpe10_mpc_program_mpc_out,
.set_output_transfer_func = vpe10_mpc_set_output_transfer_func,
.set_mpc_shaper_3dlut = vpe20_mpc_set_mpc_shaper_3dlut,
.shaper_bypass = vpe20_mpc_shaper_bypass,
.set_blend_lut = vpe10_mpc_set_blend_lut,
.program_movable_cm = vpe20_mpc_program_movable_cm,
.program_crc = vpe10_mpc_program_crc,
.attach_3dlut_to_mpc_inst = vpe20_attach_3dlut_to_mpc_inst,
.update_3dlut_fl_bias_scale = vpe20_update_3dlut_fl_bias_scale,
.program_mpc_3dlut_fl_config = vpe20_mpc_program_3dlut_fl_config,
.program_mpc_3dlut_fl = vpe20_mpc_program_3dlut_fl,
};
void vpe20_construct_mpc(struct vpe_priv *vpe_priv, struct mpc *mpc)
{
mpc->vpe_priv = vpe_priv;
mpc->funcs = &mpc_funcs;
}
void vpe20_mpc_program_mpcc_mux(struct mpc *mpc, enum mpc_mpccid mpcc_idx,
enum mpc_mux_topsel topsel, enum mpc_mux_botsel botsel, enum mpc_mux_outmux outmux,
enum mpc_mux_oppid oppid)
{
PROGRAM_ENTRY();
/* program mux and MPCC_MODE */
REG_SET(VPMPCC_TOP_SEL, 0, VPMPCC_TOP_SEL, topsel);
REG_SET(VPMPCC_BOT_SEL, 0, VPMPCC_BOT_SEL, botsel);
REG_SET(VPMPC_OUT_MUX, 0, VPMPC_OUT_MUX, outmux);
REG_SET(VPMPCC_VPOPP_ID, 0, VPMPCC_VPOPP_ID, oppid);
}
void vpe20_mpc_program_mpcc_blending(
struct mpc *mpc, enum mpc_mpccid mpcc_idx, struct mpcc_blnd_cfg *blnd_cfg)
{
PROGRAM_ENTRY();
float r_cr, g_y, b_cb;
int bg_r_cr, bg_g_y, bg_b_cb;
struct vpe_custom_float_format2 fmt;
REG_SET_5(VPMPCC_CONTROL, REG_DEFAULT(VPMPCC_CONTROL), VPMPCC_MODE, blnd_cfg->blend_mode,
VPMPCC_ALPHA_BLND_MODE, blnd_cfg->alpha_mode, VPMPCC_ALPHA_MULTIPLIED_MODE,
blnd_cfg->pre_multiplied_alpha, VPMPCC_BLND_ACTIVE_OVERLAP_ONLY, blnd_cfg->overlap_only,
VPMPCC_BOT_GAIN_MODE, blnd_cfg->bottom_gain_mode);
REG_SET_2(VPMPCC_CONTROL2, REG_DEFAULT(VPMPCC_CONTROL2), VPMPCC_GLOBAL_ALPHA,
blnd_cfg->global_alpha, VPMPCC_GLOBAL_GAIN, blnd_cfg->global_gain);
REG_SET(VPMPCC_TOP_GAIN, 0, VPMPCC_TOP_GAIN, blnd_cfg->top_gain);
REG_SET(VPMPCC_BOT_GAIN_INSIDE, 0, VPMPCC_BOT_GAIN_INSIDE, blnd_cfg->bottom_inside_gain);
REG_SET(VPMPCC_BOT_GAIN_OUTSIDE, 0, VPMPCC_BOT_GAIN_OUTSIDE, blnd_cfg->bottom_outside_gain);
if (blnd_cfg->bg_color.is_ycbcr) {
r_cr = blnd_cfg->bg_color.ycbcra.cr;
g_y = blnd_cfg->bg_color.ycbcra.y;
b_cb = blnd_cfg->bg_color.ycbcra.cb;
} else {
r_cr = blnd_cfg->bg_color.rgba.r;
g_y = blnd_cfg->bg_color.rgba.g;
b_cb = blnd_cfg->bg_color.rgba.b;
}
fmt.flags.Uint = 0;
fmt.flags.bits.sign = 1;
fmt.mantissaBits = 12;
fmt.exponentaBits = 6;
vpe_convert_to_custom_float_generic((double)r_cr, &fmt, &bg_r_cr);
vpe_convert_to_custom_float_generic((double)g_y, &fmt, &bg_g_y);
vpe_convert_to_custom_float_generic((double)b_cb, &fmt, &bg_b_cb);
// Set background color
REG_SET(VPMPCC_BG_R_CR, 0, VPMPCC_BG_R_CR, bg_r_cr);
REG_SET(VPMPCC_BG_G_Y, 0, VPMPCC_BG_G_Y, bg_g_y);
REG_SET(VPMPCC_BG_B_CB, 0, VPMPCC_BG_B_CB, bg_b_cb);
}
void vpe20_mpc_power_on_1dlut_shaper_3dlut(struct mpc *mpc, bool power_on)
{
PROGRAM_ENTRY();
// int max_retries = 10;
// VPE1 has a single register.
// VPE2 is split into two that reflects that shaper+3DLUT are in RMCM while (post)1D is stil in MCM
REG_SET(VPMPCC_MCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPCC_MCM_MEM_PWR_CTRL),
VPMPCC_MCM_1DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
REG_SET_2(VPMPC_RMCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPC_RMCM_MEM_PWR_CTRL),
VPMPC_RMCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1 : 0,
VPMPC_RMCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
/* wait for memory to fully power up */
if (power_on && vpe_priv->init.debug.enable_mem_low_power.bits.mpc) {
// REG_WAIT(VPMPCC_MCM_MEM_PWR_CTRL, VPMPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
// Use two REG_SET instead of wait for State
REG_SET(VPMPCC_MCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPCC_MCM_MEM_PWR_CTRL),
VPMPCC_MCM_1DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
REG_SET_2(VPMPC_RMCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPC_RMCM_MEM_PWR_CTRL),
VPMPC_RMCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1 : 0,
VPMPC_RMCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
REG_SET(VPMPCC_MCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPCC_MCM_MEM_PWR_CTRL),
VPMPCC_MCM_1DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
REG_SET_2(VPMPC_RMCM_MEM_PWR_CTRL, REG_DEFAULT(VPMPC_RMCM_MEM_PWR_CTRL),
VPMPC_RMCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1 : 0,
VPMPC_RMCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1 : 0);
// REG_WAIT(VPMPCC_MCM_MEM_PWR_CTRL, VPMPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
}
}
static void vpe20_mpc_configure_shaper_lut(struct mpc *mpc, bool is_ram_a)
{
PROGRAM_ENTRY();
REG_SET(VPMPC_RMCM_SHAPER_LUT_INDEX, 0, VPMPC_RMCM_SHAPER_LUT_INDEX, 0);
REG_SET_2(VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK, 0, VPMPC_RMCM_SHAPER_LUT_WRITE_EN_MASK, 7,
VPMPC_RMCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0 : 1);
}
static void vpe20_mpc_program_shaper_luta_settings(struct mpc *mpc, const struct pwl_params *params)
{
PROGRAM_ENTRY();
const struct gamma_curve *curve;
uint16_t packet_data_size;
uint16_t i;
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_START_CNTL_B, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_B,
params->corner_points[0].blue.custom_float_x,
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_START_CNTL_G, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_B,
params->corner_points[0].green.custom_float_x,
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_START_CNTL_R, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_B,
params->corner_points[0].red.custom_float_x,
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_END_CNTL_B, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_B,
params->corner_points[1].blue.custom_float_x, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_B,
params->corner_points[1].blue.custom_float_y);
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_END_CNTL_G, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_B,
params->corner_points[1].green.custom_float_x, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_B,
params->corner_points[1].green.custom_float_y);
REG_SET_2(VPMPC_RMCM_SHAPER_RAMA_END_CNTL_R, 0, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_B,
params->corner_points[1].red.custom_float_x, VPMPC_RMCM_SHAPER_RAMA_EXP_REGION_END_BASE_B,
params->corner_points[1].red.custom_float_y);
// Optimized by single VPEP config packet with auto inc
packet_data_size = (uint16_t)(REG_OFFSET(VPMPC_RMCM_SHAPER_RAMA_REGION_32_33) -
REG_OFFSET(VPMPC_RMCM_SHAPER_RAMA_REGION_0_1) + 1);
VPE_ASSERT(packet_data_size <= MAX_CONFIG_PACKET_DATA_SIZE_DWORD);
packet.bits.INC = 1; // set the auto increase bit
packet.bits.VPEP_CONFIG_DATA_SIZE =
packet_data_size - 1; // number of "continuous" dwords, 1-based
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(VPMPC_RMCM_SHAPER_RAMA_REGION_0_1);
config_writer_fill_direct_config_packet_header(config_writer, &packet);
curve = params->arr_curve_points;
for (i = 0; i < packet_data_size; i++) {
config_writer_fill(config_writer,
REG_FIELD_VALUE(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset) |
REG_FIELD_VALUE(
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num) |
REG_FIELD_VALUE(VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset) |
REG_FIELD_VALUE(
VPMPC_RMCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num));
curve += 2;
}
}
static void vpe20_mpc_program_shaper_lut(
struct mpc *mpc, const struct pwl_result_data *rgb, uint32_t num)
{
PROGRAM_ENTRY();
uint32_t i, red, green, blue;
uint32_t red_delta, green_delta, blue_delta;
uint32_t red_value, green_value, blue_value;
uint16_t packet_data_size;
// Optimized by single VPEP config packet for same address with multiple write
packet_data_size = (uint16_t)num * 3; // num writes for each channel in (R, G, B)
VPE_ASSERT(packet_data_size <= MAX_CONFIG_PACKET_DATA_SIZE_DWORD);
packet.bits.INC = 0;
packet.bits.VPEP_CONFIG_DATA_SIZE =
packet_data_size - 1; // number of "continuous" dwords, 1-based
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(VPMPC_RMCM_SHAPER_LUT_DATA);
config_writer_fill_direct_config_packet_header(config_writer, &packet);
for (i = 0; i < num; i++) {
red = rgb[i].red_reg;
green = rgb[i].green_reg;
blue = rgb[i].blue_reg;
red_delta = rgb[i].delta_red_reg;
green_delta = rgb[i].delta_green_reg;
blue_delta = rgb[i].delta_blue_reg;
red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_SHAPER_LUT_DATA, red_value));
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_SHAPER_LUT_DATA, green_value));
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_SHAPER_LUT_DATA, blue_value));
}
}
void vpe20_mpc_shaper_bypass(struct mpc *mpc, bool bypass)
{
PROGRAM_ENTRY();
REG_SET(VPMPC_RMCM_SHAPER_CONTROL, 0, VPMPC_RMCM_SHAPER_LUT_MODE, bypass ? 0 : 1);
}
bool vpe20_mpc_program_shaper(struct mpc *mpc, const struct pwl_params *params)
{
PROGRAM_ENTRY();
if (params == NULL) {
REG_SET(VPMPC_RMCM_SHAPER_CONTROL, 0, VPMPC_RMCM_SHAPER_LUT_MODE, 0);
return false;
}
vpe20_mpc_configure_shaper_lut(mpc, true); // Always use LUT_RAM_A
// if (vpe_priv->init.debug.enable_mem_low_power.bits.mpc)
// should always turn it on
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, true);
vpe20_mpc_program_shaper_luta_settings(mpc, params);
vpe20_mpc_program_shaper_lut(mpc, params->rgb_resulted, params->hw_points_num);
REG_SET(VPMPC_RMCM_SHAPER_CONTROL, 0, VPMPC_RMCM_SHAPER_LUT_MODE, 1);
REG_SET_DEFAULT(VPMPC_RMCM_SHAPER_SCALE_R);
REG_SET_DEFAULT(VPMPC_RMCM_SHAPER_SCALE_G_B);
//? Should we check debug option before turn off shaper? -- should be yes
if (vpe_priv->init.debug.enable_mem_low_power.bits.mpc)
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, false);
return true;
}
static void vpe20_mpc_select_3dlut_ram_and_mask(struct mpc *mpc, enum vpe_lut_mode mode,
bool is_color_channel_12bits, uint32_t ram_selection_mask)
{
PROGRAM_ENTRY();
VPE_ASSERT(mode == LUT_RAM_A);
REG_SET_3(VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL, REG_DEFAULT(VPMPC_RMCM_3DLUT_READ_WRITE_CONTROL),
VPMPC_RMCM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, VPMPC_RMCM_3DLUT_30BIT_EN,
is_color_channel_12bits ? 0 : 1, VPMPC_RMCM_3DLUT_WRITE_EN_MASK, ram_selection_mask);
REG_SET(VPMPC_RMCM_3DLUT_INDEX, 0, VPMPC_RMCM_3DLUT_INDEX, 0);
}
static void vpe20_mpc_set3dlut_ram12(struct mpc *mpc, const struct vpe_rgb *lut, uint32_t entries)
{
PROGRAM_ENTRY();
uint32_t i, red, green, blue, red1, green1, blue1;
uint16_t MaxLutEntriesPerPacket =
(MAX_CONFIG_PACKET_DATA_SIZE_DWORD / 3) * 2; // each two entries consumes 3 DWORDs
uint16_t ActualEntriesInPacket = 0;
uint16_t ActualPacketSize;
// Optimized by single VPEP config packet for same address with multiple write
for (i = 0; i < entries; i += 2) {
if (i % MaxLutEntriesPerPacket == 0) { // need generate one another new packet
ActualEntriesInPacket = MaxLutEntriesPerPacket;
// If single packet is big enough to contain remaining entries
if ((entries - i) < MaxLutEntriesPerPacket) {
ActualEntriesInPacket = (uint16_t)(entries - i);
if ((entries - i) % 2) {
// odd entries, round up to even as we need to program in pair
ActualEntriesInPacket++;
}
}
ActualPacketSize = ActualEntriesInPacket * 3 / 2;
VPE_ASSERT(ActualPacketSize <= MAX_CONFIG_PACKET_DATA_SIZE_DWORD);
packet.bits.INC = 0;
packet.bits.VPEP_CONFIG_DATA_SIZE =
ActualPacketSize - 1; // number of "continuous" dwords, 1-based
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(VPMPC_RMCM_3DLUT_DATA);
config_writer_fill_direct_config_packet_header(config_writer, &packet);
}
red = lut[i].red << 4;
green = lut[i].green << 4;
blue = lut[i].blue << 4;
if (i + 1 < entries) {
red1 = lut[i + 1].red << 4;
green1 = lut[i + 1].green << 4;
blue1 = lut[i + 1].blue << 4;
}
else {
// last odd entry, program 0 for extra one that accompany with it.
red1 = 0;
green1 = 0;
blue1 = 0;
}
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA0, red) |
REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA1, red1));
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA0, green) |
REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA1, green1));
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA0, blue) |
REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA1, blue1));
}
}
static void vpe20_mpc_set3dlut_ram10(struct mpc *mpc, const struct vpe_rgb *lut, uint32_t entries)
{
PROGRAM_ENTRY();
uint32_t i, red, green, blue, value;
uint16_t MaxLutEntriesPerPacket =
MAX_CONFIG_PACKET_DATA_SIZE_DWORD; // each entries consumes 1 DWORDs
uint16_t ActualPacketSize;
// Optimize to VPEP direct with multiple data
for (i = 0; i < entries; i++) {
// Need to revisit about the new config writer handling , DO WE STILL NEED IT?
// Yes, this is to ensure how many "packets" we need due to each packet have max data size
// i.e. need to split into diff packets (but might still in one direct config descriptor)
// The new config writer handles the "descriptor" size exceeded issue.
// i.e. need to split into diff direct config descriptors.
if (i % MaxLutEntriesPerPacket == 0) { // need generate one another new packet
if ((entries - i) <
MaxLutEntriesPerPacket) // Single packet is big enough to contain remaining entries
MaxLutEntriesPerPacket = (uint16_t)(entries - i);
ActualPacketSize = MaxLutEntriesPerPacket;
VPE_ASSERT(ActualPacketSize <= MAX_CONFIG_PACKET_DATA_SIZE_DWORD);
packet.bits.INC = 0;
packet.bits.VPEP_CONFIG_DATA_SIZE =
ActualPacketSize - 1; // number of "continuous" dwords, 1-based
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(VPMPC_RMCM_3DLUT_DATA_30BIT);
config_writer_fill_direct_config_packet_header(config_writer, &packet);
}
red = lut[i].red;
green = lut[i].green;
blue = lut[i].blue;
// should we shift red 22bit and green 12?
// Yes, accroding to spec.
// let's do it instead of just shift 10 bits
value = (red << 22) | (green << 12) | blue << 2;
config_writer_fill(config_writer, REG_FIELD_VALUE(VPMPC_RMCM_3DLUT_DATA_30BIT, value));
}
}
static void vpe20_mpc_set_3dlut_mode(
struct mpc *mpc, enum vpe_lut_mode mode, bool is_lut_size17x17x17)
{
PROGRAM_ENTRY();
uint32_t lut_mode;
if (mode == LUT_BYPASS)
lut_mode = 0;
else if (mode == LUT_RAM_A)
lut_mode = 1;
else
lut_mode = 2;
// 0 = 17x17x17, 1 = 9x9x9, 2 = 33x33x33
// VPE2 does not support 9x9x9
REG_SET_2(VPMPC_RMCM_3DLUT_MODE, 0, VPMPC_RMCM_3DLUT_MODE, lut_mode, VPMPC_RMCM_3DLUT_SIZE,
is_lut_size17x17x17 == true ? 0 : 2);
}
// using direct config to program the 3dlut specified in params
void vpe20_mpc_program_3dlut(struct mpc *mpc, const struct tetrahedral_params *params)
{
PROGRAM_ENTRY();
enum vpe_lut_mode mode;
bool is_17x17x17;
bool is_12bits_color_channel;
const struct vpe_rgb *lut0;
const struct vpe_rgb *lut1;
const struct vpe_rgb *lut2;
const struct vpe_rgb *lut3;
uint32_t lut_size0;
uint32_t lut_size;
if (params == NULL) {
vpe20_mpc_set_3dlut_mode(mpc, LUT_BYPASS, false);
return;
}
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, true);
// always use LUT_RAM_A except for bypass mode which is not the case here
mode = LUT_RAM_A;
is_17x17x17 = (params->lut_dim == LUT_DIM_17);
is_12bits_color_channel = params->use_12bits;
if (is_17x17x17) {
lut0 = params->tetrahedral_17.lut0;
lut1 = params->tetrahedral_17.lut1;
lut2 = params->tetrahedral_17.lut2;
lut3 = params->tetrahedral_17.lut3;
lut_size0 = sizeof(params->tetrahedral_17.lut0) / sizeof(params->tetrahedral_17.lut0[0]);
lut_size = sizeof(params->tetrahedral_17.lut1) / sizeof(params->tetrahedral_17.lut1[0]);
}
else if (params->lut_dim == LUT_DIM_33) {
lut0 = params->tetrahedral_33.lut0;
lut1 = params->tetrahedral_33.lut1;
lut2 = params->tetrahedral_33.lut2;
lut3 = params->tetrahedral_33.lut3;
lut_size0 = sizeof(params->tetrahedral_33.lut0) / sizeof(params->tetrahedral_33.lut0[0]);
lut_size = sizeof(params->tetrahedral_33.lut1) / sizeof(params->tetrahedral_33.lut1[0]);
}
else {
// 9x9x9 mode not supported on VPE2
VPE_ASSERT(false);
vpe20_mpc_set_3dlut_mode(mpc, LUT_BYPASS, false);
return;
}
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12(mpc, lut0, lut_size0);
else
vpe20_mpc_set3dlut_ram10(mpc, lut0, lut_size0);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12(mpc, lut1, lut_size);
else
vpe20_mpc_set3dlut_ram10(mpc, lut1, lut_size);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12(mpc, lut2, lut_size);
else
vpe20_mpc_set3dlut_ram10(mpc, lut2, lut_size);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12(mpc, lut3, lut_size);
else
vpe20_mpc_set3dlut_ram10(mpc, lut3, lut_size);
vpe20_mpc_set_3dlut_mode(mpc, mode, is_17x17x17);
if (vpe_priv->init.debug.enable_mem_low_power.bits.mpc)
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, false);
return;
}
static void vpe20_mpc_set3dlut_ram10_indirect(
struct mpc *mpc, const uint64_t lut_gpuva, uint32_t entries)
{
PROGRAM_ENTRY();
uint32_t data_array_size = entries; // DW size of config data array, actual size
// Optimized by single VPEP indirect config packet
// The layout inside the lut buf must be: (each element is 10bit, but LSB[1:0] are always 0)
// DW0: R0<<22 | G0<<12 | B0 <<2
// DW0: R1<<22 | G1<<12 | B1 <<2
//...
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT, mpc->inst);
// Optimized by single VPEP indirect config packet
// Fill the 3dLut array pointer
config_writer_fill_indirect_data_array(config_writer, lut_gpuva, data_array_size);
// Start from index 0
config_writer_fill_indirect_destination(
config_writer, REG_OFFSET(VPMPC_RMCM_3DLUT_INDEX), 0, REG_OFFSET(VPMPC_RMCM_3DLUT_DATA));
// resume back to direct
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
}
static void vpe20_mpc_set3dlut_ram12_indirect(
struct mpc *mpc, const uint64_t lut_gpuva, uint32_t entries)
{
PROGRAM_ENTRY();
// The layout inside the lut buf must be: (each element is 16bit, but LSB[3:0] are always 0)
// DW0: R1<<16 | R0
// DW1: G1<<16 | G0
// DW2: B1<<16 | B0
// DW3: R3<<16 | R2
// DW4: G3<<16 | G2
// DW5: B3<<16 | B2
//...
uint32_t data_array_size = (entries / 2 * 3); // DW size of config data array, actual size
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT, mpc->inst);
// Optimized by single VPEP indirect config packet
// Fill the 3dLut array pointer
config_writer_fill_indirect_data_array(config_writer, lut_gpuva, data_array_size);
// Start from index 0
config_writer_fill_indirect_destination(
config_writer, REG_OFFSET(VPMPC_RMCM_3DLUT_INDEX), 0, REG_OFFSET(VPMPC_RMCM_3DLUT_DATA));
// restore back to direct
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
}
// using indirect config to configure the 3DLut
// note that we still need direct config to switch the mask between lut0 - lut3
bool vpe20_mpc_program_3dlut_indirect(struct mpc *mpc,
struct vpe_buf *lut0_3_buf, // 3d lut buf which contains the data for lut0-lut3
bool use_tetrahedral_9, bool use_12bits)
{
PROGRAM_ENTRY();
enum vpe_lut_mode mode;
bool is_12bits_color_channel;
uint64_t lut0_gpuva;
uint64_t lut1_gpuva;
uint64_t lut2_gpuva;
uint64_t lut3_gpuva;
uint32_t lut_size0;
uint32_t lut_size;
// see struct tetrahedral_17x17x17 definition
const uint32_t tetra17_lut_size = 1228;
// make sure it is in DIRECT type
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
if (lut0_3_buf == NULL || use_tetrahedral_9) {
vpe20_mpc_set_3dlut_mode(mpc, LUT_BYPASS, false);
return false;
}
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, true);
// always use LUT_RAM_A except for bypass mode which is not the case here
mode = LUT_RAM_A;
is_12bits_color_channel = use_12bits;
lut0_gpuva = lut0_3_buf->gpu_va;
lut1_gpuva = lut0_3_buf->gpu_va + (uint64_t)(offsetof(struct tetrahedral_17x17x17, lut1));
lut2_gpuva = lut0_3_buf->gpu_va + (uint64_t)(offsetof(struct tetrahedral_17x17x17, lut2));
lut3_gpuva = lut0_3_buf->gpu_va + (uint64_t)(offsetof(struct tetrahedral_17x17x17, lut3));
lut_size0 = tetra17_lut_size + 1; // lut0 has an extra element (vertex (0,0,0))
lut_size = tetra17_lut_size;
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12_indirect(mpc, lut0_gpuva, lut_size0);
else
vpe20_mpc_set3dlut_ram10_indirect(mpc, lut0_gpuva, lut_size0);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12_indirect(mpc, lut1_gpuva, lut_size);
else
vpe20_mpc_set3dlut_ram10_indirect(mpc, lut1_gpuva, lut_size);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12_indirect(mpc, lut2_gpuva, lut_size);
else
vpe20_mpc_set3dlut_ram10_indirect(mpc, lut2_gpuva, lut_size);
if (is_12bits_color_channel)
vpe20_mpc_set3dlut_ram12_indirect(mpc, lut3_gpuva, lut_size);
else
vpe20_mpc_set3dlut_ram10_indirect(mpc, lut3_gpuva, lut_size);
vpe20_mpc_set_3dlut_mode(mpc, mode, !use_tetrahedral_9); // always true here
if (vpe_priv->init.debug.enable_mem_low_power.bits.mpc)
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, false);
return true;
}
void vpe20_attach_3dlut_to_mpc_inst(struct mpc *mpc, enum mpc_mpccid mpcc_idx)
{
PROGRAM_ENTRY();
REG_SET(VPMPC_RMCM_CNTL, REG_DEFAULT(VPMPC_RMCM_CNTL), VPMPC_RMCM_CNTL, mpcc_idx);
}
void vpe20_mpc_set_mpc_shaper_3dlut(
struct mpc *mpc, struct transfer_func *func_shaper, struct vpe_3dlut *lut3d_func)
{
const struct pwl_params *shaper_lut = NULL;
const struct tetrahedral_params *lut3d_params;
PROGRAM_ENTRY();
struct stream_ctx *stream_ctx = &vpe_priv->stream_ctx[vpe_priv->fe_cb_ctx.stream_idx];
bool bypass;
// get the shaper lut params
if (func_shaper) {
if (func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
vpe10_cm_helper_translate_curve_to_hw_format(func_shaper, &mpc->shaper_params, true,
func_shaper->dirty[mpc->inst]); // should init shaper_params first
shaper_lut = &mpc->shaper_params; // are there shaper prams in dpp instead?
}
else if (func_shaper->type == TF_TYPE_HWPWL) {
shaper_lut = &func_shaper->pwl;
}
}
bypass = (!shaper_lut || (func_shaper && func_shaper->type == TF_TYPE_BYPASS));
CONFIG_CACHE(func_shaper, stream_ctx, vpe_priv->init.debug.disable_lut_caching, bypass,
mpc->funcs->program_shaper(mpc, shaper_lut), mpc->inst);
if (lut3d_func && !lut3d_func->state.bits.is_dma) {
bypass = (!lut3d_func || !lut3d_func->state.bits.initialized);
lut3d_params = (bypass) ? (NULL) : (&lut3d_func->lut_3d);
CONFIG_CACHE(lut3d_func, stream_ctx, vpe_priv->init.debug.disable_lut_caching, bypass,
mpc->funcs->program_3dlut(mpc, lut3d_params), mpc->inst);
}
return;
}
bool vpe20_mpc_program_movable_cm(struct mpc *mpc, struct transfer_func *func_shaper,
struct vpe_3dlut *lut3d_func, struct transfer_func *blend_tf, bool afterblend)
{
struct pwl_params *params = NULL;
bool ret = false;
/*program shaper and 3dlut and 1dlut in MPC*/
/*only 1 3dlut inst so only program once*/
if ((func_shaper || lut3d_func) && (mpc->funcs->set_mpc_shaper_3dlut != NULL))
mpc->funcs->set_mpc_shaper_3dlut(mpc, func_shaper, lut3d_func);
mpc->funcs->set_blend_lut(mpc, blend_tf);
mpc->funcs->program_cm_location(mpc, afterblend);
return ret;
}
static void vpe20_program_gamut_remap(struct mpc *mpc,
enum mpcc_gamut_remap_id gamut_remap_block_id, const uint16_t *regval,
enum gamut_remap_select select)
{
uint16_t selection = 0;
struct color_matrices_reg gam_regs;
PROGRAM_ENTRY();
switch (gamut_remap_block_id) {
case VPE_MPC_GAMUT_REMAP:
if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
REG_SET(VPMPCC_GAMUT_REMAP_MODE, 0, VPMPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS);
return;
}
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPMPCC_GAMUT_REMAP_C11_A);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPMPCC_GAMUT_REMAP_C11_A);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPMPCC_GAMUT_REMAP_C12_A);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPMPCC_GAMUT_REMAP_C12_A);
gam_regs.csc_c11_c12 = REG_OFFSET(VPMPC_GAMUT_REMAP_C11_C12_A);
gam_regs.csc_c33_c34 = REG_OFFSET(VPMPC_GAMUT_REMAP_C33_C34_A);
vpe10_cm_helper_program_color_matrices(config_writer, regval, &gam_regs);
REG_SET(VPMPCC_GAMUT_REMAP_MODE, 0, VPMPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_COMA_COEFF);
break;
case VPE_MPC_RMCM_GAMUT_REMAP:
if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
REG_SET(
VPMPC_RMCM_GAMUT_REMAP_MODE, 0, VPMPC_RMCM_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS);
return;
}
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPMPC_RMCM_GAMUT_REMAP_C11_SETA);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPMPC_RMCM_GAMUT_REMAP_C11_SETA);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPMPC_RMCM_GAMUT_REMAP_C12_SETA);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPMPC_RMCM_GAMUT_REMAP_C12_SETA);
gam_regs.csc_c11_c12 = REG_OFFSET(VPMPC_RMCM_GAMUT_REMAP_C11_C12_SETA);
gam_regs.csc_c33_c34 = REG_OFFSET(VPMPC_RMCM_GAMUT_REMAP_C33_C34_SETA);
vpe10_cm_helper_program_color_matrices(config_writer, regval, &gam_regs);
REG_SET(
VPMPC_RMCM_GAMUT_REMAP_MODE, 0, VPMPC_RMCM_GAMUT_REMAP_MODE, GAMUT_REMAP_COMA_COEFF);
break;
case VPE_MPC_MCM_FIRST_GAMUT_REMAP:
if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
REG_SET(VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, 0, VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE,
GAMUT_REMAP_BYPASS);
return;
}
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPMPCC_MCM_FIRST_GAMUT_REMAP_C11_SETA);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPMPCC_MCM_FIRST_GAMUT_REMAP_C11_SETA);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPMPCC_MCM_FIRST_GAMUT_REMAP_C12_SETA);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPMPCC_MCM_FIRST_GAMUT_REMAP_C12_SETA);
gam_regs.csc_c11_c12 = REG_OFFSET(VPMPC_MCM_FIRST_GAMUT_REMAP_C11_C12_SETA);
gam_regs.csc_c33_c34 = REG_OFFSET(VPMPC_MCM_FIRST_GAMUT_REMAP_C33_C34_SETA);
vpe10_cm_helper_program_color_matrices(config_writer, regval, &gam_regs);
REG_SET(VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE, 0, VPMPCC_MCM_FIRST_GAMUT_REMAP_MODE,
GAMUT_REMAP_COMA_COEFF);
break;
case VPE_MPC_MCM_SECOND_GAMUT_REMAP:
if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
REG_SET(VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, 0, VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE,
GAMUT_REMAP_BYPASS);
return;
}
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPMPCC_MCM_SECOND_GAMUT_REMAP_C11_SETA);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPMPCC_MCM_SECOND_GAMUT_REMAP_C11_SETA);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPMPCC_MCM_SECOND_GAMUT_REMAP_C12_SETA);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPMPCC_MCM_SECOND_GAMUT_REMAP_C12_SETA);
gam_regs.csc_c11_c12 = REG_OFFSET(VPMPC_MCM_SECOND_GAMUT_REMAP_C11_C12_SETA);
gam_regs.csc_c33_c34 = REG_OFFSET(VPMPC_MCM_SECOND_GAMUT_REMAP_C33_C34_SETA);
vpe10_cm_helper_program_color_matrices(config_writer, regval, &gam_regs);
REG_SET(VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE, 0, VPMPCC_MCM_SECOND_GAMUT_REMAP_MODE,
GAMUT_REMAP_COMA_COEFF);
break;
default:
VPE_ASSERT(0);
break;
}
}
void vpe20_mpc_set_gamut_remap2(struct mpc *mpc, struct colorspace_transform *gamut_remap,
enum mpcc_gamut_remap_id mpcc_gamut_remap_block_id)
{
uint16_t arr_reg_val[12] = {0}; // Initialize to zero
PROGRAM_ENTRY();
int i = 0;
enum gamut_remap_select gamutSel = GAMUT_REMAP_COMA_COEFF;
if (!gamut_remap || !gamut_remap->enable_remap)
gamutSel = GAMUT_REMAP_BYPASS;
else {
conv_convert_float_matrix(arr_reg_val, gamut_remap->matrix, 12);
}
vpe20_program_gamut_remap(mpc, mpcc_gamut_remap_block_id,
(gamutSel == GAMUT_REMAP_COMA_COEFF) ? arr_reg_val : NULL, gamutSel);
}
void vpe20_update_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale)
{
PROGRAM_ENTRY();
REG_SET_2(VPMPC_VPCDC0_3DLUT_FL_BIAS_SCALE, 0, VPCDC0_3DLUT_FL_BIAS, bias,
VPCDC0_3DLUT_FL_SCALE, scale);
}
void vpe20_mpc_program_3dlut_fl_config(struct mpc *mpc, enum vpe_3dlut_mem_layout layout,
enum vpe_3dlut_mem_format format, bool enable)
{
PROGRAM_ENTRY();
if (enable) {
REG_SET(VPMPC_RMCM_3DLUT_FAST_LOAD_SELECT, 0, VPMPC_RMCM_3DLUT_FL_SEL,
MPC_RMCM_3DLUT_FL_ENABLE);
REG_SET_2(VPMPC_VPCDC0_3DLUT_FL_CONFIG, 0, VPCDC0_3DLUT_FL_MODE, layout,
VPCDC0_3DLUT_FL_FORMAT, format);
} else
REG_SET(VPMPC_RMCM_3DLUT_FAST_LOAD_SELECT, 0, VPMPC_RMCM_3DLUT_FL_SEL,
MPC_RMCM_3DLUT_FL_DISABLE);
}
void vpe20_mpc_program_3dlut_fl(struct mpc *mpc, enum lut_dimension lut_dimension, bool use_12bit)
{
PROGRAM_ENTRY();
enum vpe_lut_mode mode = LUT_RAM_A;
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, true);
// always use LUT_RAM_A except for bypass mode which is not the case here
vpe20_mpc_set_3dlut_mode(mpc, mode, lut_dimension == LUT_DIM_17 ? 1 : 0);
if (vpe_priv->init.debug.enable_mem_low_power.bits.mpc)
vpe20_mpc_power_on_1dlut_shaper_3dlut(mpc, false);
}

View file

@ -0,0 +1,335 @@
/* Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include <string.h>
#include "common.h"
#include "vpe_priv.h"
#include "vpe20_opp.h"
#include "hw_shared.h"
#include "reg_helper.h"
#include "custom_fp16.h"
#define CTX_BASE opp
#define CTX vpe20_opp
static struct opp_funcs opp20_funcs = {
.program_pipe_control = vpe20_opp_program_pipe_control,
.program_pipe_crc = vpe20_opp_program_pipe_crc,
.set_clamping = vpe10_opp_set_clamping,
.program_bit_depth_reduction = vpe20_opp_program_bit_depth_reduction,
.set_dyn_expansion = vpe10_opp_set_dyn_expansion,
.program_fmt = vpe10_opp_program_fmt,
.program_fmt_control = vpe20_opp_program_fmt_control,
.build_fmt_subsample_params = vpe20_opp_build_fmt_subsample_params,
.set_bg = vpe20_opp_set_bg,
.program_frod = vpe20_opp_program_frod,
.get_fmt_extra_pixel = vpe20_opp_get_fmt_extra_pixel,
};
enum fmt_pixel {
PIXEL_ENCODING_RGB444_YCBCR444 = 0,
PIXEL_ENCODING_YCBCR422 = 1,
PIXEL_ENCODING_YCBCR420 = 2
};
enum fmt_taps {
TAPS2 = 0,
TAPS3 = 1,
TAPS4 = 2,
TAPS5 = 3
};
void vpe20_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp)
{
opp->vpe_priv = vpe_priv;
opp->funcs = &opp20_funcs;
}
void vpe20_opp_program_pipe_control(struct opp *opp, const struct opp_pipe_control_params *params)
{
PROGRAM_ENTRY();
REG_SET_3(VPOPP_PIPE_CONTROL, REG_DEFAULT(VPOPP_PIPE_CONTROL), VPOPP_PIPE_ALPHA, params->alpha,
VPOPP_PIPE_DIGITAL_BYPASS_EN, params->bypass_enable, VPOPP_PIPE_ALPHA_SEL,
params->alpha_select);
}
void vpe20_opp_program_pipe_crc(struct opp *opp, bool enable)
{
PROGRAM_ENTRY();
// REG_SET(VPOPP_PIPE_CRC_CONTROL, REG_DEFAULT(VPOPP_PIPE_CRC_CONTROL), VPOPP_PIPE_CRC_EN,
// enable);
}
static void get_fmt_chroma_taps(enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct chroma_taps *ctaps)
{
memset(ctaps, 0, sizeof(*ctaps));
if (vpe_is_yuv420(format)) {
ctaps->v_taps_c = 2;
ctaps->h_taps_c = 2;
switch (cositing) {
case CHROMA_COSITING_LEFT:
ctaps->h_taps_c = 3;
break;
case CHROMA_COSITING_TOPLEFT:
ctaps->v_taps_c = 3;
ctaps->h_taps_c = 3;
break;
default:
break;
}
if (subsample_quality == SUBSAMPLING_QUALITY_HIGH) {
ctaps->v_taps_c += 2;
ctaps->h_taps_c += 2;
}
} else if (vpe_is_yuv422(format)) {
if (subsample_quality == SUBSAMPLING_QUALITY_HIGH)
ctaps->h_taps_c = 5;
else
ctaps->h_taps_c = 3;
}
}
void vpe20_opp_build_fmt_subsample_params(struct opp *opp, enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_boundary_mode boundary_mode, struct fmt_subsampling_params *subsample_params)
{
PROGRAM_ENTRY();
struct chroma_taps ctaps;
uint32_t pixel_encoding = PIXEL_ENCODING_RGB444_YCBCR444;
uint32_t bit_reduction_bypass = 0;
uint32_t vtaps = 0;
uint32_t htaps = 0;
if (!subsample_params)
return;
get_fmt_chroma_taps(format, subsample_quality, cositing, &ctaps);
if (vpe_is_yuv420(format)) {
pixel_encoding = PIXEL_ENCODING_YCBCR420;
bit_reduction_bypass = 1;
} else if (vpe_is_yuv422(format)) {
pixel_encoding = PIXEL_ENCODING_YCBCR422;
bit_reduction_bypass = 1;
} else {
pixel_encoding = PIXEL_ENCODING_RGB444_YCBCR444;
}
switch (ctaps.h_taps_c) {
case 2:
htaps = TAPS2;
break;
case 3:
htaps = TAPS3;
break;
case 4:
htaps = TAPS4;
break;
case 5:
htaps = TAPS5;
break;
default:
break;
}
switch (ctaps.v_taps_c) {
case 2:
vtaps = TAPS2;
break;
case 3:
vtaps = TAPS3;
break;
case 4:
vtaps = TAPS4;
break;
case 5:
vtaps = TAPS5;
break;
default:
break;
}
subsample_params->pixel_encoding = pixel_encoding;
subsample_params->bit_reduction_bypass = bit_reduction_bypass;
subsample_params->htaps = htaps;
subsample_params->vtaps = vtaps;
subsample_params->boundary_mode = boundary_mode;
}
void vpe20_opp_program_fmt_control(struct opp *opp, struct fmt_control_params *fmt_ctrl)
{
PROGRAM_ENTRY();
REG_SET_10(VPFMT_CONTROL, REG_DEFAULT(VPFMT_CONTROL), VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX,
fmt_ctrl->fmt_spatial_dither_frame_counter_max, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP,
fmt_ctrl->fmt_spatial_dither_frame_counter_bit_swap, VPFMT_PIXEL_ENCODING,
fmt_ctrl->subsampling_params.pixel_encoding, VPFMT_CBCR_BIT_REDUCTION_BYPASS,
fmt_ctrl->subsampling_params.bit_reduction_bypass, VPFMT_SUBSAMPLE_HTAPS,
fmt_ctrl->subsampling_params.htaps, VPFMT_SUBSAMPLE_VTAPS,
fmt_ctrl->subsampling_params.vtaps, VPFMT_SUBSAMPLE_BOTTOM_EDGE,
fmt_ctrl->subsampling_params.boundary_mode.bottom, VPFMT_SUBSAMPLE_TOP_EDGE,
fmt_ctrl->subsampling_params.boundary_mode.top, VPFMT_SUBSAMPLE_RIGHT_EDGE,
fmt_ctrl->subsampling_params.boundary_mode.right, VPFMT_SUBSAMPLE_LEFT_EDGE,
fmt_ctrl->subsampling_params.boundary_mode.left);
}
void vpe20_opp_set_bg(struct opp* opp, struct vpe_rect target_rect, struct vpe_rect dst_rect,
enum vpe_surface_pixel_format format, struct vpe_color bgcolor)
{
PROGRAM_ENTRY();
uint32_t top_lines, bot_lines, left_lines, right_lines;
uint16_t r_cr, g_y, b_cb;
top_lines = dst_rect.y >= target_rect.y ? dst_rect.y - target_rect.y : 0;
bot_lines = (target_rect.y + target_rect.height) >= (dst_rect.y + dst_rect.height)
? (target_rect.y + target_rect.height) - (dst_rect.y + dst_rect.height)
: 0;
left_lines = dst_rect.x >= target_rect.x ? dst_rect.x - target_rect.x : 0;
right_lines = (target_rect.x + target_rect.width) >= (dst_rect.x + dst_rect.width)
? (target_rect.x + target_rect.width) - (dst_rect.x + dst_rect.width)
: 0;
if (vpe_is_fp16(format)) {
vpe_convert_from_float_to_fp16(bgcolor.rgba.r, &r_cr);
vpe_convert_from_float_to_fp16(bgcolor.rgba.g, &g_y);
vpe_convert_from_float_to_fp16(bgcolor.rgba.b, &b_cb);
} else if (bgcolor.is_ycbcr) {
g_y = (uint16_t)(bgcolor.ycbcra.y * 0xffff);
r_cr = (uint16_t)(bgcolor.ycbcra.cr * 0xffff);
b_cb = (uint16_t)(bgcolor.ycbcra.cb * 0xffff);
} else {
r_cr = (uint16_t)(bgcolor.rgba.r * 0xffff);
g_y = (uint16_t)(bgcolor.rgba.g * 0xffff);
b_cb = (uint16_t)(bgcolor.rgba.b * 0xffff);
}
if (vpe_is_yuv420(format)) {
if (top_lines % 2 != 0)
top_lines += 1;
if (bot_lines % 2 != 0)
bot_lines += 1;
if (left_lines % 2 != 0)
left_lines += 1;
if (right_lines % 2 != 0)
right_lines += 1;
} else if (vpe_is_yuv422(format)) {
if (left_lines % 2 != 0)
left_lines += 1;
if (right_lines % 2 != 0)
right_lines += 1;
}
REG_SET_2(VPOPP_PIPE_OUTBG_EXT1, 0, OUTBG_EXT_TOP, top_lines, OUTBG_EXT_BOT, bot_lines);
REG_SET_2(VPOPP_PIPE_OUTBG_EXT2, 0, OUTBG_EXT_LEFT, left_lines, OUTBG_EXT_RIGHT, right_lines);
REG_SET_2(VPOPP_PIPE_OUTBG_COL1, 0, OUTBG_R_CR, r_cr, OUTBG_B_CB, b_cb);
REG_SET(VPOPP_PIPE_OUTBG_COL2, 0, OUTBG_Y, g_y);
}
void vpe20_opp_program_frod(struct opp *opp, struct opp_frod_param *frod_param)
{
PROGRAM_ENTRY();
REG_SET(VPOPP_FROD_CONTROL, 0, FROD_EN, frod_param->enable_frod);
}
void vpe20_opp_get_fmt_extra_pixel(enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_extra_pixel_info *extra_pixel)
{
(void)format;
(void)subsample_quality;
(void)cositing;
extra_pixel->left_pixels = 2;
extra_pixel->right_pixels = 1;
extra_pixel->top_pixels = 2;
extra_pixel->bottom_pixels = 1;
}
void vpe20_opp_program_bit_depth_reduction(
struct opp *opp, const struct bit_depth_reduction_params *params)
{
PROGRAM_ENTRY();
if (params->flags.SPATIAL_DITHER_ENABLED == 0) {
/*Disable spatial (random) dithering*/
REG_SET_9(VPFMT_BIT_DEPTH_CONTROL, REG_DEFAULT(VPFMT_BIT_DEPTH_CONTROL), VPFMT_TRUNCATE_EN,
params->flags.TRUNCATE_ENABLED, VPFMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH,
VPFMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE, VPFMT_SPATIAL_DITHER_EN, 0,
VPFMT_SPATIAL_DITHER_MODE, 0, VPFMT_SPATIAL_DITHER_DEPTH, 0,
VPFMT_HIGHPASS_RANDOM_ENABLE, 0, VPFMT_FRAME_RANDOM_ENABLE, 0, VPFMT_RGB_RANDOM_ENABLE,
0);
return;
}
/* Set seed for random values for
* spatial dithering for R,G,B channels
*/
REG_SET(VPFMT_DITHER_RAND_R_SEED, 0, VPFMT_RAND_R_SEED, params->r_seed_value);
REG_SET(VPFMT_DITHER_RAND_G_SEED, 0, VPFMT_RAND_G_SEED, params->g_seed_value);
REG_SET(VPFMT_DITHER_RAND_B_SEED, 0, VPFMT_RAND_B_SEED, params->b_seed_value);
/* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero
* offset for the R/Cr channel, lower 4LSB
* is forced to zeros. Typically set to 0
* RGB and 0x80000 YCbCr.
*/
/* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero
* offset for the G/Y channel, lower 4LSB is
* forced to zeros. Typically set to 0 RGB
* and 0x80000 YCbCr.
*/
/* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero
* offset for the B/Cb channel, lower 4LSB is
* forced to zeros. Typically set to 0 RGB and
* 0x80000 YCbCr.
*/
REG_SET_9(VPFMT_BIT_DEPTH_CONTROL, REG_DEFAULT(VPFMT_BIT_DEPTH_CONTROL), VPFMT_TRUNCATE_EN,
params->flags.TRUNCATE_ENABLED, VPFMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH,
VPFMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE,
/*Enable spatial dithering*/
VPFMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED,
/* Set spatial dithering mode
* (default is Seed patterrn AAAA...)
*/
VPFMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
/*Set spatial dithering bit depth*/
VPFMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
/*Disable High pass filter*/
VPFMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
/*Reset only at startup*/
VPFMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
/*Set RGB data dithered with x^28+x^3+1*/
VPFMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
}

View file

@ -0,0 +1,231 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_assert.h"
#include "vpe20_command.h"
#include "vpe20_plane_desc_writer.h"
#include "reg_helper.h"
void vpe20_construct_plane_desc_writer(struct plane_desc_writer *writer)
{
writer->init = vpe20_plane_desc_writer_init;
writer->add_source = vpe20_plane_desc_writer_add_source;
writer->add_destination = vpe20_plane_desc_writer_add_destination;
writer->add_meta = vpe20_plane_desc_writer_add_meta;
writer->add_histo = vpe20_plane_desc_writer_add_hist_destination;
}
void vpe20_plane_desc_writer_init(
struct plane_desc_writer *writer, struct vpe_buf *buf, void *p_header)
{
uint32_t *cmd_space;
uint64_t size = 4;
struct vpe20_plane_desc_header *header = (struct vpe20_plane_desc_header *)p_header;
// For VPE 2.0 all config and plane descriptors gpu address must be 6 bit aligned
uint64_t aligned_gpu_address =
(buf->gpu_va + VPE_PLANE_ADDR_ALIGNMENT_MASK) & ~VPE_PLANE_ADDR_ALIGNMENT_MASK;
uint64_t alignment_offset = aligned_gpu_address - buf->gpu_va;
buf->gpu_va = aligned_gpu_address;
buf->cpu_va = buf->cpu_va + alignment_offset;
if (buf->size < alignment_offset) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
buf->size -= alignment_offset;
writer->status = VPE_STATUS_OK;
writer->base_cpu_va = buf->cpu_va;
writer->base_gpu_va = buf->gpu_va;
writer->buf = buf;
writer->num_src = 0;
writer->num_dst = 0;
/* Buffer does not have enough space to write */
if (buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = VPE_PLANE_CFG_CMD_HEADER(header->subop, header->nps0, header->npd0, header->nps1,
header->npd1, header->dcomp0, header->dcomp1, header->frod, header->hist0_dsets,
header->hist1_dsets);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
/** fill the value to the embedded buffer. */
void vpe20_plane_desc_writer_add_source(
struct plane_desc_writer *writer, void *p_source, bool is_plane0)
{
uint32_t *cmd_space, *cmd_start;
uint32_t num_wd = is_plane0 ? 6 : 5;
uint64_t size = num_wd * sizeof(uint32_t);
struct vpe20_plane_desc_src *src = (struct vpe20_plane_desc_src *)p_source;
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_start = cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
if (is_plane0) {
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_TMZ, src->tmz) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_SWIZZLE_MODE, src->swizzle) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_SCAN_PATTERN, src->scan);
}
VPE_ASSERT(!(src->base_addr_lo & 0xFF));
*cmd_space++ = src->base_addr_lo;
*cmd_space++ = src->base_addr_hi;
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_PITCH, src->pitch - 1) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE, src->elem_size);
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_X, src->viewport_x) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_Y, src->viewport_y);
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_WIDTH, src->viewport_w - 1) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_HEIGHT, src->viewport_h - 1);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
/** fill the value to the embedded buffer. */
void vpe20_plane_desc_writer_add_destination(
struct plane_desc_writer *writer, void *p_destination, bool write_header)
{
uint32_t *cmd_space, *cmd_start;
uint32_t num_wd = write_header ? 6 : 5;
uint64_t size = num_wd * sizeof(uint32_t);
struct vpe20_plane_desc_dst *dst = (struct vpe20_plane_desc_dst *)p_destination;
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_start = cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
if (write_header) {
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_TMZ, dst->tmz) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_SWIZZLE_MODE, dst->swizzle);
}
writer->num_dst++;
VPE_ASSERT(!(dst->base_addr_lo & 0xFF));
*cmd_space++ = dst->base_addr_lo;
*cmd_space++ = dst->base_addr_hi;
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_PITCH, dst->pitch - 1) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE, dst->elem_size);
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_X, dst->viewport_x) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_Y, dst->viewport_y);
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_WIDTH, dst->viewport_w - 1) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_HEIGHT, dst->viewport_h - 1);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
void vpe20_plane_desc_writer_add_meta(struct plane_desc_writer *writer, void *p_source)
{
uint32_t *cmd_space, *cmd_start;
uint32_t num_wd = 3;
uint64_t size = num_wd * sizeof(uint32_t);
struct vpe20_plane_desc_src *src = (struct vpe20_plane_desc_src *)p_source;
if (writer == NULL || src == NULL)
return;
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_start = cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = src->meta_base_addr_lo | VPEC_FIELD_VALUE(VPE_PLANE_CFG_META_TMZ, src->tmz);
*cmd_space++ = src->meta_base_addr_hi;
*cmd_space++ = VPEC_FIELD_VALUE(VPE_PLANE_CFG_META_PITCH, src->meta_pitch - 1) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_PIXEL_FORMAT, src->format) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_INDEPENDENT_BLOCKS, src->dcc_ind_blk) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_PA, 0);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
void vpe20_plane_desc_writer_add_hist_destination(struct plane_desc_writer *writer,
void *p_destination, uint32_t hist_idx, uint8_t hist_dsets_array[])
{
uint32_t* cmd_space, * cmd_start;
uint32_t num_wd = (hist_idx == 0) ? 3 : 2;
uint64_t size = num_wd * sizeof(uint32_t);
struct vpe20_plane_desc_dst *dst = (struct vpe20_plane_desc_dst *)p_destination;
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_start = cmd_space = (uint32_t*)(uintptr_t)writer->buf->cpu_va;
if (hist_idx == 0) {
*cmd_space++ = 2; // Number of bytes of each data set 2^(8+2) = 1024
} // equal to 256bins * 4bytes per bin
writer->num_dst++;
VPE_ASSERT(!(dst->base_addr_lo & 0xFF));
*cmd_space++ = dst->base_addr_lo;
*cmd_space++ = dst->base_addr_hi;
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,129 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_assert.h"
#include "common.h"
#include "reg_helper.h"
#include "vpe10_vpe_desc_writer.h"
#include "vpe20_vpe_desc_writer.h"
#include "vpe20_command.h"
void vpe20_construct_vpe_desc_writer(struct vpe_desc_writer *writer)
{
writer->init = vpe20_vpe_desc_writer_init;
writer->add_plane_desc = vpe20_vpe_desc_writer_add_plane_desc;
writer->add_config_desc = vpe20_vpe_desc_writer_add_config_desc;
writer->complete = vpe10_vpe_desc_writer_complete;
}
enum vpe_status vpe20_vpe_desc_writer_init(
struct vpe_desc_writer *writer, struct vpe_buf *buf, int cd)
{
uint32_t *cmd_space;
uint64_t size = sizeof(uint32_t);
writer->base_cpu_va = buf->cpu_va;
writer->base_gpu_va = buf->gpu_va;
writer->buf = buf;
writer->num_config_desc = 0;
writer->plane_desc_added = false;
writer->status = VPE_STATUS_OK;
if (buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return writer->status;
}
if (writer->status == VPE_STATUS_OK) {
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = VPE_DESC_CMD_HEADER(cd);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
return writer->status;
}
void vpe20_vpe_desc_writer_add_plane_desc(
struct vpe_desc_writer *writer, uint64_t plane_desc_addr, uint8_t tmz)
{
uint32_t *cmd_space;
uint64_t size = 3 * sizeof(uint32_t);
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
VPE_ASSERT(!(plane_desc_addr & 0x3f));
VPE_ASSERT(!writer->plane_desc_added);
*cmd_space++ = (ADDR_LO(plane_desc_addr) | (unsigned)(tmz & 0xf));
*cmd_space++ = ADDR_HI(plane_desc_addr);
// skip the DW3 as well, which is finalized during complete
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
writer->plane_desc_added = true;
}
void vpe20_vpe_desc_writer_add_config_desc(
struct vpe_desc_writer* writer, uint64_t config_desc_addr, bool reuse, uint8_t tmz)
{
uint32_t* cmd_space;
uint64_t size = 2 * sizeof(uint32_t);
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t*)(uintptr_t)writer->buf->cpu_va;
VPE_ASSERT(!(config_desc_addr & 0x3f));
*cmd_space++ = (ADDR_LO(config_desc_addr) | ((unsigned)reuse << 5) | (unsigned)(tmz & 0xf));
*cmd_space++ = ADDR_HI(config_desc_addr);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
writer->num_config_desc++;
}

View file

@ -36,6 +36,13 @@ static void convert_3dlut_to_tetrahedral_params(
int num_values;
switch (params->lut_dim) {
case LUT_DIM_33:
lut0 = params->tetrahedral_33.lut0;
lut1 = params->tetrahedral_33.lut1;
lut2 = params->tetrahedral_33.lut2;
lut3 = params->tetrahedral_33.lut3;
num_values = LUT3D_SIZE_33x33x33;
break;
case LUT_DIM_9:
lut0 = params->tetrahedral_9.lut0;
lut1 = params->tetrahedral_9.lut1;
@ -102,6 +109,10 @@ bool vpe_convert_to_tetrahedral(
params->lut_3d.lut_dim = LUT_DIM_17;
effective_lut_dim = 17;
break;
case 33:
params->lut_3d.lut_dim = LUT_DIM_33;
effective_lut_dim = 33;
break;
default:
params->lut_3d.lut_dim = LUT_DIM_INVALID;
VPE_ASSERT(false);

View file

@ -41,6 +41,11 @@ void vpe_create_bg_segments(
uint16_t dst_h_div = vpe_is_yuv420(vpe_priv->output_ctx.surface.format) ? 2 : 1;
uint16_t dst_v_div = vpe_is_yuv420(vpe_priv->output_ctx.surface.format) ? 2 : 1;
if (vpe_is_yuv422(stream_ctx->stream.surface_info.format))
src_h_div = 2;
if (vpe_is_yuv422(vpe_priv->output_ctx.surface.format))
dst_h_div = 2;
for (gap_index = 0; gap_index < gaps_cnt; gap_index++) {
/* format */
@ -62,6 +67,10 @@ void vpe_create_bg_segments(
scaler_data->ratios.horz_c = vpe_fixpt_from_fraction(1, 2);
scaler_data->ratios.vert_c = vpe_fixpt_from_fraction(1, 2);
}
else if (vpe_is_yuv422(scaler_data->format)) {
scaler_data->ratios.horz_c = vpe_fixpt_from_fraction(1, 2);
scaler_data->ratios.vert_c = vpe_fixpt_one;
}
else {
scaler_data->ratios.horz_c = vpe_fixpt_one;
scaler_data->ratios.vert_c = vpe_fixpt_one;

View file

@ -392,6 +392,24 @@ static bool build_scale_and_bias(struct bias_and_scale *bias_and_scale,
is_chroma_different = true;
} // else report error? not sure if default is right
}
else if (vpe_is_rgb16(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(65536, 65535);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(65536, 60160 - 4096);
bias = vpe_fixpt_from_fraction(-4096, 65536);
} // else report error? here just go with default (1.0, 0.0)
} else if (vpe_is_yuv12(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(65536, 65535);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(65536, 60160 - 4096);
bias = vpe_fixpt_from_fraction(-4096, 65536);
scale_c = vpe_fixpt_from_fraction(65536, 61440 - 4096);
bias_c = vpe_fixpt_from_fraction(-4096, 65536); // See notes in function comment
is_chroma_different = true;
}
}
if (!vpe_convert_to_custom_float_format(scale, &fmt, &bias_and_scale->scale_green)) {
VPE_ASSERT(0);
@ -597,6 +615,7 @@ enum vpe_status vpe_color_update_3dlut(
}
}
stream_ctx->lut3d_func->state.bits.initialized = 1;
stream_ctx->lut3d_func->state.bits.is_dma = 0;
}
stream_ctx->uid_3dlut = stream_ctx->stream.tm_params.UID;
@ -604,6 +623,41 @@ enum vpe_status vpe_color_update_3dlut(
return VPE_STATUS_OK;
}
// This only updates the matrix as provided in the 3DLUT compound case
// 3DLUT itself is updated elsewhere
static enum vpe_status vpe_color_update_3dlut_matrix(
struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx)
{
float *matrix_ptr = &stream_ctx->stream.lut_compound.pCscMatrix[0][0];
float max_coeff = matrix_ptr[0];
float max_allowed = 4.0f - 1.0f / 4096.0f; // max coeff allowed is 4.0 - smallest step
float renorm_factor = 1.0f;
struct fixed31_32 renorm_fixed[12];
// Find the maximum element in the 3x4 matrix (12 elements total)
for (int i = 0; i < 12; i++) {
if (matrix_ptr[i] > max_coeff) {
max_coeff = matrix_ptr[i];
}
}
if (max_coeff > max_allowed) {
renorm_factor = max_coeff / max_allowed;
}
stream_ctx->csc_renorm_factor.value = vpe_double_to_fixed_point(renorm_factor, 0, 32, true);
for (int i = 0; i < 12; i++) {
// renorm_factor is always >= 1.0f, so division is safe
renorm_fixed[i].value =
vpe_double_to_fixed_point(matrix_ptr[i] / renorm_factor, 0, 32, true);
}
conv_convert_float_matrix(&stream_ctx->input_cs->regval[0], renorm_fixed, 12);
return VPE_STATUS_OK;
}
enum vpe_status vpe_color_update_color_space_and_tf(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
@ -636,6 +690,12 @@ enum vpe_status vpe_color_update_color_space_and_tf(
stream_ctx->stream.tm_params.UID != 0 || stream_ctx->stream.tm_params.enable_3dlut;
bool require_update = stream_ctx->uid_3dlut != stream_ctx->stream.tm_params.UID;
if (stream_ctx->stream.lut_compound.enabled) {
// handle 3dlut compound case
vpe_color_update_3dlut_matrix(vpe_priv, stream_ctx);
continue; // skip the rest of color space and tf update
}
color_check_input_cm_update(vpe_priv, stream_ctx,
&stream_ctx->stream.surface_info.cs, &stream_ctx->stream.color_adj,
is_3dlut_enable, geometric_update);
@ -669,6 +729,8 @@ enum vpe_status vpe_color_update_color_space_and_tf(
}
if (stream_ctx->dirty_bits.color_space || output_ctx->dirty_bits.color_space) {
if (stream_ctx->stream_type == VPE_STREAM_TYPE_DESTINATION)
stream_ctx->cs = output_ctx->cs;
enum color_space shaper_in_cs;
bool can_bypass_gamut = geometric_scaling;
if (is_3dlut_enable) {
@ -765,6 +827,8 @@ enum vpe_status vpe_color_update_shaper(const struct vpe_priv *vpe_priv, uint16_
shaper_in.shaper_in_max = 1 << 16;
shaper_in.use_const_hdr_mult = false; // can not be true. Fix is required.
shaper_in.index_mode = vpe_get_shaper_index_mode(stream_ctx->lut3d_func->state.bits.is_dma,
stream_ctx->lut3d_func->lut_3d.lut_dim, stream_ctx->stream.tm_params.lut_container_dim);
ret = vpe_build_shaper(&shaper_in, shaper_func->tf, pq_norm_gain, &shaper_func->pwl);
@ -779,6 +843,95 @@ enum vpe_status vpe_color_update_shaper(const struct vpe_priv *vpe_priv, uint16_
return ret;
}
enum vpe_status vpe_color_setup_dma_lut(struct vpe_3dlut *lut3d_func, struct stream_ctx *stream_ctx)
{
lut3d_func->state.bits.is_dma = 1;
lut3d_func->lut_3d.use_12bits = true;
switch (stream_ctx->stream.tm_params.lut_type) {
case VPE_LUT_TYPE_GPU_1D_PACKED:
lut3d_func->dma_params.layout = VPE_3DLUT_MEM_LAYOUT_1D_PACKED_LINEAR;
lut3d_func->dma_params.addr_mode = VPE_3DLUT_SIMPLE_LINEAR;
break;
case VPE_LUT_TYPE_GPU_3D_SWIZZLE:
lut3d_func->dma_params.layout = VPE_3DLUT_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB;
lut3d_func->dma_params.addr_mode = VPE_3DLUT_SW_LINEAR;
break;
default:
lut3d_func->dma_params.layout = VPE_3DLUT_MEM_LAYOUT_DISABLE;
}
switch (stream_ctx->stream.tm_params.lut_dim) {
case 9:
lut3d_func->lut_3d.lut_dim = LUT_DIM_9;
break;
case 17:
lut3d_func->lut_3d.lut_dim = LUT_DIM_17;
break;
case 33:
lut3d_func->lut_3d.lut_dim = LUT_DIM_33;
break;
default:
lut3d_func->lut_3d.lut_dim = LUT_DIM_INVALID;
VPE_ASSERT(false);
return VPE_STATUS_BAD_TONE_MAP_PARAMS;
}
switch (stream_ctx->stream.dma_info.lut3d.format) {
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_0_15;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_0_15;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_48_63;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_48_63;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_0_15;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12MSB;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_0_15;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12MSB;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_48_63;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12MSB;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616:
default:
lut3d_func->dma_params.crossbar_b = VPE_3DLUT_CROSSBAR_BIT_SLICE_48_63;
lut3d_func->dma_params.crossbar_g = VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47;
lut3d_func->dma_params.crossbar_r = VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31;
lut3d_func->dma_params.format = VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12MSB;
break;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_calculate_shaper(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx)
{
struct vpe_color_space cs;
@ -856,16 +1009,28 @@ enum vpe_status vpe_color_update_movable_cm(
goto exit;
}
}
// Get the normalization factor for the shaper based on tone mapping parameters.
get_shaper_norm_factor(&stream_ctx->stream.tm_params, stream_ctx, &shaper_norm_factor);
if (stream_ctx->stream.lut_compound.enabled) {
stream_ctx->lut3d_func->hdr_multiplier = stream_ctx->csc_renorm_factor;
} else {
// Get the normalization factor for the shaper based on tone mapping parameters.
get_shaper_norm_factor(
&stream_ctx->stream.tm_params, stream_ctx, &shaper_norm_factor);
// Update the HDR multiplier based on the shaper normalization factor and other
// parameters.
vpe_color_tm_update_hdr_mult(shaper_norm_factor,
&stream_ctx->lut3d_func->hdr_multiplier, enable_3dlut,
stream_ctx->stream.surface_info.cs.tf == VPE_TF_G10);
// Update the HDR multiplier based on the shaper normalization factor and other
// parameters.
vpe_color_tm_update_hdr_mult(shaper_norm_factor,
&stream_ctx->lut3d_func->hdr_multiplier, enable_3dlut,
stream_ctx->stream.surface_info.cs.tf == VPE_TF_G10);
}
vpe_color_update_3dlut(vpe_priv, stream_ctx, enable_3dlut);
// Set up 3DLUT before Shaper to determine indexing mode
if (stream_ctx->stream.tm_params.lut_type > VPE_LUT_TYPE_CPU) {
/* FastLoading */
vpe_color_setup_dma_lut(stream_ctx->lut3d_func, stream_ctx);
} else {
/* DirectConfig loading case */
vpe_color_update_3dlut(vpe_priv, stream_ctx, enable_3dlut);
}
vpe_priv->resource.calculate_shaper(vpe_priv, stream_ctx);
@ -876,7 +1041,6 @@ enum vpe_status vpe_color_update_movable_cm(
vpe_color_update_gamut(vpe_priv, out_lut_cs, vpe_priv->output_ctx.cs,
output_ctx->gamut_remap, !enable_3dlut);
vpe_color_update_3dlut(vpe_priv, stream_ctx, enable_3dlut);
}
}
exit:

View file

@ -524,3 +524,318 @@ void vpe_inverse_output_csc(enum color_space output_cs, struct vpe_color *bg_col
vpe_bg_csc(bg_color, bgcolor_cs);
}
struct format_range_csc_table {
enum color_space cs;
enum color_range_type range;
bool bg_color_is_yuv;
float val[12];
};
// Used to invert OCSC and convert into pipeline RGB for MPC bg programming
static const struct format_range_csc_table bgcolor_format_range_inversion[] = {
// RGB BG Color, RGB output
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_8BPC, false,
{1.16438356164384f, 0, 0, -0.0730593607305936f, 0, 1.16438356164384f, 0,
-0.0730593607305936f, 0, 0, 1.16438356164384f, -0.0730593607305936f}},
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_10BPC, false,
{1.167808219178082f, 0, 0, -0.073059360730594f, 0, 1.167808219178082f, 0,
-0.073059360730594f, 0, 0, 1.167808219178082f, -0.073059360730594f}},
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_16BPC, false,
{1.168931934931507f, 0, 0, -0.073059360730594f, 0, 1.168931934931507f, 0,
-0.073059360730594f, 0, 0, 1.168931934931507f, -0.073059360730594f}},
// RGB BG Color, YUV output
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_8BPC, false,
{1.14616407778763f, 0.0152565435443742f, 0.00296294031182745f, -0.0761888250163078f,
0.00777122064477659f, 1.15364940068723f, 0.00296294031182746f, -0.0706971451680937f,
0.00777122064477664f, 0.0152565435443742f, 1.14135579745468f, -0.0770147178734506f}},
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_10BPC, false,
{1.14953514860466f, 0.0153014157312695f, 0.00297165484215636f, -0.0738417268020222f,
0.00779407717608477f, 1.15704248715984f, 0.00297165484215636f, -0.0724688068399686f,
0.00779407717608482f, 0.0153014157312695f, 1.14471272627073f, -0.0740482000163079f}},
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_16BPC, false,
{1.16893193493151f, 0.0f, 0.0f, -0.0570672980878996f, 0.0f, 1.16893193493151f, 0.0f,
-0.0851306597780037f, 0.0f, 0.0f, 1.16893193493151f, -0.0528468535958906f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_8BPC, false,
{1.14391848092026f, 0.0185885518580174f, 0.00187652886555610f, -0.0765745393020221f,
0.00552562377740495f, 1.15698140900087f, 0.00187652886555609f, -0.0715963059404152f,
0.00552562377740481f, 0.0185885518580174f, 1.14026938600841f, -0.0772013250163077f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_10BPC, false,
{1.14728294704062f, 0.0186432240693645f, 0.00188204806810185f, -0.0739381553734507f,
0.00554187561204439f, 1.16038429549794f, 0.00188204806810185f, -0.0726935970330490f,
0.00554187561204425f, 0.0186432240693646f, 1.14362311949667f, -0.0740948518020221f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_16BPC, false,
{1.16893193493151f, 0.0f, 0.0f, -0.0550962364440639f, 0.0f, 1.16893193493151f, 0.0f,
-0.0805358045299480f, 0.0f, 0.0f, 1.16893193493151f, -0.0518932612728311f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_8BPC, false,
{1.14522061521626f, 0.0176216976494039f, 0.00154124877817476f, -0.0763508785877364f,
0.00682775807339991f, 1.15601455479226f, 0.00154124877817475f, -0.0714167128422008f,
0.00682775807339991f, 0.0176216976494038f, 1.13993410592103f, -0.0772589143020221f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_10BPC, false,
{1.14858891114336f, 0.0176735261719021f, 0.00154578186281643f, -0.0738822401948792f,
0.00684783971479236f, 1.15941459760047f, 0.00154578186281642f, -0.0726486987584954f,
0.00684783971479225f, 0.0176735261719021f, 1.14328685329139f, -0.0741092491234507f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_16BPC, false,
{1.16893193493151f, 0.0f, 0.0f, -0.0562391784389270f, 0.0f, 1.16893193493151f, 0.0f,
-0.0814535539639162f, 0.0f, 0.0f, 1.16893193493151f, -0.0515989708190638f}},
// YUV BG Color, YUV output
{COLOR_SPACE_YCBCR601, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.4020f, -0.7010f, 1.0f, -0.3441362860f, -0.7141362860f, 0.5291362860f, 1.0f,
1.7720f, 0, -0.8860f}},
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.59602678571429f, -0.874202217873451f, 1.16438356164384f,
-0.391762289866072f, -0.812967647008929f, 0.531667823269406f, 1.16438356164384f,
2.01723214285714f, 0, -1.08563078930202f}},
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.60072098214286f, -0.874202217873451f, 1.16780821917808f,
-0.392914531895089f, -0.815358728323661f, 0.531667823269406f, 1.16780821917808f,
2.02316517857143f, 0, -1.08563078930202f}},
{COLOR_SPACE_YCBCR601_LIMITED, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.63884257277397f, -0.876488584474886f, 1.16893193493151f,
-0.402271894674122f, -0.834776710598780f, 0.533393642858448f, 1.16893193493151f,
2.07134738869863f, 0, -1.08852054794521f}},
{COLOR_SPACE_YCBCR709, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.57480f, -0.78740f, 1.0f, -0.1873242730f, -0.4681242730f, 0.3277242730f, 1.0f,
1.85560f, 0, -0.92780f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.79274107142857f, -0.972945075016308f, 1.16438356164384f,
-0.213248614352679f, -0.532909328638393f, 0.301482665555121f, 1.16438356164384f,
2.11240178571429f, 0, -1.13340221787345f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.79801383928571f, -0.972945075016308f, 1.16780821917808f,
-0.213875816159598f, -0.534476709016741f, 0.301482665555121f, 1.16780821917808f,
2.11861473214286f, 0, -1.13340221787345f}},
{COLOR_SPACE_YCBCR709_LIMITED, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.84083401113014f, -0.975513242009132f, 1.16893193493151f,
-0.218969324897528f, -0.547205412226295f, 0.302551564031963f, 1.16893193493151f,
2.16907009845890f, 0, -1.13642831050228f}},
{COLOR_SPACE_2020_YCBCR, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.47460f, -0.73730f, 1.0f, -0.1645531270f, -0.5713531270f, 0.3679531270f, 1.0f,
1.88140f, 0, -0.94070f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.67867410714286f, -0.915687932159165f, 1.16438356164384f,
-0.187326104397321f, -0.650424318683036f, 0.347458498697978f, 1.16438356164384f,
2.14177232142857f, 0, -1.14814507501631f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.68361138392857f, -0.915687932159165f, 1.16780821917808f,
-0.187877063527902f, -0.652337331385045f, 0.347458498697978f, 1.16780821917808f,
2.14807165178571f, 0, -1.14814507501631f}},
{COLOR_SPACE_2020_YCBCR_LIMITED, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.723707031250f, -0.918092694063927f, 1.16893193493151f,
-0.192351405143140f, -0.667872916273277f, 0.348658606744292f, 1.16893193493151f,
2.19922854238014f, 0, -1.15121324200913f}},
// YUV BG Colorf, RGB output
{COLOR_SPACE_RGB601, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.4020f, -0.7010f, 1.0f, -0.3441362860f, -0.7141362860f, 0.5291362860f, 1.0f,
1.7720f, 0, -0.8860f}},
{COLOR_SPACE_RGB601_LIMITED, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.63246575342466f, -0.889292237442922f, 1.16438356164384f,
-0.400706634383562f, -0.831528552191781f, 0.543058232557078f, 1.16438356164384f,
2.06328767123288f, 0, -1.10470319634703f}},
{COLOR_SPACE_RGB601_LIMITED, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.63726712328767f, -0.891692922374429f, 1.16780821917808f,
-0.401885183308219f, -0.833974224404110f, 0.544870343125571f, 1.16780821917808f,
2.06935616438356f, 0, -1.10773744292237f}},
{COLOR_SPACE_RGB601_LIMITED, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.63884257277397f, -0.892480647117580f, 1.16893193493151f,
-0.402271894674122f, -0.834776710598780f, 0.545464941905858f, 1.16893193493151f,
2.07134738869863f, 0, -1.10873305507991f}},
{COLOR_SPACE_SRGB, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.57480f, -0.78740f, 1.0f, -0.1873242730f, -0.4681242730f, 0.3277242730f, 1.0f,
1.85560f, 0, -0.92780f}},
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.83367123287671f, -0.989894977168950f, 1.16438356164384f,
-0.218117304178082f, -0.545076208287671f, 0.308537395502283f, 1.16438356164384f,
2.16063013698630f, 0, -1.15337442922374f}},
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.83906438356164f, -0.992591552511415f, 1.16780821917808f,
-0.218758825660959f, -0.546679373606164f, 0.309659738902968f, 1.16780821917808f,
2.16698493150685f, 0, -1.15655182648402f}},
{COLOR_SPACE_SRGB_LIMITED, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.84083401113014f, -0.993476366295662f, 1.16893193493151f,
-0.218969324897528f, -0.547205412226295f, 0.310028007831318f, 1.16893193493151f,
2.16907009845890f, 0, -1.15759440996005f}},
{COLOR_SPACE_2020_RGB_FULLRANGE, COLOR_RANGE_FULL, true,
{1.0f, 0, 1.47460f, -0.73730f, 1.0f, -0.1645531270f, -0.5713531270f, 0.3679531270f, 1.0f,
1.88140f, 0, -0.94070f}},
{COLOR_SPACE_2020_RGB_LIMITEDRANGE, COLOR_RANGE_LIMITED_8BPC, true,
{1.16438356164384f, 0, 1.7170f, -0.931559360730594f, 1.16438356164384f, -0.191602956095890f,
-0.665274188972603f, 0.355379211803653f, 1.16438356164384f, 2.19067123287671f, 0,
-1.16839497716895f}},
{COLOR_SPACE_2020_RGB_LIMITEDRANGE, COLOR_RANGE_LIMITED_10BPC, true,
{1.16780821917808f, 0, 1.722050f, -0.934084360730593f, 1.16780821917808f,
-0.192166494202055f, -0.667230877763699f, 0.356639325252283f, 1.16780821917808f,
2.19711438356164f, 0, -1.17161655251142f}},
{COLOR_SPACE_2020_RGB_LIMITEDRANGE, COLOR_RANGE_LIMITED_16BPC, true,
{1.16893193493151f, 0, 1.723707031250f, -0.934912876355594f, 1.16893193493151f,
-0.192351405143140f, -0.667872916273277f, 0.357052799977615f, 1.16893193493151f,
2.19922854238014f, 0, -1.17267363192066f}}};
// Used to convert bg into output cs for OPP programming (so always in full range)
static const struct format_range_csc_table bgcolor_color_space_table[] = {
// RGB BG Color, YUV output
{COLOR_SPACE_YCBCR601, COLOR_RANGE_FULL, false,
{0.500000000027881f, -0.418687589221465f, -0.0813124108064158f, 0.5f, 0.298999999960911f,
0.587000000088494f, 0.113999999950595f, 0.0f, -0.168735891625796f, -0.331264108402085f,
0.500000000027881f, 0.5f}},
{COLOR_SPACE_YCBCR709, COLOR_RANGE_FULL, false,
{0.499999999987861f, -0.454152908279373f, -0.0458470917084874f, 0.5f, 0.212600000019117f,
0.715199999958357f, 0.0722000000225260f, 0.0f, -0.114572106067642f, -0.385427893920218f,
0.499999999987861f, 0.5f}},
{COLOR_SPACE_2020_YCBCR, COLOR_RANGE_FULL, false,
{0.499999999974095f, -0.459785704538901f, -0.0402142954351941f, 0.5f, 0.262700000038199f,
0.677999999913064f, 0.0593000000487373f, 0.0f, -0.139630062739555f, -0.360369937234540f,
0.499999999974095f, 0.5f}},
// YUV BG Color, RGB output
{COLOR_SPACE_RGB601, COLOR_RANGE_FULL, true,
{1.0f, 0.0f, 1.40200000000000f, -0.701000000000000f, 1.0f, -0.344136286000000f,
-0.714136286000000f, 0.529136286000000f, 1.0f, 1.77200000000000f, 0.0f,
-0.886000000000000f}},
{COLOR_SPACE_SRGB, COLOR_RANGE_FULL, true,
{1.0f, 0.0f, 1.57480000000000f, -0.787400000000000f, 1.0f, -0.187324273000000f,
-0.468124273000000f, 0.327724273000000f, 1.0f, 1.85560000000000f, 0.0f,
-0.927800000000000f}},
{COLOR_SPACE_2020_RGB_FULLRANGE, COLOR_RANGE_FULL, true,
{1.0f, 0.0f, 1.47460000000000f, -0.737300000000000f, 1.0f, -0.164553127000000f,
-0.571353127000000f, 0.367953127000000f, 1.0f, 1.88140000000000f, 0.0f,
-0.940700000000000f}}};
bool vpe_is_yuv_cs(enum color_space cs)
{
switch (cs) {
// output is ycbr cs, follow output's setting
case COLOR_SPACE_YCBCR601:
case COLOR_SPACE_YCBCR709:
case COLOR_SPACE_YCBCR601_LIMITED:
case COLOR_SPACE_YCBCR709_LIMITED:
case COLOR_SPACE_2020_YCBCR:
case COLOR_SPACE_2020_YCBCR_LIMITED:
return true;
default:
return false;
}
}
void vpe_bg_format_and_limited_conversion(enum color_space output_cs,
enum vpe_surface_pixel_format pixel_format, struct vpe_color *bg_color)
{
// for limited YUV output, OCSC does studio conversion. Need to calculate RGB value that will
// convert to full range YUV out, after OCSC full-> studio conversion
enum color_range_type range = vpe_get_range_type(output_cs, pixel_format);
enum color_space cs = output_cs;
if (!vpe_is_yuv_cs(output_cs) && !bg_color->is_ycbcr)
// if RGB BG->RGB out we do not care about which chromaticity to use as in-pipe RGB is
// typeless
cs = COLOR_SPACE_SRGB_LIMITED;
else
// map certain color spaces to their matching one in the matrix array
switch (cs) {
case COLOR_SPACE_MSREF_SCRGB:
cs = COLOR_SPACE_SRGB;
break;
case COLOR_SPACE_YCBCR_JFIF:
cs = COLOR_SPACE_YCBCR601;
break;
case COLOR_SPACE_RGB_JFIF:
cs = COLOR_SPACE_RGB601;
break;
default:
break;
}
int i;
int arr_size = 12;
for (i = 0; i < arr_size; i++)
if (bgcolor_format_range_inversion[i].cs == cs &&
bgcolor_format_range_inversion[i].range == range &&
bgcolor_format_range_inversion[i].bg_color_is_yuv == bg_color->is_ycbcr) {
const float *m = bgcolor_format_range_inversion[i].val;
if (bg_color->is_ycbcr) {
struct vpe_color_ycbcra ycbcra = bg_color->ycbcra;
bg_color->rgba.r = ycbcra.y * m[0] + ycbcra.cb * m[1] + ycbcra.cr * m[2] + m[3];
bg_color->rgba.g = ycbcra.y * m[4] + ycbcra.cb * m[5] + ycbcra.cr * m[6] + m[7];
bg_color->rgba.b = ycbcra.y * m[8] + ycbcra.cb * m[9] + ycbcra.cr * m[10] + m[11];
} else {
struct vpe_color_rgba rgba = bg_color->rgba;
bg_color->rgba.r = rgba.r * m[0] + rgba.g * m[1] + rgba.b * m[2] + m[3];
bg_color->rgba.g = rgba.r * m[4] + rgba.g * m[5] + rgba.b * m[6] + m[7];
bg_color->rgba.b = rgba.r * m[8] + rgba.g * m[9] + rgba.b * m[10] + m[11];
}
break;
}
}
void vpe_bg_color_space_conversion(enum color_space output_cs, struct vpe_color *bg_color)
{
enum color_space cs = output_cs;
// map certain color spaces to their matching one in the matrix array
switch (cs) {
case COLOR_SPACE_RGB601:
case COLOR_SPACE_RGB601_LIMITED:
case COLOR_SPACE_RGB_JFIF:
cs = COLOR_SPACE_RGB601;
break;
case COLOR_SPACE_SRGB:
case COLOR_SPACE_SRGB_LIMITED:
case COLOR_SPACE_MSREF_SCRGB:
cs = COLOR_SPACE_SRGB;
break;
case COLOR_SPACE_2020_RGB_FULLRANGE:
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
cs = COLOR_SPACE_2020_RGB_FULLRANGE;
break;
case COLOR_SPACE_YCBCR601_LIMITED:
case COLOR_SPACE_YCBCR_JFIF:
case COLOR_SPACE_YCBCR601:
cs = COLOR_SPACE_YCBCR601;
break;
case COLOR_SPACE_YCBCR709_LIMITED:
case COLOR_SPACE_YCBCR709:
cs = COLOR_SPACE_YCBCR709;
break;
case COLOR_SPACE_2020_YCBCR:
case COLOR_SPACE_2020_YCBCR_LIMITED:
cs = COLOR_SPACE_2020_YCBCR;
break;
default:
break;
}
int i;
int arr_size = 6;
for (i = 0; i < arr_size; i++)
if (bgcolor_color_space_table[i].cs == cs &&
bgcolor_color_space_table[i].bg_color_is_yuv == bg_color->is_ycbcr) {
const float *m = bgcolor_color_space_table[i].val;
if (vpe_is_yuv_cs(cs)) {
struct vpe_color_rgba rgba = bg_color->rgba;
bg_color->ycbcra.cr = rgba.r * m[0] + rgba.g * m[1] + rgba.b * m[2] + m[3];
bg_color->ycbcra.y = rgba.r * m[4] + rgba.g * m[5] + rgba.b * m[6] + m[7];
bg_color->ycbcra.cb = rgba.r * m[8] + rgba.g * m[9] + rgba.b * m[10] + m[11];
bg_color->is_ycbcr = true;
} else {
struct vpe_color_ycbcra ycbcra = bg_color->ycbcra;
bg_color->rgba.r = ycbcra.y * m[0] + ycbcra.cb * m[1] + ycbcra.cr * m[2] + m[3];
bg_color->rgba.g = ycbcra.y * m[4] + ycbcra.cb * m[5] + ycbcra.cr * m[6] + m[7];
bg_color->rgba.b = ycbcra.y * m[8] + ycbcra.cb * m[9] + ycbcra.cr * m[10] + m[11];
bg_color->is_ycbcr = false;
}
break;
}
}

View file

@ -53,6 +53,14 @@ bool vpe_is_dual_plane_format(enum vpe_surface_pixel_format format)
// p010
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb: /* P016 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb: /* YUV 422 */
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
return true;
default:
return false;
@ -83,15 +91,23 @@ bool vpe_is_32bit_packed_rgb(enum vpe_surface_pixel_format format)
bool vpe_is_8bit(enum vpe_surface_pixel_format format) {
return vpe_is_rgb8(format) ||
vpe_is_yuv420_8(format) ||
vpe_is_yuv422_8(format) ||
(format == VPE_SURFACE_PIXEL_FORMAT_GRPH_R8) ||
vpe_is_yuv444_8(format);
}
bool vpe_is_10bit(enum vpe_surface_pixel_format format) {
return vpe_is_rgb10(format) ||
vpe_is_yuv420_10(format) ||
vpe_is_yuv422_10(format) ||
vpe_is_yuv444_10(format);
}
bool vpe_is_16bit(enum vpe_surface_pixel_format format)
{
return vpe_is_fp16(format) || vpe_is_rgb16(format) ||
(format == VPE_SURFACE_PIXEL_FORMAT_GRPH_R16);
}
bool vpe_is_rgb8(enum vpe_surface_pixel_format format)
{
switch (format) {
@ -103,6 +119,7 @@ bool vpe_is_rgb8(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
return true;
default:
return false;
@ -121,6 +138,28 @@ bool vpe_is_rgb10(enum vpe_surface_pixel_format format)
return false;
}
}
bool vpe_is_rgb16(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
return true;
default:
return false;
}
}
bool vpe_is_planar_format(enum vpe_surface_pixel_format format)
{
return (format >= VPE_SURFACE_PIXEL_FORMAT_PLANAR_BEGIN) &&
(format <= VPE_SURFACE_PIXEL_FORMAT_PLANAR_END);
}
bool vpe_is_fp16(enum vpe_surface_pixel_format format)
{
@ -129,6 +168,7 @@ bool vpe_is_fp16(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
return true;
default:
return false;
@ -140,6 +180,7 @@ bool vpe_is_yuv420_8(enum vpe_surface_pixel_format format)
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
return true;
default:
return false;
@ -175,11 +216,13 @@ bool vpe_is_yuv420(enum vpe_surface_pixel_format format)
bool vpe_is_yuv444_8(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
return true;
default:
return false;
@ -196,36 +239,157 @@ bool vpe_is_yuv444_10(enum vpe_surface_pixel_format format)
return false;
}
}
bool vpe_is_yuv444_12(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
return true;
default:
return false;
}
}
bool vpe_is_yuv444(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv444_8(format) ||
vpe_is_yuv444_12(format) ||
vpe_is_yuv444_10(format));
}
bool vpe_is_yuv422_8(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
return true;
default:
return false;
}
}
bool vpe_is_yuv422_10(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
return true;
default:
return false;
}
}
bool vpe_is_yuv422_12(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
return true;
default:
return false;
}
}
bool vpe_is_yuv422(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv422_8(format) || vpe_is_yuv422_10(format) || vpe_is_yuv422_12(format));
}
bool vpe_is_yuv_packed(enum vpe_surface_pixel_format format)
{
switch (format) {
// YUV 422 Packed
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
// YUV 444 Packed
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
return true;
default:
return false;
}
}
bool vpe_is_mono(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
return true;
default:
return false;
}
}
bool vpe_is_yuv8(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv420_8(format) ||
vpe_is_yuv422_8(format) ||
vpe_is_yuv444_8(format));
}
bool vpe_is_yuv10(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv420_10(format) ||
vpe_is_yuv422_10(format) ||
vpe_is_yuv444_10(format));
}
bool vpe_is_yuv12(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv420_16(format)
|| vpe_is_yuv422_12(format) || vpe_is_yuv444_12(format)
);
}
bool vpe_is_yuv(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv420(format) ||
vpe_is_yuv8(format) || vpe_is_yuv422(format) ||
vpe_is_yuv444(format));
}
uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int plane_idx)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
return 1;
// nv12/21
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
if (plane_idx == 0)
return 1;
else
@ -233,16 +397,56 @@ uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int
// P010
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
// P016
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
// P210
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
// P216
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
if (plane_idx == 0)
return 2;
else
return 4;
// YUY2/UYUV
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
return 4;
// 16b Monochrome
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
return 2;
// Y210/Y216
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
return 8;
break;
// 64bpp
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
return 8;
default:
break;
@ -268,6 +472,17 @@ enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
@ -281,15 +496,46 @@ enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
c_depth = COLOR_DEPTH_101010;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
c_depth = COLOR_DEPTH_121212;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
// RGBE is technically 9bpc per component + 5 shared, using 16 here instead of default 8
// c_depth only used in OPP/backend for clamping etc, rgbe is input only so no impact
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
c_depth = COLOR_DEPTH_161616;
break;
default:
@ -325,6 +571,11 @@ bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
alpha = true;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
@ -337,6 +588,31 @@ bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
@ -516,6 +792,23 @@ enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream
return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
}
}
} else if (surface_info->address.type == VPE_PLN_ADDR_TYPE_PLANAR) {
uint32_t addr_check = 0;
uint32_t caps_alignment = vpe->caps->plane_caps.addr_alignment;
addrloc = &surface_info->address.planar.y_g_addr;
addr_check |= (addrloc->u.low_part % caps_alignment);
addrloc = &surface_info->address.planar.cb_b_addr;
addr_check |= (addrloc->u.low_part % caps_alignment);
addrloc = &surface_info->address.planar.cr_r_addr;
addr_check |= (addrloc->u.low_part % caps_alignment);
if (addr_check) {
vpe_log("failed. addr not aligned to 256 bytes\n");
return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
}
} else {
addrloc = &surface_info->address.grph.addr;
if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
@ -532,6 +825,8 @@ enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream
params.format = surface_info->format;
params.swizzle_mode = surface_info->swizzle;
params.scan = vpe_get_scan_direction(
stream->rotation, stream->horizontal_mirror, stream->vertical_mirror);
support = vpe_priv->pub.check_funcs.get_dcc_compression_input_cap(&params, &cap);
//only support non dual plane formats
if (!support) {
@ -626,9 +921,58 @@ enum vpe_status vpe_check_tone_map_support(
}
}
if (is_3D_lut_enabled && stream->tm_params.lut_dim != LUT_DIM_9 &&
stream->tm_params.lut_dim != LUT_DIM_17) { /* only support 9/17 cube */
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
if (is_3D_lut_enabled) {
/* check for 3D LUT dimension support */
switch (stream->tm_params.lut_dim) {
case LUT_DIM_9:
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.data_dim_9)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
case LUT_DIM_17:
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.data_dim_17)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
case LUT_DIM_33:
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.data_dim_33)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
default:
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
}
if (stream->tm_params.lut_type > VPE_LUT_TYPE_CPU) { /* fast loading */
if (!vpe->caps->color_caps.mpc.dma_3d_lut || /* check capability support */
((stream->dma_info.lut3d.data & 0xFF) != 0)) { /* must be 256 byte aligned */
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
} else if (!(vpe_is_rgb16(stream->dma_info.lut3d.format) ||
vpe_is_fp16(stream->dma_info.lut3d
.format))) { /* check for 3D LUT format support */
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
} else {
// Check if the 3D LUT container dimension is supported for fast loading
switch (stream->tm_params.lut_container_dim) {
case LUT_DIM_INVALID:
// unitialized lut_container_dim will be treated as 33 dimension
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.dma_dim_33)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
case LUT_DIM_17:
// Verify if 17x17x17 LUT dimension is supported for fast loading
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.dma_dim_17)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
case LUT_DIM_33:
// Verify if 33x33x33 LUT dimension is supported for fast loading
if (!vpe->caps->color_caps.mpc.lut_caps.lut_3dlut_caps.dma_dim_33)
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
break;
default:
// Unsupported LUT container dimension
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
}
}
}
}
return status;
}
@ -665,3 +1009,136 @@ uint32_t vpe_align_seg(uint32_t seg_size, uint32_t alignment)
return aligned_size;
}
enum vpe_scan_direction vpe_get_scan_direction(
enum vpe_rotation_angle rotation, bool horizontal_mirror, bool vertical_mirror)
{
enum vpe_scan_direction scan = VPE_SCAN_PATTERN_0_DEGREE;
switch (rotation) {
case VPE_ROTATION_ANGLE_0:
if (!horizontal_mirror && !vertical_mirror) {
scan = VPE_SCAN_PATTERN_0_DEGREE;
} else if (horizontal_mirror && vertical_mirror) {
scan = VPE_SCAN_PATTERN_180_DEGREE;
} else if (horizontal_mirror) {
scan = VPE_SCAN_PATTERN_0_DEGREE_H_MIRROR;
} else {
scan = VPE_SCAN_PATTERN_180_DEGREE_H_MIRROR;
}
break;
case VPE_ROTATION_ANGLE_90:
if (!horizontal_mirror && !vertical_mirror) {
scan = VPE_SCAN_PATTERN_90_DEGREE;
} else if (horizontal_mirror && vertical_mirror) {
scan = VPE_SCAN_PATTERN_270_DEGREE;
} else if (horizontal_mirror) {
scan = VPE_SCAN_PATTERN_270_DEGREE_V_MIRROR;
} else {
scan = VPE_SCAN_PATTERN_90_DEGREE_V_MIRROR;
}
break;
case VPE_ROTATION_ANGLE_180:
if (!horizontal_mirror && !vertical_mirror) {
scan = VPE_SCAN_PATTERN_180_DEGREE;
} else if (horizontal_mirror && vertical_mirror) {
scan = VPE_SCAN_PATTERN_0_DEGREE;
} else if (horizontal_mirror) {
scan = VPE_SCAN_PATTERN_180_DEGREE_H_MIRROR;
} else {
scan = VPE_SCAN_PATTERN_0_DEGREE_H_MIRROR;
}
break;
case VPE_ROTATION_ANGLE_270:
if (!horizontal_mirror && !vertical_mirror) {
scan = VPE_SCAN_PATTERN_270_DEGREE;
} else if (horizontal_mirror && vertical_mirror) {
scan = VPE_SCAN_PATTERN_90_DEGREE;
} else if (horizontal_mirror) {
scan = VPE_SCAN_PATTERN_90_DEGREE_V_MIRROR;
} else {
scan = VPE_SCAN_PATTERN_270_DEGREE_V_MIRROR;
}
break;
default:
scan = VPE_SCAN_PATTERN_0_DEGREE;
break;
}
return scan;
}
bool vpe_supported_linear_scan_pattern(enum vpe_scan_direction scan_dir)
{
switch (scan_dir) {
case VPE_SCAN_PATTERN_90_DEGREE:
case VPE_SCAN_PATTERN_270_DEGREE:
case VPE_SCAN_PATTERN_90_DEGREE_V_MIRROR:
case VPE_SCAN_PATTERN_270_DEGREE_V_MIRROR:
return false;
case VPE_SCAN_PATTERN_0_DEGREE:
case VPE_SCAN_PATTERN_180_DEGREE:
case VPE_SCAN_PATTERN_0_DEGREE_H_MIRROR:
case VPE_SCAN_PATTERN_180_DEGREE_H_MIRROR:
return true;
default:
return false;
}
}
bool vpe_validate_hist_collection(struct vpe_stream *stream)
{
uint16_t histIndex = 0;
uint16_t valid_hist[hist_max_channel];
uint16_t hist_src = 0;
memset(valid_hist, 0, sizeof(uint16_t) * hist_max_channel);
for (histIndex = 0; histIndex < hist_max_channel; histIndex++) {
if (stream->hist_params.hist_collection_param[histIndex].hist_types != VPE_HISTOGRAM_NONE) {
for (hist_src = 0; hist_src < hist_max_channel; hist_src++) {
if ( (stream->hist_params.hist_collection_param[histIndex].hist_types == channel_hist_allowed_mode[hist_src][0]) ||
(stream->hist_params.hist_collection_param[histIndex].hist_types == channel_hist_allowed_mode[hist_src][1])) {
valid_hist[hist_src]++;
if (valid_hist[hist_src] > 1) {
// two selected histograms set to the same source
return false;
}
}
}
if ( (histIndex > 0) &&
(stream->hist_params.hist_collection_param[histIndex - 1].hist_types == VPE_HISTOGRAM_NONE)) {
return false; // the sequence of histogram cannot be "none, valid" or "valid, none, valid"
} // needs to be "valid, none, none" or "valid, valid, none" or valid all 3
}
}
return true;
}
enum vpe_status vpe_check_3dlut_compound(
struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param)
{
struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
// not enabled, nothing to check, always ok
if (stream->lut_compound.enabled == false)
return VPE_STATUS_OK;
// no func ptr means no support at all, so cannot be enabled
if (!vpe_priv->resource.check_lut3d_compound)
return VPE_STATUS_LUT_COMPOUND_NOT_SUPPORTED;
return vpe_priv->resource.check_lut3d_compound(stream, param);
}
enum vpe_status vpe_check_histogram_support(struct vpe *vpe, const struct vpe_stream *stream)
{
enum vpe_status result = VPE_STATUS_OK;
// not enabled, nothing to check, always ok
if (stream->hist_params.hist_dsets == false)
return VPE_STATUS_OK;
if (!vpe->caps->histogram_support) {
result = VPE_STATUS_HISTOGRAM_NOT_SUPPORTED;
}
return result;
}

View file

@ -275,6 +275,23 @@ void config_writer_fill_indirect_destination(struct config_writer *writer,
config_writer_fill(writer, VPEC_FIELD_VALUE(VPE_IND_CFG_PKT_REGISTER_OFFSET, offset_data));
}
void config_writer_fill_3dlut_fl_addr(struct config_writer *writer, const uint64_t data_gpuva,
enum vpe_3dlut_addr_mode addr_mode, enum vpe_3dlut_mem_align mem_align, uint32_t size,
bool comp_mode, uint8_t tmz)
{
VPE_ASSERT(writer->type == CONFIG_TYPE_3DLUT_FL);
VPE_ASSERT(size > 0);
uint32_t tmp_code =
((comp_mode <<VPE_3DLUT_CFG_COMP_MODE__SHIFT) & VPE_3DLUT_CFG_COMP_MODE_MASK) | (tmz & 0xf);
uint32_t *cmd_space = (uint32_t *)(uintptr_t)writer->base_cpu_va;
*cmd_space = VPE_3DLUT_CFG_CMD_HEADER(addr_mode, mem_align); //---> this is DW0
config_writer_fill(writer, ADDR_LO(data_gpuva) | tmp_code); //----->This is DW1
config_writer_fill(writer, ADDR_HI(data_gpuva)); //---------------->This is DW2
config_writer_fill(writer, size - 1); //--------------------------->this is DW3
}
void config_writer_complete(struct config_writer *writer)
{
uint32_t *cmd_space = (uint32_t *)(uintptr_t)writer->base_cpu_va;
@ -298,7 +315,7 @@ void config_writer_complete(struct config_writer *writer)
// -4 for exclude header
// VPEP_DIRECT_CONFIG_ARRAY_SIZE is 1-based, hence need -1
*cmd_space = VPE_DIR_CFG_CMD_HEADER(((size - 4) / sizeof(uint32_t) - 1));
} else {
} else if (writer->type != CONFIG_TYPE_3DLUT_FL) {
// -4 DW for header, data array size, data array lo and data array hi
// /3 DW for each destination reg
// NUM_DST is 1-based, hence need -1

View file

@ -27,6 +27,7 @@
#include "vpe_priv.h"
#include "common.h"
#define LUT3D_SIZE_33x33x33 35937
#define LUT3D_SIZE_17x17x17 4913
#define LUT3D_SIZE_9x9x9 729

View file

@ -52,12 +52,15 @@ struct cdc_fe_funcs {
enum vpe_swizzle_mode_values swizzle, const struct vpe_rect *viewport,
const struct vpe_rect *viewport_c);
void (*program_3dlut_fl_config)(
struct cdc_fe *cdc_fe, enum lut_dimension lut_dimension, struct vpe_3dlut *lut_3d);
/** segment specific */
void (*program_viewport)(
struct cdc_fe *cdc_fe, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c);
};
struct cdc_be_funcs {
void (*program_cdc_control)(struct cdc_be *cdc_be, uint8_t enable_frod, uint32_t hist_dsets[]);
void (*program_global_sync)(struct cdc_be *cdc_be, uint32_t vupdate_offset,
uint32_t vupdate_width, uint32_t vready_offset);

View file

@ -235,7 +235,8 @@ struct color_gamut_data {
union vpe_3dlut_state {
struct {
uint32_t initialized : 1; /*< if 3dlut is went through color module for initialization */
uint32_t reserved : 15;
uint32_t is_dma : 1;
uint32_t reserved : 14;
} bits;
uint32_t raw;
};
@ -245,6 +246,14 @@ struct vpe_3dlut {
struct tetrahedral_params lut_3d;
struct fixed31_32 hdr_multiplier;
union vpe_3dlut_state state;
struct {
enum vpe_3dlut_mem_format format;
enum vpe_3dlut_mem_layout layout;
enum vpe_3dlut_addr_mode addr_mode;
enum vpe_3dlut_crossbar crossbar_r;
enum vpe_3dlut_crossbar crossbar_g;
enum vpe_3dlut_crossbar crossbar_b;
} dma_params;
// the followings are for optimization: skip if no change
bool dirty[MAX_3DLUT]; /*< indicate this object is updated or not */
@ -302,6 +311,9 @@ bool vpe_color_update_degamma_tf(struct vpe_priv *vpe_priv, enum color_transfer_
enum color_range_type vpe_get_range_type(
enum color_space color_space, enum vpe_surface_pixel_format format);
enum vpe_status vpe_color_setup_dma_lut(
struct vpe_3dlut *lut3d_func, struct stream_ctx *stream_ctx);
enum vpe_status vpe_calculate_shaper(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx);
#ifdef __cplusplus

View file

@ -52,6 +52,25 @@ struct vpe_csc_matrix {
uint16_t regval[12];
};
// S2.13
static const struct vpe_csc_matrix vpe_output_full_csc_matrix_fixed[] = {
{COLOR_SPACE_SRGB, {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0}},
{COLOR_SPACE_YCBCR601, {0x0e00, 0xf447, 0xfdb9, 0x1000, 0x082f, 0x1012, 0x031f, 0x0200, 0xfb47,
0xf6b9, 0x0e00, 0x1000}},
{COLOR_SPACE_YCBCR709, {0x0e00, 0xf349, 0xfeb7, 0x1000, 0x05d2, 0x1394, 0x01fa, 0x0200, 0xfccb,
0xf535, 0x0e00, 0x1000}},
{COLOR_SPACE_2020_YCBCR, {0x0e04, 0xf31d, 0xfedf, 0x1004, 0x0733, 0x1294, 0x01a0, 0x0201,
0xfc16, 0xf5e6, 0x0e04, 0x1004}}};
static const struct vpe_csc_matrix vpe_output_studio_csc_matrix_fixed[] = {
{COLOR_SPACE_SRGB, {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0}},
{COLOR_SPACE_YCBCR601, {0x1000, 0xf29a, 0xfd66, 0x1049, 0x0991, 0x12c9, 0x03a6, 0x0057, 0xfa9a,
0xf566, 0x1000, 0x1049}},
{COLOR_SPACE_YCBCR709, {0x1000, 0xf178, 0xfe88, 0x1049, 0x06ce, 0x16e3, 0x024f, 0x0057, 0xfc55,
0xf3ab, 0x1000, 0x1049}},
{COLOR_SPACE_2020_YCBCR, {0x1004, 0xf146, 0xfeb6, 0x104e, 0x086a, 0x15b8, 0x01e6, 0x0057,
0xfb87, 0xf475, 0x1004, 0x104e}}};
static const struct vpe_csc_matrix vpe_input_csc_matrix_fixed[] = {
{COLOR_SPACE_SRGB, {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0}},
{COLOR_SPACE_YCBCR601,

View file

@ -67,10 +67,13 @@ bool vpe_is_dual_plane_format(enum vpe_surface_pixel_format format);
bool vpe_is_32bit_packed_rgb(enum vpe_surface_pixel_format format);
bool vpe_is_rgb8(enum vpe_surface_pixel_format format);
bool vpe_is_rgb10(enum vpe_surface_pixel_format format);
bool vpe_is_rgb16(enum vpe_surface_pixel_format format);
bool vpe_is_planar_format(enum vpe_surface_pixel_format format);
bool vpe_is_fp16(enum vpe_surface_pixel_format format);
bool vpe_is_yuv8(enum vpe_surface_pixel_format format);
bool vpe_is_yuv10(enum vpe_surface_pixel_format format);
bool vpe_is_yuv12(enum vpe_surface_pixel_format format);
// yuv 4:2:0 check
bool vpe_is_yuv420_8(enum vpe_surface_pixel_format format);
@ -81,14 +84,23 @@ bool vpe_is_yuv420(enum vpe_surface_pixel_format format);
// yuv 4:4:4 check
bool vpe_is_yuv444_8(enum vpe_surface_pixel_format format);
bool vpe_is_yuv444_10(enum vpe_surface_pixel_format format);
bool vpe_is_yuv444_12(enum vpe_surface_pixel_format format);
bool vpe_is_yuv444(enum vpe_surface_pixel_format format);
// yuv 4:2:2 check
bool vpe_is_yuv422_8(enum vpe_surface_pixel_format format);
bool vpe_is_yuv422_10(enum vpe_surface_pixel_format format);
bool vpe_is_yuv422_12(enum vpe_surface_pixel_format format);
bool vpe_is_yuv422(enum vpe_surface_pixel_format format);
bool vpe_is_yuv_packed(enum vpe_surface_pixel_format format);
bool vpe_is_mono(enum vpe_surface_pixel_format format);
bool vpe_is_yuv(enum vpe_surface_pixel_format format);
bool vpe_is_8bit(enum vpe_surface_pixel_format format);
bool vpe_is_10bit(enum vpe_surface_pixel_format format);
bool vpe_is_16bit(enum vpe_surface_pixel_format format);
enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format);
bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format);
@ -107,6 +119,17 @@ uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int
uint32_t vpe_align_seg(uint32_t seg_size, uint32_t alignment);
enum vpe_status vpe_check_3dlut_compound(
struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param);
enum vpe_status vpe_check_histogram_support(struct vpe *vpe, const struct vpe_stream *stream);
enum vpe_scan_direction vpe_get_scan_direction(
enum vpe_rotation_angle rotation, bool horizontal_mirror, bool vertical_mirror);
bool vpe_supported_linear_scan_pattern(enum vpe_scan_direction scan_dir);
bool vpe_validate_hist_collection(struct vpe_stream* stream);
#ifdef __cplusplus
}
#endif

View file

@ -41,6 +41,7 @@ enum config_type {
CONFIG_TYPE_UNKNOWN,
CONFIG_TYPE_DIRECT,
CONFIG_TYPE_INDIRECT,
CONFIG_TYPE_3DLUT_FL,
};
typedef void (*config_callback_t)(
@ -178,6 +179,10 @@ void config_writer_fill_indirect_data_array(
void config_writer_fill_indirect_destination(struct config_writer *writer,
const uint32_t offset_index, const uint32_t start_index, const uint32_t offset_data);
void config_writer_fill_3dlut_fl_addr(struct config_writer *writer, const uint64_t data_gpuva,
enum vpe_3dlut_addr_mode addr_mode, enum vpe_3dlut_mem_align mem_align, uint32_t size,
bool comp_mode, uint8_t tmz);
/** explicitly complete the config */
void config_writer_complete(struct config_writer *writer);

View file

@ -113,6 +113,15 @@ struct dpp_funcs {
uint32_t (*get_line_buffer_size)(void);
bool (*validate_number_of_taps)(struct dpp *dpp, struct scaler_data *scl_data);
void (*enable_clocks)(struct dpp *dpp, bool enable);
void (*dscl_program_easf)(struct dpp *dpp, const struct scaler_data *scl_data);
void (*dscl_disable_easf)(struct dpp *dpp, const struct scaler_data *scl_data);
void (*dscl_program_isharp)(struct dpp *dpp, const struct scaler_data *scl_data);
void (*program_histogram)(struct dpp* dpp, struct vpe_histogram_param* hist_param, enum color_space cs);
void (*program_crc)(struct dpp *opp, bool enable);
};

View file

@ -28,8 +28,11 @@
#define MAX_3DLUT 1
#define MAX_INPUT_PIPE 1
#define MAX_OUTPUT_PIPE 1
#define MAX_INPUT_PIPE 2
#define MAX_OUTPUT_PIPE 4
#define FROD_NUM_OUTPUTS 4 /**< 4 outputs for FROD, one pipeline output and 3 downscaled versions 1:2, 1:4 and 1:8*/
#define FROD_DOWNSAMPLING_RATIO 2
#define MAX_HISTO_SETS 3
#ifdef __cplusplus
extern "C" {
@ -136,6 +139,48 @@ enum hw_point_position {
HW_POINT_POSITION_RIGHT,
};
/** @enum vpe_3dlut_mem_format
* @brief 3DLUT memory formats
*/
enum vpe_3dlut_mem_format {
VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12MSB = 0, /**< 12 bit integer in a 16 bit container
aligned MSB */
VPE_3DLUT_MEM_FORMAT_16161616_UNORM_12LSB = 1, /**< 12 bit integer in a 16 bit container
aligned LSB */
VPE_3DLUT_MEM_FORMAT_16161616_FLOAT_FP1_5_10 = 2, /**< Floating point with one sign bit,
5 exponential bits and 10 mantissa */
};
/** @enum vpe_3dlut_mem_layout
* @brief 3DLUT memory layout
*/
enum vpe_3dlut_mem_layout {
VPE_3DLUT_MEM_LAYOUT_DISABLE = 0, /**< Disabled */
VPE_3DLUT_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB = 1, /**< 3D Swizzle linear surface addressing
incremented as R->G->B */
VPE_3DLUT_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR = 2, /**< 3D Swizzle linear surface addressing
incremented as B->G->R */
VPE_3DLUT_MEM_LAYOUT_1D_PACKED_LINEAR = 3, /**< Packed 1d linear addressing */
};
/** @enum vpe_3dlut_crossbar
* @brief 3DLUT Crossbar bit slice
*/
enum vpe_3dlut_crossbar {
VPE_3DLUT_CROSSBAR_BIT_SLICE_0_15 = 0, /**< 3DLUT Crossbar Mux Select bits 0-15 */
VPE_3DLUT_CROSSBAR_BIT_SLICE_16_31 = 1, /**< 3DLUT Crossbar Mux Select bits 16-31 */
VPE_3DLUT_CROSSBAR_BIT_SLICE_32_47 = 2, /**< 3DLUT Crossbar Mux Select bits 32-47 */
VPE_3DLUT_CROSSBAR_BIT_SLICE_48_63 = 3, /**< 3DLUT Crossbar Mux Select bits 48-63 */
};
/** @enum vpe_3dlut_addr_mode
* @brief 3DLUT Swizzle addressing
*/
enum vpe_3dlut_addr_mode {
VPE_3DLUT_SIMPLE_LINEAR = 0, /**< Linear swizzle 3DLUT addressing */
VPE_3DLUT_SW_LINEAR = 1, /**< Contiguous 3DLUT addressing */
};
struct gamma_point {
int32_t left_index;
int32_t right_index;
@ -158,6 +203,7 @@ enum lut_dimension {
LUT_DIM_INVALID = 0,
LUT_DIM_9 = 9,
LUT_DIM_17 = 17,
LUT_DIM_33 = 33,
};
struct vpe_rgb {
@ -166,6 +212,13 @@ struct vpe_rgb {
uint32_t blue;
};
struct tetrahedral_33x33x33 {
struct vpe_rgb lut0[8985];
struct vpe_rgb lut1[8984];
struct vpe_rgb lut2[8984];
struct vpe_rgb lut3[8984];
};
struct tetrahedral_17x17x17 {
struct vpe_rgb lut0[1229];
struct vpe_rgb lut1[1228];
@ -181,6 +234,7 @@ struct tetrahedral_9x9x9 {
struct tetrahedral_params {
union {
struct tetrahedral_33x33x33 tetrahedral_33;
struct tetrahedral_17x17x17 tetrahedral_17;
struct tetrahedral_9x9x9 tetrahedral_9;
};

View file

@ -43,21 +43,25 @@ enum mpc_mpccid {
enum mpc_mux_topsel {
MPC_MUX_TOPSEL_DPP0 = 0,
MPC_MUX_TOPSEL_DPP1 = 1,
MPC_MUX_TOPSEL_DISABLE = 0x0f,
};
enum mpc_mux_botsel {
MPC_MUX_BOTSEL_MPCC0 = 0,
MPC_MUX_BOTSEL_MPCC1 = 1,
MPC_MUX_BOTSEL_DISABLE = 0x0f,
};
enum mpc_mux_outmux {
MPC_MUX_OUTMUX_MPCC0 = 0,
MPC_MUX_OUTMUX_MPCC1 = 1,
MPC_MUX_OUTMUX_DISABLE = 0x0f,
};
enum mpc_mux_oppid {
MPC_MUX_OPPID_OPP0 = 0,
MPC_MUX_OPPID_OPP1 = 1,
MPC_MUX_OPPID_DISABLE = 0x0f,
};
@ -72,6 +76,14 @@ enum mpcc_alpha_blend_mode {
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA,
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN,
MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA,
MPCC_ALPHA_BLEND_MODE_ALPHA_THROUGH_LUMA,
};
enum mpcc_gamut_remap_id {
VPE_MPC_GAMUT_REMAP,
VPE_MPC_RMCM_GAMUT_REMAP,
VPE_MPC_MCM_FIRST_GAMUT_REMAP,
VPE_MPC_MCM_SECOND_GAMUT_REMAP,
};
/*
@ -168,6 +180,20 @@ struct mpc_funcs {
struct vpe_3dlut *lut3d_func, struct transfer_func *blend_tf, bool afterblend);
void (*program_crc)(struct mpc *mpc, bool enable);
void (*attach_3dlut_to_mpc_inst)(struct mpc *mpc, enum mpc_mpccid mpcc_idx);
void (*set_gamut_remap2)(struct mpc *mpc, struct colorspace_transform *gamut_remap,
enum mpcc_gamut_remap_id mpcc_gamut_remap_block_id);
void (*update_3dlut_fl_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale);
void (*program_mpc_3dlut_fl_config)(struct mpc *mpc, enum vpe_3dlut_mem_layout layout,
enum vpe_3dlut_mem_format format, bool enable);
void (*program_mpc_3dlut_fl)(struct mpc *mpc, enum lut_dimension lut_dimension, bool use_12bit);
void (*shaper_bypass)(struct mpc *mpc, bool bypass);
};
struct mpc {

View file

@ -0,0 +1,143 @@
/* Copyright 2025 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe_mps_section {
uint16_t num_streams;
int32_t start_x;
int32_t end_x;
struct vpe_vector *command_vector; // type struct vpe_mps_command
};
struct vpe_mps_command {
uint16_t num_inputs;
uint16_t stream_idx[MAX_INPUT_PIPE]; // stream idx for input in vpe_priv->stream_ctx array
int16_t mps_idx[MAX_INPUT_PIPE]; // track stream idx in mps struct for each input
uint16_t
seg_idx[MAX_INPUT_PIPE]; // track segment idx for each input (segments stores in stream_ctx)
int32_t start_x[MAX_INPUT_PIPE]; // start_x for each input (segment + bg gen)
int32_t end_x[MAX_INPUT_PIPE]; // end_x for each input (segment + bg gen)
bool is_bg_gen[MAX_INPUT_PIPE]; // is this input all bg
};
struct vpe_mps_stream_info {
struct stream_ctx *stream_ctx;
struct vpe_rect src_rect;
struct vpe_rect dst_rect;
};
struct vpe_mps_ctx {
struct vpe_vector *section_vector; // type struct vpe_mps_section
uint16_t num_streams;
uint16_t stream_idx[MAX_INPUT_PIPE];
uint16_t segment_count[MAX_INPUT_PIPE]; // how many segments each stream has
struct vpe_vector
*segment_widths[MAX_INPUT_PIPE]; // type struct vpe_vector<uint32_t> : array containing
// vector of segments widths per stream
};
struct vpe_mps_stream_ctx {
struct stream_ctx *stream_ctx;
struct vpe_rect src_rect;
struct vpe_rect dst_rect;
};
// Everything required to run MPS algo
struct vpe_mps_input {
uint16_t num_inputs;
struct vpe_mps_stream_ctx mps_stream_ctx[MAX_INPUT_PIPE];
uint32_t max_seg_width;
uint32_t recout_width_alignment;
};
/**
* @brief Check if MPS is possible with the streams passed in
* @param[in] vpe_priv vpe_priv
* @param[in] stream_ctx array of stream_ctx involved in MPS blend
* @param[in] num_streams number of streams in stream_ctx array
* @return true if possible, false if not
*/
bool vpe_is_mps_possible(struct vpe_priv *vpe_priv, struct stream_ctx **stream_ctx,
uint16_t num_streams, uint32_t recout_width_alignment);
/**
* @brief Allocate mps_ctx and initialize it with the stream_idx and num_streams. Run
* vpe_is_mps_possible beforehand!
* @param[in] vpe_priv vpe_priv
* @param[in] stream_ctx array of stream_ctx involved in MPS blend
* @param[in] num_streams number of streams in stream_ctx array
* @return VPE_STATUS_OK if successful, error code otherwise
*/
enum vpe_status vpe_init_mps_ctx(
struct vpe_priv *vpe_priv, struct stream_ctx **stream_ctx, uint16_t num_streams);
/**
* @brief Clear mps_ctx and NULL mps_parent_stream for non-parents streams involved (mem isn't
* freed)
* @param[in] vpe_priv vpe_priv
* @param[in] mps_ctx mps_ctx to be cleared
* @return VPE_STATUS_OK if successful, error code otherwise
*/
void vpe_clear_mps_ctx(struct vpe_priv *vpe_priv, struct vpe_mps_ctx *mps_ctx);
/**
* @brief Deallocate and free mps_ctx and NULL mps_parent_stream for all streams involved
* @param[in] vpe_priv vpe_priv
* @param[in] mps_ctx mps_ctx to be freed
* @return VPE_STATUS_OK if successful, error code otherwise
*/
void vpe_free_mps_ctx(struct vpe_priv *vpe_priv, struct vpe_mps_ctx **mps_ctx);
/**
* @brief Add commands to vpe_priv cmd_vector for this MPS op
* @param[in] vpe_priv vpe_priv
* @param[in] mps_ctx mps_ctx (filled out by vpe_mps_build_mps_ctx)
* @return VPE_STATUS_OK if successful, error code otherwise
*/
enum vpe_status vpe_fill_mps_blend_cmd_info(struct vpe_priv *vpe_priv, struct vpe_mps_ctx *mps_ctx);
/**
* @brief Get number of segments required for this MPS involved stream. This must be ran on the
* parent stream the first time!
* @param[in] vpe_priv vpe_priv
* @param[in] stream_ctx stream_ctx
* @param[in] max_seg_width maximum segment width for this stream
* @param[in] recout_width_alignment recout width alignment
* @return number of segments required for this stream
*/
uint16_t vpe_mps_get_num_segs(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx,
uint32_t *max_seg_width, uint32_t recout_width_alignment);
#ifdef __cplusplus
}
#endif

View file

@ -103,12 +103,59 @@ struct opp_pipe_control_params {
/**< Digital bypass enable */
bool bypass_enable;
/**< Enable bypass mode for the pipe */
/**< Pipe alpha select */
bool alpha_select;
};
enum subsampling_quality {
SUBSAMPLING_QUALITY_HIGH,
SUBSAMPLING_QUALITY_LOW,
SUBSAMPLING_QUALITY_COUNT,
};
enum fmt_subsampling_boundary_mode {
FMT_SUBSAMPLING_BOUNDARY_REPEAT = 0,
FMT_SUBSAMPLING_BOUNDARY_EXTRA = 1,
};
struct fmt_boundary_mode {
enum fmt_subsampling_boundary_mode left;
enum fmt_subsampling_boundary_mode right;
enum fmt_subsampling_boundary_mode top;
enum fmt_subsampling_boundary_mode bottom;
};
struct chroma_taps {
uint32_t v_taps_c; /**< Number of vertical taps for chroma plane */
uint32_t h_taps_c; /**< Number of horizontal taps for chroma plane */
};
struct fmt_extra_pixel_info {
uint32_t left_pixels;
uint32_t right_pixels;
uint32_t top_pixels;
uint32_t bottom_pixels;
};
struct fmt_subsampling_params {
uint32_t pixel_encoding;
uint32_t bit_reduction_bypass;
uint32_t vtaps;
uint32_t htaps;
struct fmt_boundary_mode boundary_mode;
};
struct fmt_control_params {
uint8_t fmt_spatial_dither_frame_counter_max;
uint8_t fmt_spatial_dither_frame_counter_bit_swap;
struct fmt_subsampling_params subsampling_params;
};
struct opp_frod_param {
union {
uint8_t enable_frod;
};
};
struct opp_funcs {
@ -129,6 +176,19 @@ struct opp_funcs {
void (*program_pipe_crc)(struct opp *opp, bool enable);
void (*build_fmt_subsample_params)(struct opp *opp, enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_boundary_mode boundary_mode, struct fmt_subsampling_params *subsample_params);
void (*set_bg)(struct opp* opp, struct vpe_rect target_rect, struct vpe_rect dst_rect,
enum vpe_surface_pixel_format format, struct vpe_color bgcolor);
void (*program_frod)(struct opp *opp, struct opp_frod_param *frod_param);
void (*get_fmt_extra_pixel)(enum vpe_surface_pixel_format format,
enum subsampling_quality subsample_quality, enum chroma_cositing cositing,
struct fmt_extra_pixel_info *extra_pixel);
};
struct opp {

View file

@ -45,6 +45,9 @@ struct plane_desc_writer {
void (*init)(struct plane_desc_writer *writer, struct vpe_buf *buf, void *p_header);
void (*add_source)(struct plane_desc_writer *writer, void *p_source, bool is_plane0);
void (*add_destination)(struct plane_desc_writer *writer, void *p_destination, bool is_plane0);
void (*add_meta)(struct plane_desc_writer *writer, void *p_source);
void (*add_histo)(struct plane_desc_writer *writer, void *p_destination, uint32_t hist_index,
uint8_t hist_dsets_array[]);
};
#ifdef __cplusplus

View file

@ -122,8 +122,46 @@ struct resource {
enum vpe_status (*check_alpha_fill_support)(
struct vpe *vpe, const struct vpe_build_param *param);
enum vpe_status (*fill_alpha_through_luma_cmd_info)(
struct vpe_priv *vpe_priv, uint16_t alpha_stream_idx);
enum vpe_status (*fill_non_performance_mode_cmd_info)(
struct vpe_priv *vpe_priv, uint16_t stream_idx);
enum vpe_status (*fill_performance_mode_cmd_info)(
struct vpe_priv *vpe_priv, uint16_t stream_idx, uint16_t avail_pipe_count);
enum vpe_status (*fill_blending_cmd_info)(
struct vpe_priv *vpe_priv, uint16_t top_stream_idx, uint16_t bot_stream_idx);
enum vpe_status (*populate_frod_param)(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
uint32_t (*get_num_pipes_available)(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx);
void (*set_frod_output_viewport)(struct vpe_cmd_output *dst_output,
struct vpe_cmd_output *src_output, uint32_t viewport_divider,
enum vpe_surface_pixel_format format);
void (*reset_pipes)(struct vpe_priv *vpe_priv);
enum vpe_status (*check_lut3d_compound)(
const struct vpe_stream *stream, const struct vpe_build_param *param);
void (*set_lls_pref)(struct vpe_priv *vpe_priv, struct spl_in *spl_input,
enum color_transfer_func tf, enum vpe_surface_pixel_format pixel_format);
void (*program_fastload)(struct vpe_priv *vpe_priv, uint32_t cmd_idx);
enum vpe_status (*calculate_shaper)(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx);
void (*update_opp_adjust_and_boundary)(struct stream_ctx *stream_ctx, uint16_t seg_idx,
bool dst_subsampled, const struct vpe_rect *src_rect, const struct vpe_rect *dst_rect,
struct output_ctx *output_ctx, struct spl_opp_adjust *opp_recout_adjust);
bool (*set_dst_cmd_info_scaler)(struct stream_ctx *dst_stream_ctx,
struct scaler_data *dst_scaler_data, struct vpe_rect recout, struct vpe_rect dst_viewport,
struct fmt_boundary_mode *boundary_mode, struct spl_opp_adjust *opp_adjust);
// Indicates the nominal range hdr input content should be in during processing.
int internal_hdr_normalization;
@ -196,6 +234,16 @@ void vpe_backend_config_callback(
bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2);
bool vpe_is_zero_rect(struct vpe_rect *rect);
bool vpe_is_valid_vp(struct vpe_rect *src_rect, struct vpe_rect *dst_rect);
bool vpe_is_scaling_factor_supported(struct vpe_priv *vpe_priv, struct vpe_rect *src_rect,
struct vpe_rect *dst_rect, enum vpe_rotation_angle rotation);
struct stream_ctx *vpe_get_virtual_stream(
struct vpe_priv *vpe_priv, enum vpe_stream_type stream_type);
const struct vpe_caps *vpe_get_capability(enum vpe_ip_level ip_level);
void vpe_setup_check_funcs(struct vpe_check_support_funcs *funcs, enum vpe_ip_level ip_level);

View file

@ -31,12 +31,21 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define SHAPER_EXP_MAX_IN 16
enum vpe_shaper_index_mode {
SHAPER_INDEX_MODE_DEFAULT,
SHAPER_INDEX_MODE_17IN33LUT
};
struct vpe_shaper_setup_in {
double source_luminance;
double shaper_in_max;
bool use_const_hdr_mult;
enum vpe_shaper_index_mode index_mode;
};
enum vpe_status vpe_build_shaper(const struct vpe_shaper_setup_in *shaper_in,
enum color_transfer_func shaper_tf, struct fixed31_32 pq_norm_gain,
struct pwl_params *shaper_out);
enum vpe_shaper_index_mode vpe_get_shaper_index_mode(
uint32_t is_dma, enum lut_dimension lut_dim, enum lut_dimension lut_container_dim);

View file

@ -29,6 +29,7 @@
#include <stdbool.h>
#include "vpe_hw_types.h"
#include "fixed31_32.h"
#include "SPL/dc_spl_types.h"
#ifdef __cplusplus
extern "C" {
@ -46,22 +47,6 @@ struct gamut_remap_matrix {
enum gamut_adjust_type adjust_type;
};
enum lb_memory_config {
/* Enable all 3 pieces of memory */
LB_MEMORY_CONFIG_0 = 0,
/* Enable only the first piece of memory */
LB_MEMORY_CONFIG_1 = 1,
/* Enable only the second piece of memory */
LB_MEMORY_CONFIG_2 = 2,
/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
* last piece of chroma memory used for the luma storage
*/
LB_MEMORY_CONFIG_3 = 3,
};
struct scaling_ratios {
struct fixed31_32 horz;
struct fixed31_32 vert;
@ -100,6 +85,7 @@ struct scaler_data {
enum vpe_surface_pixel_format format;
struct line_buffer_params lb_params;
struct vpe_scaling_filter_coeffs *polyphase_filter_coeffs;
struct dscl_prog_data dscl_prog_data;
};
const uint16_t *vpe_get_filter_2tap_64p(void);

View file

@ -89,6 +89,7 @@ enum VPE_CMD_OPCODE {
enum VPE_VPEP_CFG_SUBOP {
VPE_VPEP_CFG_SUBOP_DIR_CFG = 0x0,
VPE_VPEP_CFG_SUBOP_IND_CFG = 0x1,
VPE_VPEP_CFG_SUBOP_3DLUT_CFG = 0x2,
};
// Direct Config Command Header
@ -119,6 +120,22 @@ enum VPE_VPEP_CFG_SUBOP {
#define VPE_IND_CFG_PKT_REGISTER_OFFSET__SHIFT 2
#define VPE_IND_CFG_PKT_REGISTER_OFFSET_MASK 0x000FFFFC
// VPEP 3D LUT Config Command Header
#define VPE_3DLUT_CFG_HEADER_ADDR_MOD__SHIFT 31
#define VPE_3DLUT_CFG_HEADER_ADDR_MOD_MASK 0x80000000
#define VPE_3DLUT_CFG_HEADER_PITCH_MOD__SHIFT 30
#define VPE_3DLUT_CFG_HEADER_PITCH_MOD_MASK 0x40000000
#define VPE_3DLUT_CFG_CMD_HEADER(addr_mode, mem_align) \
(VPE_CMD_HEADER(VPE_CMD_OPCODE_VPEP_CFG, VPE_VPEP_CFG_SUBOP_3DLUT_CFG) | \
((((uint32_t)addr_mode) << VPE_3DLUT_CFG_HEADER_ADDR_MOD__SHIFT) & \
VPE_3DLUT_CFG_HEADER_ADDR_MOD_MASK) | \
((((uint32_t)mem_align) << VPE_3DLUT_CFG_HEADER_PITCH_MOD__SHIFT) & \
VPE_3DLUT_CFG_HEADER_PITCH_MOD_MASK))
#define VPE_3DLUT_CFG_COMP_MODE__SHIFT 5
#define VPE_3DLUT_CFG_COMP_MODE_MASK 0x20
/**************************
* Poll Reg/Mem Sub-OpCode
**************************/

View file

@ -61,12 +61,24 @@ extern "C" {
#define MAX_LINE_CNT 4
#define VPE_NO_ALIGNMENT 1
#define VPE_SUBSAMPLED_OUT_ALIGNMENT 2
#define VPE_FROD_ALIGNMENT 16
#define MAX_FROD_VIEWPORT_DIVIDER 8
#define VPE_DESTINATION_AS_INPUT_STREAM_INDEX 0xff
#define OPTIMAL_MIN_PERFORMACE_MODE_SIZE \
400 // Temp smallest value for performance mode to be worth it - need to determine this
// experimentally i.e. values where num_pixels isn't worth cmd_info generation time
enum vpe_cmd_ops {
VPE_CMD_OPS_BLENDING,
VPE_CMD_OPS_BG,
VPE_CMD_OPS_COMPOSITING,
VPE_CMD_OPS_BG_VSCF_INPUT, // For visual confirm input
VPE_CMD_OPS_BG_VSCF_OUTPUT, // For visual confirm output
VPE_CMD_OPS_ALPHA_THROUGH_LUMA,
VPE_CMD_OPS_BG_VSCF_PIPE0, // For visual confirm pipe 0
VPE_CMD_OPS_BG_VSCF_PIPE1, // For visual confirm pipe 1
};
enum vpe_cmd_type {
@ -74,17 +86,26 @@ enum vpe_cmd_type {
VPE_CMD_TYPE_BG,
VPE_CMD_TYPE_BG_VSCF_INPUT, // For visual confirm input
VPE_CMD_TYPE_BG_VSCF_OUTPUT, // For visual confirm output
VPE_CMD_TYPE_BLENDING, // For alpha blending
VPE_CMD_TYPE_ALPHA_THROUGH_LUMA,
VPE_CMD_TYPE_BG_VSCF_PIPE0, // For visual confirm pipe 0
VPE_CMD_TYPE_BG_VSCF_PIPE1, // For visual confirm pipe 1
VPE_CMD_TYPE_COUNT
};
enum vpe_stream_type {
VPE_STREAM_TYPE_INPUT,
VPE_STREAM_TYPE_BG_GEN,
VPE_STREAM_TYPE_DESTINATION,
VPE_STREAM_TYPE_BKGR_BACKGROUND, // New background for the bg replacement (BKGR) feature
VPE_STREAM_TYPE_BKGR_VIDEO, // Video which will have its bg replaced
VPE_STREAM_TYPE_BKGR_ALPHA, // Alpha stream for to combine with BKGR video stream
};
enum lut3d_type {
LUT3D_TYPE_NONE,
LUT3D_TYPE_CPU,
LUT3D_TYPE_GPU,
};
/** this represents a segement context.
@ -93,6 +114,8 @@ struct segment_ctx {
uint16_t segment_idx;
struct stream_ctx *stream_ctx;
struct scaler_data scaler_data;
struct fmt_boundary_mode boundary_mode;
struct spl_opp_adjust opp_recout_adjust;
};
struct vpe_cmd_input {
@ -103,6 +126,8 @@ struct vpe_cmd_input {
struct vpe_cmd_output {
struct vpe_rect dst_viewport;
struct vpe_rect dst_viewport_c;
struct fmt_boundary_mode boundary_mode;
struct spl_opp_adjust opp_recout_adjust;
};
struct vpe_cmd_info {
@ -121,6 +146,9 @@ struct vpe_cmd_info {
bool insert_start_csync;
bool insert_end_csync;
struct vpe_surface_info frod_surface[VPE_FROD_MAX_STAGE]; /**< FROD outputs */
struct opp_frod_param frod_param; /**< FROD parameters */
uint32_t histo_dsets[MAX_INPUT_PIPE];
};
struct config_record {
@ -151,6 +179,7 @@ struct stream_ctx {
uint64_t uid_3dlut; // UID for current 3D LUT params
bool geometric_scaling;
bool is_yuv_input;
struct fixed31_32 csc_renorm_factor; // csc was scaled down to fit into HW format
union {
struct {
@ -169,10 +198,21 @@ struct stream_ctx {
struct transfer_func *in_shaper_func; // for shaper lut
struct vpe_3dlut *lut3d_func; // for 3dlut
struct transfer_func *blend_tf; // for 1dlut
struct vpe_mps_ctx *mps_ctx; // used to store the return values from multi-pipe segmentation.
// Allocated by the base stream. if non-base stream, access this
// through ctx->mps_parent_stream->mps_ctx
struct stream_ctx
*mps_parent_stream; // point to base stream for multi-pipe segmentation
// ex. if blending streams 0, 1 & 2, this will point to stream 0
white_point_gain white_point_gain;
bool flip_horizonal_output;
struct vpe_color_adjust color_adjustments; // stores the current color adjustments params
struct fixed31_32 tf_scaling_factor; // a gain applied on a transfer function
enum vpe_scan_direction scan; // Scan direction based on the h/v mirror and rotation angle
struct spl_in spl_input;
struct spl_out spl_output;
enum fmt_subsampling_boundary_mode left;
enum fmt_subsampling_boundary_mode right;
};
struct output_ctx {
@ -200,6 +240,9 @@ struct output_ctx {
};
unsigned int u32All;
} dirty_bits;
struct vpe_surface_info frod_surface[VPE_FROD_MAX_STAGE]; // surfaces for FROD
struct vpe_csc_matrix* out_csc_matrix; // for mpc out
struct vpe_frod_param frod_param; // FROD parameters
struct transfer_func *output_tf;
const struct transfer_func *in_shaper_func; // for shaper lut
const struct vpe_3dlut *lut3d_func; // for 3dlut

View file

@ -0,0 +1,48 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#pragma once
#include "vpe_types.h"
#include "transform.h"
#include "vpe_priv.h"
#include "SPL/dc_spl_types.h"
#include "SPL/dc_spl.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe_spl_scl_to_vpe_scl(struct spl_out *spl_out, struct scaler_data *vpe_scl_data);
void vpe_init_spl_in(
struct spl_in *spl_input, struct stream_ctx *stream_ctx, struct output_ctx *output_ctx);
void vpe_scl_to_dscl_bg(struct scaler_data *scl_data);
void vpe_get_vp_scan_direction(enum vpe_rotation_angle degree, bool h_mirror, bool v_mirror,
bool *orthogonal_rotation, bool *flip_horz_scan_dir, bool *flip_vert_scan_dir);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,9 @@
#include "vpe11_resource.h"
#include "vpe20_resource.h"
#include "multi_pipe_segmentation.h"
static const struct vpe_debug_options debug_defaults = {
.flags = {0},
.cm_in_bypass = 0,
@ -75,6 +78,10 @@ static const struct vpe_debug_options debug_defaults = {
.skip_optimal_tap_check = 0,
.disable_lut_caching = 0,
.bypass_blndgam = 0,
.disable_performance_mode = 0,
.multi_pipe_segmentation_policy = 1, // 0: disable, 1: use for blending, 2: always use
.opp_background_gen = 0, // 0 : mpc bg gen, 1: opp bg gen
.subsampling_quality = 1, // 0 : 4/5 taps 1: 2/3 taps
};
enum vpe_ip_level vpe_resource_parse_ip_version(
@ -90,6 +97,10 @@ enum vpe_ip_level vpe_resource_parse_ip_version(
case VPE_VERSION(6, 1, 2):
ip_level = VPE_IP_LEVEL_1_1;
break;
case VPE_VERSION(2, 0, 0):
case VPE_VERSION(7, 0, 0): // to be removed when caller switches to new convention
ip_level = VPE_IP_LEVEL_2_0;
break;
default:
ip_level = VPE_IP_LEVEL_UNKNOWN;
break;
@ -109,6 +120,9 @@ enum vpe_status vpe_construct_resource(
case VPE_IP_LEVEL_1_1:
status = vpe11_construct_resource(vpe_priv, res);
break;
case VPE_IP_LEVEL_2_0:
status = vpe20_construct_resource(vpe_priv, res);
break;
default:
status = VPE_STATUS_NOT_SUPPORTED;
vpe_log("invalid ip level: %d", (int)level);
@ -132,6 +146,9 @@ void vpe_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res)
case VPE_IP_LEVEL_1_1:
vpe11_destroy_resource(vpe_priv, res);
break;
case VPE_IP_LEVEL_2_0:
vpe20_destroy_resource(vpe_priv, res);
break;
default:
break;
}
@ -276,6 +293,10 @@ static void free_stream_ctx(uint32_t num_streams, struct stream_ctx *stream_ctx)
ctx->segment_ctx = NULL;
}
if (ctx->mps_ctx)
if (ctx->mps_parent_stream == ctx)
vpe_free_mps_ctx(vpe_priv, &ctx->mps_ctx);
destroy_input_config_vector(ctx);
}
}
@ -434,6 +455,10 @@ void vpe_calculate_scaling_ratios(struct scaler_data *scl_data, struct vpe_rect
scl_data->ratios.vert_c.value /= 2;
}
if (vpe_is_yuv422(format)) {
scl_data->ratios.horz_c.value /= 2;
}
scl_data->ratios.horz = vpe_fixpt_truncate(scl_data->ratios.horz, 19);
scl_data->ratios.vert = vpe_fixpt_truncate(scl_data->ratios.vert, 19);
scl_data->ratios.horz_c = vpe_fixpt_truncate(scl_data->ratios.horz_c, 19);
@ -549,6 +574,10 @@ static enum vpe_status calculate_inits_and_viewports(struct segment_ctx *segment
struct fixed31_32 init_adj_h = vpe_fixpt_zero;
struct fixed31_32 init_adj_v = vpe_fixpt_zero;
if (vpe_is_yuv422(data->format)) {
vpc_h_div = 2;
}
get_vp_scan_direction(stream_ctx->stream.rotation, stream_ctx->stream.horizontal_mirror,
&orthogonal_rotation, &flip_vert_scan_dir, &flip_horz_scan_dir);
@ -613,6 +642,8 @@ enum lut3d_type vpe_get_stream_lut3d_type(struct stream_ctx *stream_ctx)
// for Fast Load Enable/Disable
if ((stream_ctx->stream.tm_params.UID == 0) || (!stream_ctx->stream.tm_params.enable_3dlut)) {
lut3d = LUT3D_TYPE_NONE;
} else if (stream_ctx->stream.tm_params.lut_type != VPE_LUT_TYPE_CPU) {
lut3d = LUT3D_TYPE_GPU;
} else {
lut3d = LUT3D_TYPE_CPU;
}
@ -631,9 +662,14 @@ bool vpe_should_generate_cmd_info(struct stream_ctx *stream_ctx)
{
enum vpe_stream_type stream_type = stream_ctx->stream_type;
if (stream_ctx->mps_parent_stream != NULL && stream_ctx->mps_parent_stream != stream_ctx)
return false; // don't generate cmd info for non-parent stream in mps blending
// all cmd info for whole MPS op will be generated by parent stream
switch (stream_type) {
case VPE_STREAM_TYPE_INPUT:
case VPE_STREAM_TYPE_BG_GEN:
case VPE_STREAM_TYPE_BKGR_ALPHA:
return true;
default:
/* destination-as-input virtual stream does not need a new cmd_info,
@ -897,6 +933,15 @@ void vpe_backend_config_callback(
uint32_t vpe_get_recout_width_alignment(const struct vpe_build_param *params)
{
uint16_t recout_alignment;
bool dst_subsampled;
dst_subsampled = vpe_is_subsampled_format(params->dst_surface.format);
if (params->frod_param.enable_frod == true)
recout_alignment = VPE_FROD_ALIGNMENT;
else if (dst_subsampled == true)
recout_alignment = VPE_SUBSAMPLED_OUT_ALIGNMENT;
else
recout_alignment = VPE_NO_ALIGNMENT;
return recout_alignment;
@ -908,6 +953,52 @@ bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2)
rec1.height == rec2.height);
}
bool vpe_is_zero_rect(struct vpe_rect *rect)
{
return (rect->width <= 0 || rect->height <= 0);
}
bool vpe_is_valid_vp(struct vpe_rect *src_rect, struct vpe_rect *dst_rect)
{
return (src_rect->width >= VPE_MIN_VIEWPORT_SIZE && src_rect->height >= VPE_MIN_VIEWPORT_SIZE &&
dst_rect->width >= VPE_MIN_VIEWPORT_SIZE && dst_rect->height >= VPE_MIN_VIEWPORT_SIZE);
}
bool vpe_is_scaling_factor_supported(struct vpe_priv *vpe_priv, struct vpe_rect *src_rect,
struct vpe_rect *dst_rect, enum vpe_rotation_angle rotation)
{
bool ort_rotated = (rotation == VPE_ROTATION_ANGLE_90 || rotation == VPE_ROTATION_ANGLE_270);
const uint32_t max_upscale_factor = vpe_priv->pub.caps->plane_caps.max_upscale_factor;
const uint32_t max_downscale_factor = vpe_priv->pub.caps->plane_caps.max_downscale_factor;
uint32_t factor;
uint32_t src_width = ort_rotated ? src_rect->height : src_rect->width;
uint32_t src_height = ort_rotated ? src_rect->width : src_rect->height;
// horizontal factor
factor = (uint32_t)vpe_fixpt_ceil(vpe_fixpt_from_fraction((1000 * dst_rect->width), src_width));
if (factor > max_upscale_factor || factor < max_downscale_factor)
return false;
// vertical factor
factor =
(uint32_t)vpe_fixpt_ceil(vpe_fixpt_from_fraction((1000 * dst_rect->height), src_height));
if (factor > max_upscale_factor || factor < max_downscale_factor)
return false;
return true;
}
struct stream_ctx *vpe_get_virtual_stream(
struct vpe_priv *vpe_priv, enum vpe_stream_type stream_type)
{
for (uint32_t i = 0; i < vpe_priv->num_virtual_streams; i++) {
if (vpe_priv->stream_ctx[i + vpe_priv->num_input_streams].stream_type == stream_type) {
return &(vpe_priv->stream_ctx[i + vpe_priv->num_input_streams]);
}
}
return NULL;
}
const struct vpe_caps *vpe_get_capability(enum vpe_ip_level ip_level)
{
const struct vpe_caps *caps;
@ -918,6 +1009,9 @@ const struct vpe_caps *vpe_get_capability(enum vpe_ip_level ip_level)
case VPE_IP_LEVEL_1_1:
caps = vpe11_get_capability();
break;
case VPE_IP_LEVEL_2_0:
caps = vpe20_get_capability();
break;
default:
caps = NULL;
@ -934,6 +1028,9 @@ void vpe_setup_check_funcs(struct vpe_check_support_funcs *funcs, enum vpe_ip_le
case VPE_IP_LEVEL_1_1:
vpe11_setup_check_funcs(funcs);
break;
case VPE_IP_LEVEL_2_0:
vpe20_setup_check_funcs(funcs);
break;
default:
break;
}

View file

@ -36,6 +36,18 @@ struct shaper_setup_out {
int end_base_fixed_0_14;
};
enum vpe_shaper_index_mode vpe_get_shaper_index_mode(
uint32_t is_dma, enum lut_dimension lut_dim, enum lut_dimension lut_container_dim)
{
// unitialized lut_container_dim will be treated as 33 dimension
if (is_dma && (lut_dim == LUT_DIM_17) &&
((lut_container_dim == LUT_DIM_33) || (lut_container_dim == LUT_DIM_INVALID))) {
return SHAPER_INDEX_MODE_17IN33LUT;
} else {
return SHAPER_INDEX_MODE_DEFAULT;
}
}
static unsigned int vpe_computer_shaper_pq_14u(double x, struct fixed31_32 normalized_factor)
{
unsigned output_fixpt_14u = 0x3fff;
@ -216,6 +228,11 @@ enum vpe_status vpe_build_shaper(const struct vpe_shaper_setup_in *shaper_in,
else if (!calculate_shaper_properties_variable_hdr_mult(shaper_in, &shaper_params))
goto release;
if (shaper_in->index_mode == SHAPER_INDEX_MODE_17IN33LUT) {
normalized_factor = vpe_fixpt_mul_int(normalized_factor, 2);
d_norm /= 2;
shaper_params.end_base_fixed_0_14 /= 2;
}
exp = shaper_params.exp_begin_raw;
num_exp = shaper_params.exp_end_raw - shaper_params.exp_begin_raw + 1;

View file

@ -0,0 +1,679 @@
/* Copyright 2024 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "vpe_spl_translation.h"
#include "color.h"
#include "vpe_hw_types.h"
#include "common.h"
const struct spl_sharpness_range SHARPNESS_RANGE = {
0, 1750, 750, // SDR RGB Min, Max, Mid
0, 3500, 1500, // SDR YUV Min, Max, Mid
0, 2750, 1500 // HDR RGB Min, Max, Mid
};
static void spl_rect_to_vpe_rect(struct spl_rect *spl_rect, struct vpe_rect *vpe_rect)
{
vpe_rect->height = spl_rect->height;
vpe_rect->width = spl_rect->width;
vpe_rect->x = spl_rect->x;
vpe_rect->y = spl_rect->y;
}
static void vpe_rect_to_spl_rect(struct vpe_rect *vpe_rect, struct spl_rect *spl_rect)
{
spl_rect->height = vpe_rect->height;
spl_rect->width = vpe_rect->width;
spl_rect->x = vpe_rect->x;
spl_rect->y = vpe_rect->y;
}
struct spl_rotation_mirror_map {
enum spl_rotation_angle rotation;
bool h_mirror;
};
static struct spl_rotation_mirror_map spl_scan_map[] = {
{SPL_ROTATION_ANGLE_0, false},
{SPL_ROTATION_ANGLE_270, false},
{SPL_ROTATION_ANGLE_180, false},
{SPL_ROTATION_ANGLE_90, false},
{SPL_ROTATION_ANGLE_0, true},
{SPL_ROTATION_ANGLE_270, true},
{SPL_ROTATION_ANGLE_180, true},
{SPL_ROTATION_ANGLE_90, true},
};
static void get_spl_rotation(
enum vpe_scan_direction scan_dir, enum spl_rotation_angle *spl_angle, bool *spl_h_mirror)
{
// VPE and DCN HW rotate in opposite directions.
// 90 degree rotation in VPE corresponds to 270 degree rotation in DCN,
// and vice versa.
*spl_angle = spl_scan_map[scan_dir].rotation;
*spl_h_mirror = spl_scan_map[scan_dir].h_mirror;
}
static enum chroma_cositing get_spl_cositing(enum vpe_chroma_cositing cositing)
{
switch (cositing) {
case VPE_CHROMA_COSITING_NONE:
return CHROMA_COSITING_NONE;
case VPE_CHROMA_COSITING_LEFT:
return CHROMA_COSITING_LEFT;
case VPE_CHROMA_COSITING_TOPLEFT:
return CHROMA_COSITING_TOPLEFT;
default:
VPE_ASSERT(false);
return CHROMA_COSITING_NONE;
}
}
static enum spl_pixel_format get_spl_format(enum vpe_surface_pixel_format fmt)
{
// 8/10/16 bit differences in formats does not affect SPL
switch (fmt) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
return SPL_PIXEL_FORMAT_RGB565;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
return SPL_PIXEL_FORMAT_ARGB8888;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
return SPL_PIXEL_FORMAT_ARGB2101010;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
return SPL_PIXEL_FORMAT_FP16;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
return SPL_PIXEL_FORMAT_420BPP8;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
return SPL_PIXEL_FORMAT_420BPP10;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
return SPL_PIXEL_FORMAT_422BPP8;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
return SPL_PIXEL_FORMAT_422BPP10;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
return SPL_PIXEL_FORMAT_444BPP8;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
return SPL_PIXEL_FORMAT_444BPP10;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
case VPE_SURFACE_PIXEL_FORMAT_INVALID:
return SPL_PIXEL_FORMAT_UNKNOWN;
default:
VPE_ASSERT(false);
return SPL_PIXEL_FORMAT_INVALID;
}
}
static enum spl_transfer_func_type get_spl_tf_type(enum transfer_func_type tf_type)
{
switch (tf_type) {
case TF_TYPE_PREDEFINED:
return SPL_TF_TYPE_PREDEFINED;
case TF_TYPE_DISTRIBUTED_POINTS:
return SPL_TF_TYPE_DISTRIBUTED_POINTS;
case TF_TYPE_BYPASS:
return SPL_TF_TYPE_BYPASS;
case TF_TYPE_HWPWL:
return SPL_TF_TYPE_HWPWL;
default:
VPE_ASSERT(false);
return SPL_TF_TYPE_PREDEFINED;
}
}
static enum spl_transfer_func_predefined get_spl_tf(enum color_transfer_func tf)
{
switch (tf) {
case TRANSFER_FUNC_SRGB:
return SPL_TRANSFER_FUNCTION_SRGB;
case TRANSFER_FUNC_BT709:
return SPL_TRANSFER_FUNCTION_BT709;
case TRANSFER_FUNC_BT1886:
return SPL_TRANSFER_FUNCTION_GAMMA24;
case TRANSFER_FUNC_PQ2084:
return SPL_TRANSFER_FUNCTION_PQ;
case TRANSFER_FUNC_LINEAR:
return SPL_TRANSFER_FUNCTION_LINEAR;
case TRANSFER_FUNC_NORMALIZED_PQ:
return SPL_TRANSFER_FUNCTION_UNITY;
case TRANSFER_FUNC_HLG:
return SPL_TRANSFER_FUNCTION_HLG;
default:
VPE_ASSERT(false);
return SPL_TRANSFER_FUNCTION_SRGB;
}
}
static enum spl_color_space get_spl_cs(enum color_space cs)
{
switch (cs) {
case COLOR_SPACE_SRGB:
case COLOR_SPACE_YCBCR_JFIF:
case COLOR_SPACE_RGB_JFIF:
return SPL_COLOR_SPACE_SRGB;
case COLOR_SPACE_SRGB_LIMITED:
return SPL_COLOR_SPACE_SRGB_LIMITED;
case COLOR_SPACE_MSREF_SCRGB:
return SPL_COLOR_SPACE_MSREF_SCRGB;
case COLOR_SPACE_YCBCR601:
case COLOR_SPACE_RGB601:
return SPL_COLOR_SPACE_YCBCR601;
case COLOR_SPACE_RGB601_LIMITED:
case COLOR_SPACE_YCBCR601_LIMITED:
return SPL_COLOR_SPACE_YCBCR601_LIMITED;
case COLOR_SPACE_YCBCR709:
return SPL_COLOR_SPACE_YCBCR709;
case COLOR_SPACE_YCBCR709_LIMITED:
return SPL_COLOR_SPACE_YCBCR709_LIMITED;
case COLOR_SPACE_2020_RGB_FULLRANGE:
return SPL_COLOR_SPACE_2020_RGB_FULLRANGE;
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
return SPL_COLOR_SPACE_2020_RGB_LIMITEDRANGE;
case COLOR_SPACE_2020_YCBCR:
case COLOR_SPACE_2020_YCBCR_LIMITED:
return SPL_COLOR_SPACE_2020_YCBCR;
default:
VPE_ASSERT(false);
return SPL_COLOR_SPACE_UNKNOWN;
}
}
static struct fixed31_32 spl_int_frac_to_fixpt(
uint32_t int_part, uint32_t frac_part, uint32_t shift_frac)
{
struct fixed31_32 fixed_pt = vpe_fixpt_zero;
fixed_pt = vpe_fixpt_from_int(int_part);
fixed_pt.value += (frac_part >> shift_frac);
return fixed_pt;
}
static struct fixed31_32 spl_ratio_to_fixpt(uint32_t ratio_u3d19)
{
uint32_t int_part;
uint32_t frac_part;
struct fixed31_32 fixed_pt = vpe_fixpt_zero;
ratio_u3d19 = ratio_u3d19 >> 5;
frac_part = ratio_u3d19 & 0x7FFFF;
int_part = (ratio_u3d19 >> 19) & 0x7;
fixed_pt = spl_int_frac_to_fixpt(int_part, frac_part, 0);
return fixed_pt;
}
static struct fixed31_32 spl_init_to_fixpt(
uint32_t int_part, uint32_t frac_part, uint32_t shift_frac)
{
return spl_int_frac_to_fixpt(int_part, frac_part, 5);
}
static void set_clip_rect(
struct spl_rect *spl_clip_rect, struct vpe_rect dst_rect, struct vpe_rect clipped_dst_rect)
{
spl_clip_rect->x = clipped_dst_rect.x - dst_rect.x;
spl_clip_rect->y = clipped_dst_rect.y - dst_rect.y;
spl_clip_rect->width = clipped_dst_rect.width;
spl_clip_rect->height = clipped_dst_rect.height;
}
void vpe_spl_scl_to_vpe_scl(struct spl_out *spl_out, struct scaler_data *vpe_scl_data)
{
// taps
vpe_scl_data->taps.v_taps = spl_out->dscl_prog_data->taps.v_taps + 1;
vpe_scl_data->taps.h_taps = spl_out->dscl_prog_data->taps.h_taps + 1;
vpe_scl_data->taps.h_taps_c = spl_out->dscl_prog_data->taps.h_taps_c + 1;
vpe_scl_data->taps.v_taps_c = spl_out->dscl_prog_data->taps.v_taps_c + 1;
// viewport
spl_rect_to_vpe_rect(&spl_out->dscl_prog_data->viewport, &vpe_scl_data->viewport);
spl_rect_to_vpe_rect(&spl_out->dscl_prog_data->viewport_c, &vpe_scl_data->viewport_c);
// recout
spl_rect_to_vpe_rect(&spl_out->dscl_prog_data->recout, &vpe_scl_data->recout);
// ratios
vpe_scl_data->ratios.horz = spl_ratio_to_fixpt(spl_out->dscl_prog_data->ratios.h_scale_ratio);
vpe_scl_data->ratios.vert = spl_ratio_to_fixpt(spl_out->dscl_prog_data->ratios.v_scale_ratio);
vpe_scl_data->ratios.horz_c =
spl_ratio_to_fixpt(spl_out->dscl_prog_data->ratios.h_scale_ratio_c);
vpe_scl_data->ratios.vert_c =
spl_ratio_to_fixpt(spl_out->dscl_prog_data->ratios.v_scale_ratio_c);
// inits
vpe_scl_data->inits.h = spl_init_to_fixpt(spl_out->dscl_prog_data->init.h_filter_init_int,
spl_out->dscl_prog_data->init.h_filter_init_frac, 5);
vpe_scl_data->inits.v = spl_init_to_fixpt(spl_out->dscl_prog_data->init.v_filter_init_int,
spl_out->dscl_prog_data->init.v_filter_init_frac, 5);
vpe_scl_data->inits.h_c = spl_init_to_fixpt(spl_out->dscl_prog_data->init.h_filter_init_int_c,
spl_out->dscl_prog_data->init.h_filter_init_frac_c, 5);
vpe_scl_data->inits.v_c = spl_init_to_fixpt(spl_out->dscl_prog_data->init.v_filter_init_int_c,
spl_out->dscl_prog_data->init.v_filter_init_frac_c, 5);
}
struct vp_scan_direction {
bool orthogonal_rotation;
bool flip_horz_scan_dir;
bool flip_vert_scan_dir;
};
static const struct vp_scan_direction
vp_scan_direction[VPE_ROTATION_ANGLE_COUNT][2][2] =
{
{
// VPE_ROTATION_ANGLE_0
[false] =
{
// h_mirror = false
[false] = {false, false, false},
[true] = {false, false, true},
},
[true] =
{
// h_mirror = true
[false] = {false, true, false},
[true] = {false, true, true},
},
},
{
// VPE_ROTATION_ANGLE_90
[false] =
{
[false] = {true, false, true},
[true] = {true, true, true},
},
[true] =
{
[false] = {true, false, false},
[true] = {true, true, false},
},
},
{
// VPE_ROTATION_ANGLE_180
[false] =
{
[false] = {false, true, true},
[true] = {false, true, false},
},
[true] =
{
[false] = {false, false, true},
[true] = {false, false, false},
},
},
{
// VPE_ROTATION_ANGLE_270
[false] =
{
[false] = {true, true, false},
[true] = {true, false, false},
},
[true] =
{
[false] = {true, true, true},
[true] = {true, false, true},
},
},
};
void vpe_get_vp_scan_direction(enum vpe_rotation_angle degree, bool h_mirror, bool v_mirror,
bool *orthogonal_rotation, bool *flip_horz_scan_dir, bool *flip_vert_scan_dir)
{
struct vp_scan_direction res = vp_scan_direction[degree][h_mirror][v_mirror];
*orthogonal_rotation = res.orthogonal_rotation;
*flip_vert_scan_dir = res.flip_vert_scan_dir;
*flip_horz_scan_dir = res.flip_horz_scan_dir;
}
static void determine_opp_recout_adjust(struct spl_in *spl_input, struct stream_ctx *stream_ctx,
struct output_ctx *output_ctx, const struct vpe_rect *clipped_src_rect,
const struct vpe_rect *clipped_dst_rect)
{
struct vpe_caps *caps = stream_ctx->vpe_priv->pub.caps;
struct opp *opp = stream_ctx->vpe_priv->resource.opp[0];
struct fmt_extra_pixel_info extra_info;
bool dst_subsampled = vpe_is_subsampled_format(output_ctx->surface.format);
memset(&spl_input->basic_in.opp_recout_adjust, 0, sizeof(struct spl_opp_adjust));
opp->funcs->get_fmt_extra_pixel(output_ctx->surface.format,
stream_ctx->vpe_priv->init.debug.subsampling_quality,
(enum chroma_cositing)output_ctx->surface.cs.cositing, &extra_info);
if (dst_subsampled) {
bool orthogonal, flip_horz, flip_vert;
struct vpe_scaling_info *scaling_info = &stream_ctx->stream.scaling_info;
struct vpe_rect surf_src = *clipped_src_rect;
struct fixed31_32 h_ratio, temp;
int32_t offset;
vpe_get_vp_scan_direction(stream_ctx->stream.rotation, stream_ctx->stream.horizontal_mirror,
stream_ctx->stream.vertical_mirror, &orthogonal, &flip_horz, &flip_vert);
if (orthogonal) {
swap(surf_src.width, surf_src.height);
}
h_ratio = vpe_fixpt_from_fraction(surf_src.width, clipped_dst_rect->width);
// see if the LEFT most needs more for output boundary handling, left needs 2 extra
temp = vpe_fixpt_mul_int(h_ratio, extra_info.left_pixels);
offset = (int32_t)vpe_fixpt_floor(temp);
// default is REPEAT - destination stream is set manually beforehand
if (stream_ctx->stream_type != VPE_STREAM_TYPE_DESTINATION) {
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_REPEAT;
stream_ctx->right = FMT_SUBSAMPLING_BOUNDARY_REPEAT;
}
if (offset != 0) {
if (orthogonal) {
if (flip_vert) {
// i.e. left is at the bottom, check if it is out of bound
if ((clipped_src_rect->y + clipped_src_rect->height + offset) <=
(scaling_info->src_rect.y + scaling_info->src_rect.height)) {
/* can not directly modify the clipped_src_rect and clipped_dst_rect as it
* will break the recout alignment partitioning in spl becoz it assumes
* clipped_dst_rect is the same after opp */
spl_input->basic_in.opp_recout_adjust.width += extra_info.left_pixels;
spl_input->basic_in.opp_recout_adjust.x -= extra_info.left_pixels;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
} else {
// i.e. left is at the top, check if it is out of bound
if ((clipped_src_rect->y - scaling_info->src_rect.y) >= offset) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.left_pixels;
spl_input->basic_in.opp_recout_adjust.x -= extra_info.left_pixels;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
}
} else {
if (!flip_horz) {
if ((clipped_src_rect->x - scaling_info->src_rect.x) >= offset) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.left_pixels;
spl_input->basic_in.opp_recout_adjust.x -= extra_info.left_pixels;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
} else {
// right is left instead
if ((clipped_src_rect->x + clipped_src_rect->width + offset) <=
(scaling_info->src_rect.x + scaling_info->src_rect.width)) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.left_pixels;
spl_input->basic_in.opp_recout_adjust.x -= extra_info.left_pixels;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
}
}
}
// see if the RIGHT most needs more for output boundary handling, right needs 1 extra
temp = vpe_fixpt_mul_int(h_ratio, extra_info.right_pixels);
offset = vpe_fixpt_floor(temp);
if (offset != 0) {
if (orthogonal) {
if (flip_vert) {
// right is at the top
if ((clipped_src_rect->y - scaling_info->src_rect.y) >= offset) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.right_pixels;
stream_ctx->right = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
} else {
// right is at the bottom
if ((clipped_src_rect->y + clipped_src_rect->height + offset) <=
(scaling_info->src_rect.y + scaling_info->src_rect.height)) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.right_pixels;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
}
} else {
if (!flip_horz) {
if ((clipped_src_rect->x + clipped_src_rect->width + offset) <=
(scaling_info->src_rect.x + scaling_info->src_rect.width)) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.right_pixels;
stream_ctx->right = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
} else {
// left is right instead
if ((clipped_src_rect->x - scaling_info->src_rect.x) >= offset) {
spl_input->basic_in.opp_recout_adjust.width += extra_info.right_pixels;
stream_ctx->right = FMT_SUBSAMPLING_BOUNDARY_EXTRA;
}
}
}
}
} else {
stream_ctx->right = FMT_SUBSAMPLING_BOUNDARY_REPEAT;
stream_ctx->left = FMT_SUBSAMPLING_BOUNDARY_REPEAT;
}
}
void vpe_init_spl_in(
struct spl_in *spl_input, struct stream_ctx *stream_ctx, struct output_ctx *output_ctx)
{
enum color_space in_cs, out_cs;
enum color_transfer_func in_tf, out_tf;
struct vpe_rect clipped_src_rect;
struct vpe_rect clipped_dst_rect;
struct vpe_scaling_info *scaling_info = &stream_ctx->stream.scaling_info;
vpe_color_get_color_space_and_tf(&stream_ctx->stream.surface_info.cs, &in_cs, &in_tf);
vpe_color_get_color_space_and_tf(
&stream_ctx->vpe_priv->output_ctx.surface.cs, &out_cs, &out_tf);
/** Since the active values just set the mpc_size in SPL and vpelib calculates the mpc_size
* for each segment after the SPL call for segmentation, the active values does not affect the
* segmentation. Therefore, zero is set for the initialization to avoid NAN assignement.
*
* in vpe, we do not have mpc combine output from multiple input streams
* as such, we could not specify all output-related rect to use final coordinates,
* all output related rects are relative to the {0, 0 , dst_width, dst_height} only
*/
spl_input->h_active = 0;
spl_input->v_active = 0;
// BASIC_OUT
clipped_src_rect = scaling_info->src_rect;
clipped_dst_rect = scaling_info->dst_rect;
vpe_clip_stream(&clipped_src_rect, &clipped_dst_rect, &output_ctx->target_rect);
determine_opp_recout_adjust(
spl_input, stream_ctx, output_ctx, &clipped_src_rect, &clipped_dst_rect);
// struct spl_size output_size; // Output Size
spl_input->basic_out.output_size.width = scaling_info->dst_rect.width;
spl_input->basic_out.output_size.height = scaling_info->dst_rect.height;
// do not have 2-stages scaling concept in usage, set basic_out src_rect = dst_rect
spl_input->basic_out.src_rect.x = 0;
spl_input->basic_out.src_rect.y = 0;
spl_input->basic_out.src_rect.width = scaling_info->dst_rect.width;
spl_input->basic_out.src_rect.height = scaling_info->dst_rect.height;
spl_input->basic_out.dst_rect = spl_input->basic_out.src_rect;
// int odm_combine_factor; // deprecated
spl_input->basic_out.odm_combine_factor = 1;
spl_input->basic_out.alpha_en = stream_ctx->per_pixel_alpha;
// BASIC_IN
// enum spl_pixel_format format; // Pixel Format
spl_input->basic_in.format = get_spl_format(stream_ctx->stream.surface_info.format);
// enum chroma_cositing cositing; /* Chroma Subsampling Offset */
spl_input->basic_in.cositing = get_spl_cositing(stream_ctx->stream.surface_info.cs.cositing);
if (stream_ctx->stream.lut_compound.enabled) {
// In 3DLUT compound case, cs is "custom" with no cositing info
// It is provided separately via lut_compound.chroma_cositing
spl_input->basic_in.cositing =
get_spl_cositing(stream_ctx->stream.lut_compound.upsampled_chroma_input);
} else if (vpe_is_yuv422(stream_ctx->stream.surface_info.format)) {
// Force TOPLEFT cositing for 422 as other cositing modes have vertical adjustment
spl_input->basic_in.cositing = CHROMA_COSITING_TOPLEFT;
}
// struct spl_rect src_rect; // Source rect
vpe_rect_to_spl_rect(&scaling_info->src_rect, &spl_input->basic_in.src_rect);
// struct spl_rect dst_rect; // Destination Rect
// spl shall only know the relative location of the output.
// the final absolute destination rect is adjusted in calculate_dst_viewport_and_active
spl_input->basic_in.dst_rect.x = 0;
spl_input->basic_in.dst_rect.y = 0;
spl_input->basic_in.dst_rect.width = scaling_info->dst_rect.width;
spl_input->basic_in.dst_rect.height = scaling_info->dst_rect.height;
// enum spl_rotation_angle rotation; // Rotation
// bool horizontal_mirror; // Horizontal mirror
get_spl_rotation(vpe_get_scan_direction(stream_ctx->stream.rotation,
stream_ctx->stream.horizontal_mirror, stream_ctx->stream.vertical_mirror),
&spl_input->basic_in.rotation, &spl_input->basic_in.horizontal_mirror);
// int mpc_num_h_slices; // MPC Horizontal Combine Factor (number of segments/horizintal slices)
spl_input->basic_in.num_h_slices_recout_width_align.use_recout_width_aligned = false;
spl_input->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_num_h_slices =
stream_ctx->num_segments;
// enum spl_transfer_func_type tf_type; /* Transfer function type */
spl_input->basic_in.tf_type = SPL_TF_TYPE_DISTRIBUTED_POINTS;
// enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */
spl_input->basic_in.tf_predefined_type = get_spl_tf(in_tf);
// enum spl_color_space color_space; // Color Space
spl_input->basic_in.color_space = get_spl_cs(in_cs);
// unsigned int max_luminance; // Max Luminance
spl_input->basic_in.max_luminance = 80;
// struct spl_rect clip_rect; // Clip rect
set_clip_rect(&spl_input->basic_in.clip_rect, scaling_info->dst_rect, clipped_dst_rect);
// int odm_slice_index; // ODM Slice Index using get_odm_split_index
spl_input->odm_slice_index = 0;
// struct spl_taps scaling_quality; // Explicit Scaling Quality
spl_input->scaling_quality.v_taps = scaling_info->taps.v_taps;
spl_input->scaling_quality.h_taps = scaling_info->taps.h_taps;
spl_input->scaling_quality.v_taps_c = scaling_info->taps.v_taps_c;
spl_input->scaling_quality.h_taps_c = scaling_info->taps.h_taps_c;
spl_input->scaling_quality.integer_scaling = false;
spl_input->is_hdr_on = vpe_is_HDR(out_tf);
spl_input->adaptive_sharpness.enable = scaling_info->adaptive_sharpeness.enable;
spl_input->adaptive_sharpness.sharpness_level =
scaling_info->adaptive_sharpeness.sharpness_level;
spl_input->adaptive_sharpness.sharpness_range = SHARPNESS_RANGE; // to be passed by the caller
spl_input->sharpen_policy = SHARPEN_ALWAYS;
spl_input->disable_easf = !scaling_info->enable_easf;
spl_input->prefer_easf = scaling_info->prefer_easf;
if (vpe_is_subsampled_format(stream_ctx->stream.surface_info.format)) {
spl_input->min_viewport_size = 2;
} else {
spl_input->min_viewport_size = 1;
}
}
void vpe_scl_to_dscl_bg(struct scaler_data *scl_data)
{
// struct spl_rect recout;
vpe_rect_to_spl_rect(&scl_data->recout, &scl_data->dscl_prog_data.recout);
// struct mpc_size mpc_size;
scl_data->dscl_prog_data.mpc_size.width = scl_data->h_active;
scl_data->dscl_prog_data.mpc_size.height = scl_data->v_active;
// struct ratio ratios;
scl_data->dscl_prog_data.ratios.h_scale_ratio = vpe_fixpt_u3d19(scl_data->ratios.horz) << 5;
scl_data->dscl_prog_data.ratios.v_scale_ratio = vpe_fixpt_u3d19(scl_data->ratios.vert) << 5;
scl_data->dscl_prog_data.ratios.h_scale_ratio_c = vpe_fixpt_u3d19(scl_data->ratios.horz_c) << 5;
scl_data->dscl_prog_data.ratios.v_scale_ratio_c = vpe_fixpt_u3d19(scl_data->ratios.vert_c) << 5;
// struct init init;
scl_data->dscl_prog_data.init.h_filter_init_frac = vpe_fixpt_u0d19(scl_data->inits.h) << 5;
scl_data->dscl_prog_data.init.h_filter_init_int = vpe_fixpt_floor(scl_data->inits.h);
scl_data->dscl_prog_data.init.h_filter_init_frac_c = vpe_fixpt_u0d19(scl_data->inits.h_c) << 5;
scl_data->dscl_prog_data.init.h_filter_init_int_c = vpe_fixpt_floor(scl_data->inits.h_c);
scl_data->dscl_prog_data.init.v_filter_init_frac = vpe_fixpt_u0d19(scl_data->inits.v) << 5;
scl_data->dscl_prog_data.init.v_filter_init_int = vpe_fixpt_floor(scl_data->inits.v);
scl_data->dscl_prog_data.init.v_filter_init_frac_c = vpe_fixpt_u0d19(scl_data->inits.v_c) << 5;
scl_data->dscl_prog_data.init.v_filter_init_int_c = vpe_fixpt_floor(scl_data->inits.v_c);
// struct spl_taps taps; // TAPS - set based on scl_data.taps
scl_data->dscl_prog_data.taps.h_taps = scl_data->taps.h_taps - 1;
scl_data->dscl_prog_data.taps.v_taps = scl_data->taps.v_taps - 1;
scl_data->dscl_prog_data.taps.h_taps_c = scl_data->taps.h_taps_c - 1;
scl_data->dscl_prog_data.taps.v_taps_c = scl_data->taps.v_taps_c - 1;
// struct spl_rect viewport;
vpe_rect_to_spl_rect(&scl_data->viewport, &scl_data->dscl_prog_data.viewport);
// struct spl_rect viewport_c;
vpe_rect_to_spl_rect(&scl_data->viewport_c, &scl_data->dscl_prog_data.viewport_c);
}

View file

@ -66,6 +66,8 @@ static uint16_t vpe_get_visual_confirm_total_seg_count(
uint16_t stream_idx;
struct stream_ctx *stream_ctx;
uint32_t alignment = vpe_get_recout_width_alignment(params);
struct vpe_cmd_info *cmd_info;
uint16_t cmd_idx;
if (vpe_priv->init.debug.visual_confirm_params.input_format) {
for (stream_idx = 0; stream_idx < (uint16_t)vpe_priv->num_streams; stream_idx++) {
@ -81,9 +83,59 @@ static uint16_t vpe_get_visual_confirm_total_seg_count(
get_visual_confirm_segs_count(max_seg_width, params->target_rect.width, alignment);
}
if (vpe_priv->init.debug.visual_confirm_params.pipe_idx) {
cmd_info = vpe_priv->vpe_cmd_vector->element;
for (cmd_idx = 0; cmd_idx < (uint16_t)vpe_priv->vpe_cmd_vector->num_elements; cmd_idx++) {
total_visual_confirm_segs += cmd_info->num_inputs;
cmd_info++;
}
}
return total_visual_confirm_segs;
}
static void generate_pipe_segments(struct vpe_priv *vpe_priv, const struct vpe_build_param *params,
struct vpe_rect *current_gap, uint32_t max_seg_width)
{
uint16_t cmd_idx, input_idx, seg_cnt;
struct vpe_cmd_info *cmd_info;
struct vpe_rect visual_confirm_rect;
uint32_t recout_alignment = vpe_get_recout_width_alignment(params);
if (vpe_priv->init.debug.visual_confirm_params.pipe_idx &&
params->target_rect.height > 3 * VISUAL_CONFIRM_HEIGHT) {
cmd_info = vpe_priv->vpe_cmd_vector->element;
for (cmd_idx = 0; cmd_idx < (uint16_t)vpe_priv->vpe_cmd_vector->num_elements; cmd_idx++) {
if (cmd_info->ops == VPE_CMD_OPS_BG_VSCF_INPUT ||
cmd_info->ops == VPE_CMD_OPS_BG_VSCF_OUTPUT ||
cmd_info->ops == VPE_CMD_OPS_BG_VSCF_PIPE0 ||
cmd_info->ops == VPE_CMD_OPS_BG_VSCF_PIPE1) {
cmd_info++;
continue;
}
for (input_idx = 0; input_idx < cmd_info->num_inputs; input_idx++) {
visual_confirm_rect = cmd_info->inputs[input_idx].scaler_data.dst_viewport;
visual_confirm_rect.height = VISUAL_CONFIRM_HEIGHT;
visual_confirm_rect.y += 2 * VISUAL_CONFIRM_HEIGHT;
seg_cnt = get_visual_confirm_segs_count(
max_seg_width, visual_confirm_rect.width, recout_alignment);
vpe_full_bg_gaps(current_gap, &visual_confirm_rect, recout_alignment, seg_cnt);
if (input_idx == 0) {
vpe_priv->resource.create_bg_segments(
vpe_priv, current_gap, seg_cnt, VPE_CMD_OPS_BG_VSCF_PIPE0);
} else if (input_idx == 1) {
vpe_priv->resource.create_bg_segments(
vpe_priv, current_gap, seg_cnt, VPE_CMD_OPS_BG_VSCF_PIPE1);
} else {
VPE_ASSERT(0);
}
current_gap += seg_cnt;
}
cmd_info++;
}
}
}
struct vpe_color vpe_get_visual_confirm_color(struct vpe_priv *vpe_priv,
enum vpe_surface_pixel_format format, struct vpe_color_space cs, enum color_space output_cs,
struct transfer_func *output_tf, enum vpe_surface_pixel_format output_format, bool enable_3dlut)
@ -99,6 +151,7 @@ struct vpe_color vpe_get_visual_confirm_color(struct vpe_priv *vpe_priv,
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA:
// YUV420 8bit: Green
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 1.0;
@ -165,6 +218,121 @@ struct vpe_color vpe_get_visual_confirm_color(struct vpe_priv *vpe_priv,
visual_confirm_color.rgba.g = 0.65f;
visual_confirm_color.rgba.b = 0.0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_12bpc_YCbCr:
// P016 : Dark Green
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 0.35f;
visual_confirm_color.rgba.b = 0.0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_UNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616_SNORM:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616_SNORM:
// RGB16 and variants: Blue
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 0.0;
visual_confirm_color.rgba.b = 1.0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R8:
// Monochrome 8 bit: Silver
visual_confirm_color.rgba.r = 0.753f;
visual_confirm_color.rgba.g = 0.753f;
visual_confirm_color.rgba.b = 0.753f;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_R16:
// Monochrome 16 bit: Dim Gray
visual_confirm_color.rgba.r = 0.412f;
visual_confirm_color.rgba.g = 0.412f;
visual_confirm_color.rgba.b = 0.412f;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_YCbCr:
// YUY2: Misty Rose
visual_confirm_color.rgba.r = 0.412f;
visual_confirm_color.rgba.g = 0.894f;
visual_confirm_color.rgba.b = 0.882f;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbCr:
// Y210: Salmon
visual_confirm_color.rgba.r = 0.412f;
visual_confirm_color.rgba.g = 0.627f;
visual_confirm_color.rgba.b = 0.478f;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbCr:
// Y216: Maroon
visual_confirm_color.rgba.r = 0.5;
visual_confirm_color.rgba.g = 0.0;
visual_confirm_color.rgba.b = 0.0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrCbYA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
// AYUV: Aqua Marine
visual_confirm_color.rgba.r = 0.5;
visual_confirm_color.rgba.g = 1.0;
visual_confirm_color.rgba.b = 0.8f;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
// Y410: Dark Cyan
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 0.5;
visual_confirm_color.rgba.b = 0.5;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb12121212:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA12121212:
// Y416: Navy
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 0.0;
visual_confirm_color.rgba.b = 0.5;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_RGB:
// Planar RGB8: Lavender
visual_confirm_color.rgba.r = 0.9f;
visual_confirm_color.rgba.g = 0.9f;
visual_confirm_color.rgba.b = 0.98f;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_8bpc_YCbCr:
// Planar YCbCr8: Chocolate
visual_confirm_color.rgba.r = 0.824f;
visual_confirm_color.rgba.g = 0.412f;
visual_confirm_color.rgba.b = 0.118f;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_RGB:
// Planar RGB16: Rosy Brown
visual_confirm_color.rgba.r = 0.737f;
visual_confirm_color.rgba.g = 0.56f;
visual_confirm_color.rgba.b = 0.56f;
break;
case VPE_SURFACE_PIXEL_FORMAT_PLANAR_16bpc_YCbCr:
// Planar YCbCr16: Saddle Brown
visual_confirm_color.rgba.r = 0.545f;
visual_confirm_color.rgba.g = 0.271f;
visual_confirm_color.rgba.b = 0.075f;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
// RGBE: Olive
visual_confirm_color.rgba.r = 0.5;
visual_confirm_color.rgba.g = 0.5;
visual_confirm_color.rgba.b = 0.0;
break;
default:
break;
}
@ -236,6 +404,8 @@ enum vpe_status vpe_create_visual_confirm_segs(
current_gap += seg_cnt;
}
generate_pipe_segments(vpe_priv, params, current_gap, max_seg_width);
if (visual_confirm_gaps != NULL) {
vpe_free(visual_confirm_gaps);
visual_confirm_gaps = NULL;

View file

@ -40,6 +40,7 @@
#include <stdlib.h>
#include <time.h>
#include <vpe_command.h>
#include "multi_pipe_segmentation.h"
static void dummy_sys_event(enum vpe_event_id eventId, ...)
{
@ -135,6 +136,11 @@ static void override_debug_option(
if (user_debug->flags.disable_performance_mode)
debug->disable_performance_mode = user_debug->disable_performance_mode;
if (user_debug->flags.subsampling_quality)
debug->subsampling_quality = user_debug->subsampling_quality;
if (user_debug->flags.disable_3dlut_fl)
debug->disable_3dlut_fl = user_debug->disable_3dlut_fl;
}
static void verify_collaboration_mode(struct vpe_priv *vpe_priv)
@ -189,6 +195,9 @@ static void free_output_ctx(struct vpe_priv *vpe_priv)
vpe_free(vpe_priv->output_ctx.output_tf);
vpe_priv->output_ctx.output_tf = NULL;
if (vpe_priv->output_ctx.out_csc_matrix)
vpe_free(vpe_priv->output_ctx.out_csc_matrix);
vpe_priv->output_ctx.out_csc_matrix = NULL;
destroy_output_config_vector(vpe_priv);
}
@ -295,6 +304,8 @@ struct vpe *vpe_create(const struct vpe_init_data *params)
vpe_priv->scale_yuv_matrix = true;
vpe_priv->collaborate_sync_index = 0;
if (vpe_priv->init.debug.disable_3dlut_fl) /* disable DMA 3D LUT support for debugging */
vpe_priv->pub.caps->color_caps.mpc.dma_3d_lut = 0;
return &vpe_priv->pub;
}
@ -333,6 +344,81 @@ void vpe_destroy(struct vpe **vpe)
*vpe = NULL;
}
/*****************************************************************************************
* populate_destination_stream
* populate destination stream for multi-pass blending
* struct vpe* vpe
* [input] vpe context
* const struct vpe_build_param* param
* [input] original parameter from caller
* struct struct vpe_stream_ctx* stream_ctx
* [input/output] caller provided vpe_stream_ctx struct to populate
*****************************************************************************************/
static enum vpe_status populate_destination_stream(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param, struct stream_ctx *stream_ctx)
{
struct vpe_surface_info *surface_info;
struct vpe_scaling_info *scaling_info;
struct vpe_scaling_filter_coeffs *polyphaseCoeffs;
struct vpe_stream *stream;
struct output_ctx *output_ctx;
if (!param || !stream_ctx)
return VPE_STATUS_ERROR;
stream = &stream_ctx->stream;
output_ctx = &vpe_priv->output_ctx;
stream_ctx->stream_type = VPE_STREAM_TYPE_DESTINATION;
// set output surface as our destination input
surface_info = &stream->surface_info;
scaling_info = &stream->scaling_info;
polyphaseCoeffs = &stream->polyphase_scaling_coeffs;
memcpy(&stream->surface_info, &output_ctx->surface, sizeof(struct vpe_surface_info));
stream_ctx->cs = output_ctx->cs;
scaling_info->src_rect.x = param->target_rect.x;
scaling_info->src_rect.y = param->target_rect.y;
scaling_info->src_rect.width = param->target_rect.width;
scaling_info->src_rect.height = param->target_rect.height;
scaling_info->dst_rect.x = param->target_rect.x;
scaling_info->dst_rect.y = param->target_rect.y;
scaling_info->dst_rect.width = param->target_rect.width;
scaling_info->dst_rect.height = param->target_rect.height;
scaling_info->taps.v_taps = 0;
scaling_info->taps.h_taps = 0;
scaling_info->taps.v_taps_c = 0;
scaling_info->taps.h_taps_c = 0;
polyphaseCoeffs->taps = scaling_info->taps;
polyphaseCoeffs->nb_phases = 64;
stream->blend_info.blending = false;
stream->blend_info.pre_multiplied_alpha = false;
stream->blend_info.global_alpha = true;
stream->blend_info.global_alpha_value = 1.0f;
stream->color_adj.brightness = 0.0f;
stream->color_adj.contrast = 1.0f;
stream->color_adj.hue = 0.0f;
stream->color_adj.saturation = 1.0f;
stream->rotation = VPE_ROTATION_ANGLE_0;
stream->horizontal_mirror = false;
stream->vertical_mirror = false;
stream->enable_luma_key = false;
stream->lower_luma_bound = 0;
stream->upper_luma_bound = 0;
stream->hdr_metadata = output_ctx->hdr_metadata;
stream->flags.hdr_metadata = 1;
stream->flags.geometric_scaling = 0;
stream->use_external_scaling_coeffs = false;
return VPE_STATUS_OK;
}
/*****************************************************************************************
* populate_bg_stream
* populate virtual stream for background output only
@ -423,12 +509,21 @@ static enum vpe_status populate_bg_stream(struct vpe_priv *vpe_priv, const struc
static uint32_t get_required_virtual_stream_count(struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
uint32_t result = 0;
uint32_t i;
// Check for zero-input background stream
// Normally we result++ instead of returning, but bg_color_fill_only removes other streams (and therefore other features)
if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only)
return 1;
// Check for destination stream for multi-pass blending
for (i = 1; i < param->num_streams; i++) {
if (param->streams[i].blend_info.blending) {
result++;
break;
}
}
return result;
}
@ -444,6 +539,46 @@ static enum vpe_status populate_input_streams(struct vpe_priv *vpe_priv, const s
for (i = 0; i < vpe_priv->num_input_streams; i++) {
stream_ctx = &stream_ctx_base[i];
stream_ctx->stream_type = VPE_STREAM_TYPE_INPUT;
// BGR feature streams
if (param->streams[i].flags.is_alpha_combine) {
// Stream is part of bg replace feature
if (!vpe_has_per_pixel_alpha(vpe_priv->output_ctx.surface.format)) {
// Output surface must support alpha if we are doing bg replace
return VPE_STATUS_PARAM_CHECK_ERROR;
}
if (param->streams[i].flags.is_alpha_plane) {
if (param->streams[i].surface_info.format !=
VPE_SURFACE_PIXEL_FORMAT_VIDEO_ALPHA_THRU_LUMA)
return VPE_STATUS_PARAM_CHECK_ERROR;
stream_ctx->stream_type = VPE_STREAM_TYPE_BKGR_ALPHA;
if (vpe_priv->num_input_streams <= i + 2)
// Sanity check: Check we pass in enough planes for bg replace (this + 2)
return VPE_STATUS_PARAM_CHECK_ERROR;
else if (param->streams[i + VPE_BKGR_STREAM_VIDEO_OFFSET].flags.is_alpha_combine ==
0 ||
param->streams[i + VPE_BKGR_STREAM_BACKGROUND_OFFSET]
.flags.is_background_plane == 0)
// Sanity check: Check we pass in video stream next
return VPE_STATUS_PARAM_CHECK_ERROR;
} else if (param->streams[i].flags.is_background_plane) {
stream_ctx->stream_type = VPE_STREAM_TYPE_BKGR_BACKGROUND;
if (i < 2)
return VPE_STATUS_PARAM_CHECK_ERROR;
else if (param->streams[i - VPE_BKGR_STREAM_BACKGROUND_OFFSET]
.flags.is_alpha_plane == false ||
param->streams[i - VPE_BKGR_STREAM_VIDEO_OFFSET].flags.is_alpha_combine ==
false)
// Sanity check: Ensure two previous streams are part of BGR op
return VPE_STATUS_PARAM_CHECK_ERROR;
} else {
stream_ctx->stream_type = VPE_STREAM_TYPE_BKGR_VIDEO;
}
}
if (vpe_validate_hist_collection(&param->streams[i]) == false) {
return VPE_INVALID_HISTOGRAM_SELECTION;
}
stream_ctx->stream_idx = (int32_t)i;
stream_ctx->per_pixel_alpha =
@ -462,6 +597,13 @@ static enum vpe_status populate_input_streams(struct vpe_priv *vpe_priv, const s
stream_ctx->flip_horizonal_output = false;
memcpy(&stream_ctx->stream, &param->streams[i], sizeof(struct vpe_stream));
if (stream_ctx->stream_type == VPE_STREAM_TYPE_BKGR_ALPHA) {
stream_ctx->stream.blend_info.blending = true;
stream_ctx->per_pixel_alpha = true;
} else if (stream_ctx->stream_type == VPE_STREAM_TYPE_BKGR_BACKGROUND) {
stream_ctx->stream.blend_info.blending = true;
stream_ctx->per_pixel_alpha = true;
}
}
return result;
@ -473,6 +615,7 @@ static enum vpe_status populate_virtual_streams(struct vpe_priv* vpe_priv, const
uint32_t virtual_stream_idx = 0;
struct stream_ctx *stream_ctx;
bool input_h_mirror, output_h_mirror;
uint32_t i;
vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror);
@ -484,6 +627,18 @@ static enum vpe_status populate_virtual_streams(struct vpe_priv* vpe_priv, const
result = populate_bg_stream(vpe_priv, param, &stream_ctx_base[virtual_stream_idx++]);
}
if (result != VPE_STATUS_OK)
return result;
// Destination stream for multi-pass blending
for (i = 1; i < param->num_streams; i++) {
if (param->streams[i].blend_info.blending) {
result = populate_destination_stream(
vpe_priv, param, &stream_ctx_base[virtual_stream_idx++]);
break;
}
}
if (result != VPE_STATUS_OK)
return result;
@ -564,6 +719,10 @@ enum vpe_status vpe_check_support(
vpe_log("fail alplha fill check. status %d\n", (int)status);
}
}
for (i = 0; i < param->num_streams; i++)
if (vpe_priv->stream_ctx != NULL)
if (vpe_priv->stream_ctx[i].mps_ctx)
vpe_clear_mps_ctx(vpe_priv, vpe_priv->stream_ctx[i].mps_ctx);
if (status == VPE_STATUS_OK) {
// output checking - check per asic support
@ -594,6 +753,19 @@ enum vpe_status vpe_check_support(
break;
}
// input checking - check 3dlut compound support
status = vpe_check_3dlut_compound(vpe, &param->streams[i], param);
if (status != VPE_STATUS_OK) {
vpe_log("fail 3dlut support check. status %d\n", (int)status);
break;
}
// histogram support check
status = vpe_check_histogram_support(vpe, &param->streams[i]);
if (status != VPE_STATUS_OK) {
vpe_log("fail histogram support check. status %d\n", (int)status);
break;
}
}
}
if (status == VPE_STATUS_OK) {
@ -610,6 +782,17 @@ enum vpe_status vpe_check_support(
vpe_vector_clear(vpe_priv->vpe_cmd_vector);
output_ctx->clamping_params = vpe_priv->init.debug.clamping_params;
}
if (status == VPE_STATUS_OK && param->frod_param.enable_frod) {
if (vpe->caps->frod_support) {
status = vpe_priv->resource.populate_frod_param(vpe_priv, param);
if (status != VPE_STATUS_OK) {
vpe_log("fail frod support check. status %d\n", (int)status);
}
} else {
status = VPE_STATUS_FROD_NOT_SUPPORTED;
vpe_log("fail frod support check. status %d\n", (int)status);
}
}
if (status == VPE_STATUS_OK) {
status = populate_input_streams(vpe_priv, param, vpe_priv->stream_ctx);

View file

@ -0,0 +1,33 @@
#
# Copyright 2017 Advanced Micro Devices, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
#
# Makefile for the 'spl' sub-component of DAL.
# It provides the scaling library interface.
SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o spl_fixpt31_32.o spl_custom_float.o
AMD_DAL_SPL = $(addprefix $(AMDDALPATH)/dc/sspl/,$(SPL))
AMD_DISPLAY_FILES += $(AMD_DAL_SPL)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DC_SPL_H__
#define __DC_SPL_H__
#include "dc_spl_types.h"
#define BLACK_OFFSET_RGB_Y 0x0
#define BLACK_OFFSET_CBCR 0x8000
#ifdef __cplusplus
extern "C" {
#endif
/* SPL interfaces */
bool SPL_NAMESPACE(spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out));
bool SPL_NAMESPACE(spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out));
#ifdef __cplusplus
}
#endif
#endif /* __DC_SPL_H__ */

View file

@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "dc_spl_filters.h"
void SPL_NAMESPACE(convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
uint16_t *s1_12_filter, int num_taps))
{
int num_entries = NUM_PHASES_COEFF * num_taps;
int i;
for (i = 0; i < num_entries; i++)
*(s1_12_filter + i) = *(s1_10_filter + i) * 4;
}

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef __DC_SPL_FILTERS_H__
#define __DC_SPL_FILTERS_H__
#include "dc_spl_types.h"
#define NUM_PHASES_COEFF 33
void SPL_NAMESPACE(convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
uint16_t *s1_12_filter, int num_taps));
#endif /* __DC_SPL_FILTERS_H__ */

View file

@ -0,0 +1,554 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "spl_debug.h"
#include "dc_spl_filters.h"
#include "dc_spl_isharp_filters.h"
//========================================
// Delta Gain 1DLUT
// LUT content is packed as 4-bytes into one DWORD/entry
// A_start = 0.000000
// A_end = 10.000000
// A_gain = 3.000000
// B_start = 11.000000
// B_end = 127.000000
// C_start = 40.000000
// C_end = 127.000000
//========================================
static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = {
0x03010000,
0x0F0B0805,
0x211E1813,
0x2B292624,
0x3533302E,
0x3E3C3A37,
0x46444240,
0x4D4B4A48,
0x5352504F,
0x59575655,
0x5D5C5B5A,
0x61605F5E,
0x64646362,
0x66666565,
0x68686767,
0x68686868,
0x68686868,
0x67676868,
0x65656666,
0x62636464,
0x5E5F6061,
0x5A5B5C5D,
0x55565759,
0x4F505253,
0x484A4B4D,
0x40424446,
0x373A3C3E,
0x2E303335,
0x2426292B,
0x191B1E21,
0x0D101316,
0x0003060A,
};
// Blur and scale coefficients
//========================================================
// <using> gen_BlurScale_coeffs.m
// <date> 25-Apr-2022
// <num_taps> 4
// <num_phases> 64
// <CoefType> Blur & Scale LPF
// <CoefQuant> S1.10
//========================================================
static const uint16_t filter_isharp_bs_4tap_in_6_64p[198] = {
0x0000, 0x00E5, 0x0237, 0x00E4, 0x0000, 0x0000,
0x0000, 0x00DE, 0x0237, 0x00EB, 0x0000, 0x0000,
0x0000, 0x00D7, 0x0236, 0x00F2, 0x0001, 0x0000,
0x0000, 0x00D0, 0x0235, 0x00FA, 0x0001, 0x0000,
0x0000, 0x00C9, 0x0234, 0x0101, 0x0002, 0x0000,
0x0000, 0x00C2, 0x0233, 0x0108, 0x0003, 0x0000,
0x0000, 0x00BB, 0x0232, 0x0110, 0x0003, 0x0000,
0x0000, 0x00B5, 0x0230, 0x0117, 0x0004, 0x0000,
0x0000, 0x00AE, 0x022E, 0x011F, 0x0005, 0x0000,
0x0000, 0x00A8, 0x022C, 0x0126, 0x0006, 0x0000,
0x0000, 0x00A2, 0x022A, 0x012D, 0x0007, 0x0000,
0x0000, 0x009C, 0x0228, 0x0134, 0x0008, 0x0000,
0x0000, 0x0096, 0x0225, 0x013C, 0x0009, 0x0000,
0x0000, 0x0090, 0x0222, 0x0143, 0x000B, 0x0000,
0x0000, 0x008A, 0x021F, 0x014B, 0x000C, 0x0000,
0x0000, 0x0085, 0x021C, 0x0151, 0x000E, 0x0000,
0x0000, 0x007F, 0x0218, 0x015A, 0x000F, 0x0000,
0x0000, 0x007A, 0x0215, 0x0160, 0x0011, 0x0000,
0x0000, 0x0074, 0x0211, 0x0168, 0x0013, 0x0000,
0x0000, 0x006F, 0x020D, 0x016F, 0x0015, 0x0000,
0x0000, 0x006A, 0x0209, 0x0176, 0x0017, 0x0000,
0x0000, 0x0065, 0x0204, 0x017E, 0x0019, 0x0000,
0x0000, 0x0060, 0x0200, 0x0185, 0x001B, 0x0000,
0x0000, 0x005C, 0x01FB, 0x018C, 0x001D, 0x0000,
0x0000, 0x0057, 0x01F6, 0x0193, 0x0020, 0x0000,
0x0000, 0x0053, 0x01F1, 0x019A, 0x0022, 0x0000,
0x0000, 0x004E, 0x01EC, 0x01A1, 0x0025, 0x0000,
0x0000, 0x004A, 0x01E6, 0x01A8, 0x0028, 0x0000,
0x0000, 0x0046, 0x01E1, 0x01AF, 0x002A, 0x0000,
0x0000, 0x0042, 0x01DB, 0x01B6, 0x002D, 0x0000,
0x0000, 0x003F, 0x01D5, 0x01BB, 0x0031, 0x0000,
0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000,
0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000
};
//========================================================
// <using> gen_BlurScale_coeffs.m
// <date> 25-Apr-2022
// <num_taps> 4
// <num_phases> 64
// <CoefType> Blur & Scale LPF
// <CoefQuant> S1.10
//========================================================
static const uint16_t filter_isharp_bs_4tap_64p[132] = {
0x00E5, 0x0237, 0x00E4, 0x0000,
0x00DE, 0x0237, 0x00EB, 0x0000,
0x00D7, 0x0236, 0x00F2, 0x0001,
0x00D0, 0x0235, 0x00FA, 0x0001,
0x00C9, 0x0234, 0x0101, 0x0002,
0x00C2, 0x0233, 0x0108, 0x0003,
0x00BB, 0x0232, 0x0110, 0x0003,
0x00B5, 0x0230, 0x0117, 0x0004,
0x00AE, 0x022E, 0x011F, 0x0005,
0x00A8, 0x022C, 0x0126, 0x0006,
0x00A2, 0x022A, 0x012D, 0x0007,
0x009C, 0x0228, 0x0134, 0x0008,
0x0096, 0x0225, 0x013C, 0x0009,
0x0090, 0x0222, 0x0143, 0x000B,
0x008A, 0x021F, 0x014B, 0x000C,
0x0085, 0x021C, 0x0151, 0x000E,
0x007F, 0x0218, 0x015A, 0x000F,
0x007A, 0x0215, 0x0160, 0x0011,
0x0074, 0x0211, 0x0168, 0x0013,
0x006F, 0x020D, 0x016F, 0x0015,
0x006A, 0x0209, 0x0176, 0x0017,
0x0065, 0x0204, 0x017E, 0x0019,
0x0060, 0x0200, 0x0185, 0x001B,
0x005C, 0x01FB, 0x018C, 0x001D,
0x0057, 0x01F6, 0x0193, 0x0020,
0x0053, 0x01F1, 0x019A, 0x0022,
0x004E, 0x01EC, 0x01A1, 0x0025,
0x004A, 0x01E6, 0x01A8, 0x0028,
0x0046, 0x01E1, 0x01AF, 0x002A,
0x0042, 0x01DB, 0x01B6, 0x002D,
0x003F, 0x01D5, 0x01BB, 0x0031,
0x003B, 0x01CF, 0x01C2, 0x0034,
0x0037, 0x01C9, 0x01C9, 0x0037,
};
//========================================================
// <using> gen_BlurScale_coeffs.m
// <date> 09-Jun-2022
// <num_taps> 3
// <num_phases> 64
// <CoefType> Blur & Scale LPF
// <CoefQuant> S1.10
//========================================================
static const uint16_t filter_isharp_bs_3tap_64p[99] = {
0x0200, 0x0200, 0x0000,
0x01F6, 0x0206, 0x0004,
0x01EC, 0x020B, 0x0009,
0x01E2, 0x0211, 0x000D,
0x01D8, 0x0216, 0x0012,
0x01CE, 0x021C, 0x0016,
0x01C4, 0x0221, 0x001B,
0x01BA, 0x0226, 0x0020,
0x01B0, 0x022A, 0x0026,
0x01A6, 0x022F, 0x002B,
0x019C, 0x0233, 0x0031,
0x0192, 0x0238, 0x0036,
0x0188, 0x023C, 0x003C,
0x017E, 0x0240, 0x0042,
0x0174, 0x0244, 0x0048,
0x016A, 0x0248, 0x004E,
0x0161, 0x024A, 0x0055,
0x0157, 0x024E, 0x005B,
0x014D, 0x0251, 0x0062,
0x0144, 0x0253, 0x0069,
0x013A, 0x0256, 0x0070,
0x0131, 0x0258, 0x0077,
0x0127, 0x025B, 0x007E,
0x011E, 0x025C, 0x0086,
0x0115, 0x025E, 0x008D,
0x010B, 0x0260, 0x0095,
0x0102, 0x0262, 0x009C,
0x00F9, 0x0263, 0x00A4,
0x00F0, 0x0264, 0x00AC,
0x00E7, 0x0265, 0x00B4,
0x00DF, 0x0264, 0x00BD,
0x00D6, 0x0265, 0x00C5,
0x00CD, 0x0266, 0x00CD,
};
/* Converted Blur & Scale coeff tables from S1.10 to S1.12 */
static const uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198] = {
0x0000, 0x0394, 0x08dc, 0x0390, 0x0000, 0x0000,
0x0000, 0x0378, 0x08dc, 0x03ac, 0x0000, 0x0000,
0x0000, 0x035c, 0x08d8, 0x03c8, 0x0004, 0x0000,
0x0000, 0x0340, 0x08d4, 0x03e8, 0x0004, 0x0000,
0x0000, 0x0324, 0x08d0, 0x0404, 0x0008, 0x0000,
0x0000, 0x0308, 0x08cc, 0x0420, 0x000c, 0x0000,
0x0000, 0x02ec, 0x08c8, 0x0440, 0x000c, 0x0000,
0x0000, 0x02d4, 0x08c0, 0x045c, 0x0010, 0x0000,
0x0000, 0x02b8, 0x08b8, 0x047c, 0x0014, 0x0000,
0x0000, 0x02a0, 0x08b0, 0x0498, 0x0018, 0x0000,
0x0000, 0x0288, 0x08a8, 0x04b4, 0x001c, 0x0000,
0x0000, 0x0270, 0x08a0, 0x04d0, 0x0020, 0x0000,
0x0000, 0x0258, 0x0894, 0x04f0, 0x0024, 0x0000,
0x0000, 0x0240, 0x0888, 0x050c, 0x002c, 0x0000,
0x0000, 0x0228, 0x087c, 0x052c, 0x0030, 0x0000,
0x0000, 0x0214, 0x0870, 0x0544, 0x0038, 0x0000,
0x0000, 0x01fc, 0x0860, 0x0568, 0x003c, 0x0000,
0x0000, 0x01e8, 0x0854, 0x0580, 0x0044, 0x0000,
0x0000, 0x01d0, 0x0844, 0x05a0, 0x004c, 0x0000,
0x0000, 0x01bc, 0x0834, 0x05bc, 0x0054, 0x0000,
0x0000, 0x01a8, 0x0824, 0x05d8, 0x005c, 0x0000,
0x0000, 0x0194, 0x0810, 0x05f8, 0x0064, 0x0000,
0x0000, 0x0180, 0x0800, 0x0614, 0x006c, 0x0000,
0x0000, 0x0170, 0x07ec, 0x0630, 0x0074, 0x0000,
0x0000, 0x015c, 0x07d8, 0x064c, 0x0080, 0x0000,
0x0000, 0x014c, 0x07c4, 0x0668, 0x0088, 0x0000,
0x0000, 0x0138, 0x07b0, 0x0684, 0x0094, 0x0000,
0x0000, 0x0128, 0x0798, 0x06a0, 0x00a0, 0x0000,
0x0000, 0x0118, 0x0784, 0x06bc, 0x00a8, 0x0000,
0x0000, 0x0108, 0x076c, 0x06d8, 0x00b4, 0x0000,
0x0000, 0x00fc, 0x0754, 0x06ec, 0x00c4, 0x0000,
0x0000, 0x00ec, 0x073c, 0x0708, 0x00d0, 0x0000,
0x0000, 0x00dc, 0x0724, 0x0724, 0x00dc, 0x0000,
};
static const uint16_t filter_isharp_bs_4tap_64p_s1_12[132] = {
0x0394, 0x08dc, 0x0390, 0x0000,
0x0378, 0x08dc, 0x03ac, 0x0000,
0x035c, 0x08d8, 0x03c8, 0x0004,
0x0340, 0x08d4, 0x03e8, 0x0004,
0x0324, 0x08d0, 0x0404, 0x0008,
0x0308, 0x08cc, 0x0420, 0x000c,
0x02ec, 0x08c8, 0x0440, 0x000c,
0x02d4, 0x08c0, 0x045c, 0x0010,
0x02b8, 0x08b8, 0x047c, 0x0014,
0x02a0, 0x08b0, 0x0498, 0x0018,
0x0288, 0x08a8, 0x04b4, 0x001c,
0x0270, 0x08a0, 0x04d0, 0x0020,
0x0258, 0x0894, 0x04f0, 0x0024,
0x0240, 0x0888, 0x050c, 0x002c,
0x0228, 0x087c, 0x052c, 0x0030,
0x0214, 0x0870, 0x0544, 0x0038,
0x01fc, 0x0860, 0x0568, 0x003c,
0x01e8, 0x0854, 0x0580, 0x0044,
0x01d0, 0x0844, 0x05a0, 0x004c,
0x01bc, 0x0834, 0x05bc, 0x0054,
0x01a8, 0x0824, 0x05d8, 0x005c,
0x0194, 0x0810, 0x05f8, 0x0064,
0x0180, 0x0800, 0x0614, 0x006c,
0x0170, 0x07ec, 0x0630, 0x0074,
0x015c, 0x07d8, 0x064c, 0x0080,
0x014c, 0x07c4, 0x0668, 0x0088,
0x0138, 0x07b0, 0x0684, 0x0094,
0x0128, 0x0798, 0x06a0, 0x00a0,
0x0118, 0x0784, 0x06bc, 0x00a8,
0x0108, 0x076c, 0x06d8, 0x00b4,
0x00fc, 0x0754, 0x06ec, 0x00c4,
0x00ec, 0x073c, 0x0708, 0x00d0,
0x00dc, 0x0724, 0x0724, 0x00dc,
};
static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = {
0x0800, 0x0800, 0x0000,
0x07d8, 0x0818, 0x0010,
0x07b0, 0x082c, 0x0024,
0x0788, 0x0844, 0x0034,
0x0760, 0x0858, 0x0048,
0x0738, 0x0870, 0x0058,
0x0710, 0x0884, 0x006c,
0x06e8, 0x0898, 0x0080,
0x06c0, 0x08a8, 0x0098,
0x0698, 0x08bc, 0x00ac,
0x0670, 0x08cc, 0x00c4,
0x0648, 0x08e0, 0x00d8,
0x0620, 0x08f0, 0x00f0,
0x05f8, 0x0900, 0x0108,
0x05d0, 0x0910, 0x0120,
0x05a8, 0x0920, 0x0138,
0x0584, 0x0928, 0x0154,
0x055c, 0x0938, 0x016c,
0x0534, 0x0944, 0x0188,
0x0510, 0x094c, 0x01a4,
0x04e8, 0x0958, 0x01c0,
0x04c4, 0x0960, 0x01dc,
0x049c, 0x096c, 0x01f8,
0x0478, 0x0970, 0x0218,
0x0454, 0x0978, 0x0234,
0x042c, 0x0980, 0x0254,
0x0408, 0x0988, 0x0270,
0x03e4, 0x098c, 0x0290,
0x03c0, 0x0990, 0x02b0,
0x039c, 0x0994, 0x02d0,
0x037c, 0x0990, 0x02f4,
0x0358, 0x0994, 0x0314,
0x0334, 0x0998, 0x0334,
};
/* Pre-generated 1DLUT for given setup and sharpness level */
static struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
{
0, 0,
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
}
},
{
0, 0,
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
}
},
{
0, 0,
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
}
},
{
0, 0,
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
}
},
};
static struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = {
{1125, 1000, 0},
{11, 10, 1},
{1075, 1000, 2},
{105, 100, 3},
{1025, 1000, 4},
{1, 1, 5},
};
static unsigned int spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)
{
int j;
struct spl_fixed31_32 ratio_level;
struct scale_ratio_to_sharpness_level_adj *lookup_ptr;
unsigned int sharpness_level_down_adj;
/*
* Adjust sharpness level based on current scaling ratio
*
* We have 5 discrete scaling ratios which we will use to adjust the
* sharpness level down by 1 as we pass each ratio. The ratios
* are
*
* 1.125 upscale and higher - no adj
* 1.100 - under 1.125 - adj level down 1
* 1.075 - under 1.100 - adj level down 2
* 1.050 - under 1.075 - adj level down 3
* 1.025 - under 1.050 - adj level down 4
* 1.000 - under 1.025 - adj level down 5
*
*/
j = 0;
sharpness_level_down_adj = 0;
lookup_ptr = sharpness_level_adj;
while (j < NUM_SHARPNESS_ADJ_LEVELS) {
ratio_level = SPL_NAMESPACE(spl_fixpt_from_fraction(lookup_ptr->ratio_numer,
lookup_ptr->ratio_denom));
if (ratio.value >= ratio_level.value) {
sharpness_level_down_adj = lookup_ptr->level_down_adj;
break;
}
lookup_ptr++;
j++;
}
return sharpness_level_down_adj;
}
static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,
unsigned int discrete_sharpness_level, enum system_setup setup,
struct spl_sharpness_range sharpness_range,
enum scale_to_sharpness_policy scale_to_sharpness_policy)
{
unsigned int sharpness_level = 0;
unsigned int sharpness_level_down_adj = 0;
int min_sharpness, max_sharpness, mid_sharpness;
/*
* Adjust sharpness level if policy requires we adjust it based on
* scale ratio. Based on scale ratio, we may adjust the sharpness
* level down by a certain number of steps. We will not select
* a sharpness value of 0 so the lowest sharpness level will be
* 0 or 1 depending on what the min_sharpness is
*
* If the policy is no required, this code maybe removed at a later
* date
*/
switch (setup) {
case HDR_L:
min_sharpness = sharpness_range.hdr_rgb_min;
max_sharpness = sharpness_range.hdr_rgb_max;
mid_sharpness = sharpness_range.hdr_rgb_mid;
if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
break;
case HDR_NL:
/* currently no use case, use Non-linear SDR values for now */
case SDR_NL:
min_sharpness = sharpness_range.sdr_yuv_min;
max_sharpness = sharpness_range.sdr_yuv_max;
mid_sharpness = sharpness_range.sdr_yuv_mid;
if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV)
sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
break;
case SDR_L:
default:
min_sharpness = sharpness_range.sdr_rgb_min;
max_sharpness = sharpness_range.sdr_rgb_max;
mid_sharpness = sharpness_range.sdr_rgb_mid;
if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
break;
}
if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level))
discrete_sharpness_level = 1;
else if (sharpness_level_down_adj >= discrete_sharpness_level)
discrete_sharpness_level = 0;
else
discrete_sharpness_level -= sharpness_level_down_adj;
int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
// lower half linear approximation
if (discrete_sharpness_level < 5)
sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
// upper half linear approximation
else
sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
return sharpness_level;
}
void SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve(
struct spl_fixed31_32 ratio, enum system_setup setup,
struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy))
{
uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
int j;
int size_1dlut;
int sharp_calc_int;
uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
/* Custom sharpnessX1000 value */
unsigned int sharpnessX1000 = spl_calculate_sharpness_level(ratio,
sharpness.sharpness_level, setup,
sharpness.sharpness_range, scale_to_sharpness_policy);
sharp_level = SPL_NAMESPACE(spl_fixpt_from_fraction(sharpnessX1000, 1000));
/*
* Check if pregen 1dlut table is already precalculated
* If numer/denom is different, then recalculate
*/
if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
(filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
return;
/*
* Calculate LUT_128_gained with this equation:
*
* LUT_128_gained[i] = (uint8)(0.5 + min(255,(double)(LUT_128[i])*sharpLevel/iGain))
* where LUT_128[i] is contents of 3p0x isharp 1dlut
* where sharpLevel is desired sharpness level
* where iGain is base sharpness level 3.0
* where LUT_128_gained[i] is adjusted 1dlut value based on desired sharpness level
*/
byte_ptr_1dlut_src = (uint8_t *)filter_isharp_1D_lut_3p0x;
byte_ptr_1dlut_dst = (uint8_t *)filter_pregen_store;
size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
memset(byte_ptr_1dlut_dst, 0, size_1dlut);
for (j = 0; j < size_1dlut; j++) {
sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
sharp_calc = SPL_NAMESPACE(spl_fixpt_mul(sharp_base, sharp_level));
sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
sharp_calc = spl_fixpt_add(sharp_calc,
SPL_NAMESPACE(spl_fixpt_from_fraction(1, 2)));
sharp_calc_int = spl_fixpt_floor(sharp_calc);
/* Clamp it at 0x7F so it doesn't wrap */
if (sharp_calc_int > 127)
sharp_calc_int = 127;
*byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
byte_ptr_1dlut_src++;
byte_ptr_1dlut_dst++;
}
/* Update 1dlut table and sharpness level */
memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
}
uint32_t *SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup))
{
return filter_isharp_1D_lut_pregen[setup].value;
}
const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(int taps))
{
if (taps == 3)
return filter_isharp_bs_3tap_64p_s1_12;
else if (taps == 4)
return filter_isharp_bs_4tap_64p_s1_12;
else if (taps == 6)
return filter_isharp_bs_4tap_in_6_64p_s1_12;
else {
/* should never happen, bug */
SPL_BREAK_TO_DEBUGGER();
return NULL;
}
}
const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps))
{
if (taps == 3)
return filter_isharp_bs_3tap_64p;
else if (taps == 4)
return filter_isharp_bs_4tap_64p;
else if (taps == 6)
return filter_isharp_bs_4tap_in_6_64p;
else {
/* should never happen, bug */
SPL_BREAK_TO_DEBUGGER();
return NULL;
}
}
void SPL_NAMESPACE(spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
const struct spl_scaler_data *data))
{
dscl_prog_data->filter_blur_scale_h =
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.h_taps));
dscl_prog_data->filter_blur_scale_v =
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps));
}

View file

@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DC_SPL_ISHARP_FILTERS_H__
#define __DC_SPL_ISHARP_FILTERS_H__
#include "dc_spl_types.h"
#define NUM_SHARPNESS_ADJ_LEVELS 6
struct scale_ratio_to_sharpness_level_adj {
unsigned int ratio_numer;
unsigned int ratio_denom;
unsigned int level_down_adj; /* adjust sharpness level down */
};
struct isharp_1D_lut_pregen {
unsigned int sharpness_numer;
unsigned int sharpness_denom;
uint32_t value[ISHARP_LUT_TABLE_SIZE];
};
enum system_setup {
SDR_NL = 0,
SDR_L,
HDR_NL,
HDR_L,
NUM_SHARPNESS_SETUPS
};
void SPL_NAMESPACE(spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
const struct spl_scaler_data *data));
void SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve(
struct spl_fixed31_32 ratio, enum system_setup setup,
struct adaptive_sharpness sharpness,
enum scale_to_sharpness_policy scale_to_sharpness_policy));
uint32_t *SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup));
// public API
const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(int taps));
const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps));
#endif /* __DC_SPL_ISHARP_FILTERS_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef __DC_SPL_SCL_EASF_FILTERS_H__
#define __DC_SPL_SCL_EASF_FILTERS_H__
#include "dc_spl_types.h"
struct scale_ratio_to_reg_value_lookup {
int numer;
int denom;
const uint32_t reg_value;
};
void SPL_NAMESPACE(spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
const struct spl_scaler_data *data, bool enable_easf_v,
bool enable_easf_h));
uint32_t SPL_NAMESPACE(spl_get_v_bf3_mode(struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_h_bf3_mode(struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_dntilt_uptilt_offset(
int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio));
uint32_t SPL_NAMESPACE(spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio));
/* public API */
const uint16_t *SPL_NAMESPACE(spl_dscl_get_easf_filter_coeffs_64p(
int taps, struct spl_fixed31_32 ratio));
const uint16_t *SPL_NAMESPACE(spl_dscl_get_easf_filter_coeffs_64p_s1_10(
int taps, struct spl_fixed31_32 ratio));
#endif /* __DC_SPL_SCL_EASF_FILTERS_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DC_SPL_SCL_FILTERS_H__
#define __DC_SPL_SCL_FILTERS_H__
#include "dc_spl_types.h"
/* public API */
const uint16_t *SPL_NAMESPACE(spl_dscl_get_filter_coeffs_64p(
int taps, struct spl_fixed31_32 ratio));
#endif /* __DC_SPL_SCL_FILTERS_H__ */

View file

@ -0,0 +1,624 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DC_SPL_TYPES_H__
#define __DC_SPL_TYPES_H__
#include "spl_debug.h"
#include "spl_os_types.h" // swap
#include "spl_fixpt31_32.h" // fixed31_32 and related functions
#include "spl_custom_float.h" // custom float and related functions
struct spl_size {
uint32_t width;
uint32_t height;
};
struct spl_rect {
int x;
int y;
int width;
int height;
};
struct spl_ratios {
struct spl_fixed31_32 horz;
struct spl_fixed31_32 vert;
struct spl_fixed31_32 horz_c;
struct spl_fixed31_32 vert_c;
};
struct spl_inits {
struct spl_fixed31_32 h;
struct spl_fixed31_32 h_c;
struct spl_fixed31_32 v;
struct spl_fixed31_32 v_c;
};
struct spl_taps {
uint32_t v_taps;
uint32_t h_taps;
uint32_t v_taps_c;
uint32_t h_taps_c;
bool integer_scaling;
};
enum spl_view_3d {
SPL_VIEW_3D_NONE = 0,
SPL_VIEW_3D_FRAME_SEQUENTIAL,
SPL_VIEW_3D_SIDE_BY_SIDE,
SPL_VIEW_3D_TOP_AND_BOTTOM,
SPL_VIEW_3D_COUNT,
SPL_VIEW_3D_FIRST = SPL_VIEW_3D_FRAME_SEQUENTIAL
};
/* Pixel format */
enum spl_pixel_format {
/*graph*/
SPL_PIXEL_FORMAT_UNINITIALIZED,
SPL_PIXEL_FORMAT_INDEX8,
SPL_PIXEL_FORMAT_RGB565,
SPL_PIXEL_FORMAT_ARGB8888,
SPL_PIXEL_FORMAT_ARGB2101010,
SPL_PIXEL_FORMAT_ARGB2101010_XRBIAS,
SPL_PIXEL_FORMAT_FP16,
/*video*/
SPL_PIXEL_FORMAT_420BPP8,
SPL_PIXEL_FORMAT_420BPP10,
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
SPL_PIXEL_FORMAT_422BPP8,
SPL_PIXEL_FORMAT_422BPP10,
SPL_PIXEL_FORMAT_422BPP12,
SPL_PIXEL_FORMAT_444BPP8,
SPL_PIXEL_FORMAT_444BPP10,
#endif
/*end of pixel format definition*/
SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8,
SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16,
SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_422BPP12,
#else
SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_420BPP10,
#endif
SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_444BPP10,
#else
SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_420BPP10,
#endif
SPL_PIXEL_FORMAT_INVALID,
SPL_PIXEL_FORMAT_UNKNOWN
};
enum lb_memory_config {
/* Enable all 3 pieces of memory */
LB_MEMORY_CONFIG_0 = 0,
/* Enable only the first piece of memory */
LB_MEMORY_CONFIG_1 = 1,
/* Enable only the second piece of memory */
LB_MEMORY_CONFIG_2 = 2,
/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
* last piece of chroma memory used for the luma storage
*/
LB_MEMORY_CONFIG_3 = 3
};
/* Rotation angle */
enum spl_rotation_angle {
SPL_ROTATION_ANGLE_0 = 0,
SPL_ROTATION_ANGLE_90,
SPL_ROTATION_ANGLE_180,
SPL_ROTATION_ANGLE_270,
SPL_ROTATION_ANGLE_COUNT
};
enum spl_color_space {
SPL_COLOR_SPACE_UNKNOWN,
SPL_COLOR_SPACE_SRGB,
SPL_COLOR_SPACE_XR_RGB,
SPL_COLOR_SPACE_SRGB_LIMITED,
SPL_COLOR_SPACE_MSREF_SCRGB,
SPL_COLOR_SPACE_YCBCR601,
SPL_COLOR_SPACE_YCBCR709,
SPL_COLOR_SPACE_XV_YCC_709,
SPL_COLOR_SPACE_XV_YCC_601,
SPL_COLOR_SPACE_YCBCR601_LIMITED,
SPL_COLOR_SPACE_YCBCR709_LIMITED,
SPL_COLOR_SPACE_2020_RGB_FULLRANGE,
SPL_COLOR_SPACE_2020_RGB_LIMITEDRANGE,
SPL_COLOR_SPACE_2020_YCBCR,
SPL_COLOR_SPACE_ADOBERGB,
SPL_COLOR_SPACE_DCIP3,
SPL_COLOR_SPACE_DISPLAYNATIVE,
SPL_COLOR_SPACE_DOLBYVISION,
SPL_COLOR_SPACE_APPCTRL,
SPL_COLOR_SPACE_CUSTOMPOINTS,
SPL_COLOR_SPACE_YCBCR709_BLACK,
};
enum chroma_cositing {
CHROMA_COSITING_NONE,
CHROMA_COSITING_LEFT,
CHROMA_COSITING_TOPLEFT,
CHROMA_COSITING_COUNT
};
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
enum upsp_mode {
UPSP_BYPASS = 0,
UPSP_HORIZONTAL_UPSAMPLING_ONLY,
UPSP_VERTICAL_UPSAMPLING_ONLY,
UPSP_HORIZONTAL_VERTICAL_UPSAMPLING
};
enum upsp_num_taps {
UPSP_2_TAPS,
UPSP_4_TAPS
};
enum upsp_boundary_mode {
UPSP_BOUNDARY_EDGE, //Replace out of bound samples with the edge samples
UPSP_BOUNDARY_BLACK //Replace out of bound samples with black as 12bpc(0x800)
};
#endif
// Scratch space for calculating scaler params
struct spl_scaler_data {
int h_active;
int v_active;
struct spl_taps taps;
struct spl_rect viewport;
struct spl_rect viewport_c;
struct spl_rect recout;
struct spl_ratios ratios;
struct spl_ratios recip_ratios;
struct spl_inits inits;
};
enum spl_transfer_func_type {
SPL_TF_TYPE_PREDEFINED,
SPL_TF_TYPE_DISTRIBUTED_POINTS,
SPL_TF_TYPE_BYPASS,
SPL_TF_TYPE_HWPWL
};
enum spl_transfer_func_predefined {
SPL_TRANSFER_FUNCTION_SRGB,
SPL_TRANSFER_FUNCTION_BT709,
SPL_TRANSFER_FUNCTION_PQ,
SPL_TRANSFER_FUNCTION_LINEAR,
SPL_TRANSFER_FUNCTION_UNITY,
SPL_TRANSFER_FUNCTION_HLG,
SPL_TRANSFER_FUNCTION_HLG12,
SPL_TRANSFER_FUNCTION_GAMMA22,
SPL_TRANSFER_FUNCTION_GAMMA24,
SPL_TRANSFER_FUNCTION_GAMMA26
};
/*==============================================================*/
/* Below structs are defined to hold hw register data */
// SPL output is used to set below registers
// MPC_SIZE - set based on scl_data h_active and v_active
struct mpc_size {
uint32_t width;
uint32_t height;
};
// SCL_MODE - set based on scl_data.ratios and always_scale
enum scl_mode {
SCL_MODE_SCALING_444_BYPASS = 0,
SCL_MODE_SCALING_444_RGB_ENABLE = 1,
SCL_MODE_SCALING_444_YCBCR_ENABLE = 2,
SCL_MODE_SCALING_420_YCBCR_ENABLE = 3,
SCL_MODE_SCALING_420_LUMA_BYPASS = 4,
SCL_MODE_SCALING_420_CHROMA_BYPASS = 5,
SCL_MODE_DSCL_BYPASS = 6
};
// SCL_BLACK_COLOR - set based on scl_data.format
struct scl_black_color {
uint32_t offset_rgb_y;
uint32_t offset_rgb_cbcr;
};
// RATIO - set based on scl_data.ratios
struct ratio {
uint32_t h_scale_ratio;
uint32_t v_scale_ratio;
uint32_t h_scale_ratio_c;
uint32_t v_scale_ratio_c;
};
// INIT - set based on scl_data.init
struct init {
// SCL_HORZ_FILTER_INIT
uint32_t h_filter_init_frac; // SCL_H_INIT_FRAC
uint32_t h_filter_init_int; // SCL_H_INIT_INT
// SCL_HORZ_FILTER_INIT_C
uint32_t h_filter_init_frac_c; // SCL_H_INIT_FRAC_C
uint32_t h_filter_init_int_c; // SCL_H_INIT_INT_C
// SCL_VERT_FILTER_INIT
uint32_t v_filter_init_frac; // SCL_V_INIT_FRAC
uint32_t v_filter_init_int; // SCL_V_INIT_INT
// SCL_VERT_FILTER_INIT_C
uint32_t v_filter_init_frac_c; // SCL_V_INIT_FRAC_C
uint32_t v_filter_init_int_c; // SCL_V_INIT_INT_C
// SCL_VERT_FILTER_INIT_BOT
uint32_t v_filter_init_bot_frac; // SCL_V_INIT_FRAC_BOT
uint32_t v_filter_init_bot_int; // SCL_V_INIT_INT_BOT
// SCL_VERT_FILTER_INIT_BOT_C
uint32_t v_filter_init_bot_frac_c; // SCL_V_INIT_FRAC_BOT_C
uint32_t v_filter_init_bot_int_c; // SCL_V_INIT_INT_BOT_C
};
// FILTER - calculated based on scl_data ratios and taps
// iSHARP
struct isharp_noise_det {
uint32_t enable; // ISHARP_NOISEDET_EN
uint32_t mode; // ISHARP_NOISEDET_MODE
uint32_t uthreshold; // ISHARP_NOISEDET_UTHRE
uint32_t dthreshold; // ISHARP_NOISEDET_DTHRE
uint32_t pwl_start_in; // ISHARP_NOISEDET_PWL_START_IN
uint32_t pwl_end_in; // ISHARP_NOISEDET_PWL_END_IN
uint32_t pwl_slope; // ISHARP_NOISEDET_PWL_SLOPE
};
struct isharp_lba {
uint32_t mode; // ISHARP_LBA_MODE
uint32_t in_seg[6];
uint32_t base_seg[6];
uint32_t slope_seg[6];
};
struct isharp_fmt {
uint32_t mode; // ISHARP_FMT_MODE
uint32_t norm; // ISHARP_FMT_NORM
};
struct isharp_nldelta_sclip {
uint32_t enable_p; // ISHARP_NLDELTA_SCLIP_EN_P
uint32_t pivot_p; // ISHARP_NLDELTA_SCLIP_PIVOT_P
uint32_t slope_p; // ISHARP_NLDELTA_SCLIP_SLOPE_P
uint32_t enable_n; // ISHARP_NLDELTA_SCLIP_EN_N
uint32_t pivot_n; // ISHARP_NLDELTA_SCLIP_PIVOT_N
uint32_t slope_n; // ISHARP_NLDELTA_SCLIP_SLOPE_N
};
enum isharp_en {
ISHARP_DISABLE,
ISHARP_ENABLE
};
#define ISHARP_LUT_TABLE_SIZE 32
// Below struct holds values that can be directly used to program
// hardware registers. No conversion/clamping is required
struct dscl_prog_data {
struct spl_rect recout; // RECOUT - set based on scl_data.recout
struct mpc_size mpc_size;
uint32_t dscl_mode;
struct scl_black_color scl_black_color;
struct ratio ratios;
struct init init;
struct spl_taps taps; // TAPS - set based on scl_data.taps
struct spl_rect viewport;
struct spl_rect viewport_c;
// raw filter
const uint16_t *filter_h;
const uint16_t *filter_v;
const uint16_t *filter_h_c;
const uint16_t *filter_v_c;
// EASF registers
uint32_t easf_matrix_mode;
uint32_t easf_ltonl_en;
uint32_t easf_v_en;
uint32_t easf_v_sharp_factor;
uint32_t easf_v_ring;
uint32_t easf_v_bf1_en;
uint32_t easf_v_bf2_mode;
uint32_t easf_v_bf3_mode;
uint32_t easf_v_bf2_flat1_gain;
uint32_t easf_v_bf2_flat2_gain;
uint32_t easf_v_bf2_roc_gain;
uint32_t easf_v_ringest_3tap_dntilt_uptilt;
uint32_t easf_v_ringest_3tap_uptilt_max;
uint32_t easf_v_ringest_3tap_dntilt_slope;
uint32_t easf_v_ringest_3tap_uptilt1_slope;
uint32_t easf_v_ringest_3tap_uptilt2_slope;
uint32_t easf_v_ringest_3tap_uptilt2_offset;
uint32_t easf_v_ringest_eventap_reduceg1;
uint32_t easf_v_ringest_eventap_reduceg2;
uint32_t easf_v_ringest_eventap_gain1;
uint32_t easf_v_ringest_eventap_gain2;
uint32_t easf_v_bf_maxa;
uint32_t easf_v_bf_maxb;
uint32_t easf_v_bf_mina;
uint32_t easf_v_bf_minb;
uint32_t easf_v_bf1_pwl_in_seg0;
uint32_t easf_v_bf1_pwl_base_seg0;
uint32_t easf_v_bf1_pwl_slope_seg0;
uint32_t easf_v_bf1_pwl_in_seg1;
uint32_t easf_v_bf1_pwl_base_seg1;
uint32_t easf_v_bf1_pwl_slope_seg1;
uint32_t easf_v_bf1_pwl_in_seg2;
uint32_t easf_v_bf1_pwl_base_seg2;
uint32_t easf_v_bf1_pwl_slope_seg2;
uint32_t easf_v_bf1_pwl_in_seg3;
uint32_t easf_v_bf1_pwl_base_seg3;
uint32_t easf_v_bf1_pwl_slope_seg3;
uint32_t easf_v_bf1_pwl_in_seg4;
uint32_t easf_v_bf1_pwl_base_seg4;
uint32_t easf_v_bf1_pwl_slope_seg4;
uint32_t easf_v_bf1_pwl_in_seg5;
uint32_t easf_v_bf1_pwl_base_seg5;
uint32_t easf_v_bf1_pwl_slope_seg5;
uint32_t easf_v_bf1_pwl_in_seg6;
uint32_t easf_v_bf1_pwl_base_seg6;
uint32_t easf_v_bf1_pwl_slope_seg6;
uint32_t easf_v_bf1_pwl_in_seg7;
uint32_t easf_v_bf1_pwl_base_seg7;
uint32_t easf_v_bf3_pwl_in_set0;
uint32_t easf_v_bf3_pwl_base_set0;
uint32_t easf_v_bf3_pwl_slope_set0;
uint32_t easf_v_bf3_pwl_in_set1;
uint32_t easf_v_bf3_pwl_base_set1;
uint32_t easf_v_bf3_pwl_slope_set1;
uint32_t easf_v_bf3_pwl_in_set2;
uint32_t easf_v_bf3_pwl_base_set2;
uint32_t easf_v_bf3_pwl_slope_set2;
uint32_t easf_v_bf3_pwl_in_set3;
uint32_t easf_v_bf3_pwl_base_set3;
uint32_t easf_v_bf3_pwl_slope_set3;
uint32_t easf_v_bf3_pwl_in_set4;
uint32_t easf_v_bf3_pwl_base_set4;
uint32_t easf_v_bf3_pwl_slope_set4;
uint32_t easf_v_bf3_pwl_in_set5;
uint32_t easf_v_bf3_pwl_base_set5;
uint32_t easf_h_en;
uint32_t easf_h_sharp_factor;
uint32_t easf_h_ring;
uint32_t easf_h_bf1_en;
uint32_t easf_h_bf2_mode;
uint32_t easf_h_bf3_mode;
uint32_t easf_h_bf2_flat1_gain;
uint32_t easf_h_bf2_flat2_gain;
uint32_t easf_h_bf2_roc_gain;
uint32_t easf_h_ringest_eventap_reduceg1;
uint32_t easf_h_ringest_eventap_reduceg2;
uint32_t easf_h_ringest_eventap_gain1;
uint32_t easf_h_ringest_eventap_gain2;
uint32_t easf_h_bf_maxa;
uint32_t easf_h_bf_maxb;
uint32_t easf_h_bf_mina;
uint32_t easf_h_bf_minb;
uint32_t easf_h_bf1_pwl_in_seg0;
uint32_t easf_h_bf1_pwl_base_seg0;
uint32_t easf_h_bf1_pwl_slope_seg0;
uint32_t easf_h_bf1_pwl_in_seg1;
uint32_t easf_h_bf1_pwl_base_seg1;
uint32_t easf_h_bf1_pwl_slope_seg1;
uint32_t easf_h_bf1_pwl_in_seg2;
uint32_t easf_h_bf1_pwl_base_seg2;
uint32_t easf_h_bf1_pwl_slope_seg2;
uint32_t easf_h_bf1_pwl_in_seg3;
uint32_t easf_h_bf1_pwl_base_seg3;
uint32_t easf_h_bf1_pwl_slope_seg3;
uint32_t easf_h_bf1_pwl_in_seg4;
uint32_t easf_h_bf1_pwl_base_seg4;
uint32_t easf_h_bf1_pwl_slope_seg4;
uint32_t easf_h_bf1_pwl_in_seg5;
uint32_t easf_h_bf1_pwl_base_seg5;
uint32_t easf_h_bf1_pwl_slope_seg5;
uint32_t easf_h_bf1_pwl_in_seg6;
uint32_t easf_h_bf1_pwl_base_seg6;
uint32_t easf_h_bf1_pwl_slope_seg6;
uint32_t easf_h_bf1_pwl_in_seg7;
uint32_t easf_h_bf1_pwl_base_seg7;
uint32_t easf_h_bf3_pwl_in_set0;
uint32_t easf_h_bf3_pwl_base_set0;
uint32_t easf_h_bf3_pwl_slope_set0;
uint32_t easf_h_bf3_pwl_in_set1;
uint32_t easf_h_bf3_pwl_base_set1;
uint32_t easf_h_bf3_pwl_slope_set1;
uint32_t easf_h_bf3_pwl_in_set2;
uint32_t easf_h_bf3_pwl_base_set2;
uint32_t easf_h_bf3_pwl_slope_set2;
uint32_t easf_h_bf3_pwl_in_set3;
uint32_t easf_h_bf3_pwl_base_set3;
uint32_t easf_h_bf3_pwl_slope_set3;
uint32_t easf_h_bf3_pwl_in_set4;
uint32_t easf_h_bf3_pwl_base_set4;
uint32_t easf_h_bf3_pwl_slope_set4;
uint32_t easf_h_bf3_pwl_in_set5;
uint32_t easf_h_bf3_pwl_base_set5;
uint32_t easf_matrix_c0;
uint32_t easf_matrix_c1;
uint32_t easf_matrix_c2;
uint32_t easf_matrix_c3;
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
// UPSP registers
uint32_t upsp_mode;//UPSP_MODE
uint32_t upsp_v_num_taps;
uint32_t upsp_v_init_int;
uint32_t upsp_v_init_frac;
uint32_t upsp_h_num_taps;
uint32_t upsp_h_init_int;
uint32_t upsp_h_init_frac;
uint32_t upsp_boundary_mode;
uint32_t upsp_v_coef_tap0_p0;//UPSP_V_COEF_P0
uint32_t upsp_v_coef_tap1_p0;
uint32_t upsp_v_coef_tap2_p0;
uint32_t upsp_v_coef_tap3_p0;
uint32_t upsp_v_coef_tap0_p1;//UPSP_V_COEF_P1
uint32_t upsp_v_coef_tap1_p1;
uint32_t upsp_v_coef_tap2_p1;
uint32_t upsp_v_coef_tap3_p1;
uint32_t upsp_h_coef_tap0_p0;//UPSP_H_COEF_P0
uint32_t upsp_h_coef_tap1_p0;
uint32_t upsp_h_coef_tap2_p0;
uint32_t upsp_h_coef_tap3_p0;
uint32_t upsp_h_coef_tap0_p1;//UPSP_H_COEF_P1
uint32_t upsp_h_coef_tap1_p1;
uint32_t upsp_h_coef_tap2_p1;
uint32_t upsp_h_coef_tap3_p1;
uint32_t upsp_clamp_max;//UPSP_CLAMP
uint32_t upsp_clamp_min;
#endif
// iSharp
uint32_t isharp_en; // ISHARP_EN
struct isharp_noise_det isharp_noise_det; // ISHARP_NOISEDET
uint32_t isharp_nl_en; // ISHARP_NL_EN ? TODO:check this
struct isharp_lba isharp_lba; // ISHARP_LBA
struct isharp_fmt isharp_fmt; // ISHARP_FMT
uint32_t isharp_delta[ISHARP_LUT_TABLE_SIZE];
struct isharp_nldelta_sclip isharp_nldelta_sclip; // ISHARP_NLDELTA_SCLIP
/* blur and scale filter */
const uint16_t *filter_blur_scale_v;
const uint16_t *filter_blur_scale_h;
int sharpness_level; /* Track sharpness level */
};
/* SPL input and output definitions */
// SPL scratch struct
struct spl_scratch {
// Pack all SPL outputs in scl_data
struct spl_scaler_data scl_data;
};
/* SPL input and output definitions */
// SPL outputs struct
struct spl_out {
// Pack all output need to program hw registers
struct dscl_prog_data *dscl_prog_data;
};
// end of SPL outputs
// SPL inputs
// opp extra adjustment for rect
struct spl_opp_adjust {
int x;
int y;
int width;
int height;
};
// Basic input information
struct basic_in {
enum spl_pixel_format format; // Pixel Format
enum chroma_cositing cositing; /* Chroma Subsampling Offset */
struct spl_rect src_rect; // Source rect
struct spl_rect dst_rect; // Destination Rect
struct spl_rect clip_rect; // Clip rect
enum spl_rotation_angle rotation; // Rotation
bool horizontal_mirror; // Horizontal mirror
struct { // previous mpc_combine_h - split count
bool use_recout_width_aligned;
union {
int mpc_num_h_slices;
int mpc_recout_width_align;
} num_slices_recout_width;
} num_h_slices_recout_width_align;
int mpc_h_slice_index; // previous mpc_combine_v - split_idx
struct spl_opp_adjust opp_recout_adjust;
// Inputs for adaptive scaler - TODO
enum spl_transfer_func_type tf_type; /* Transfer function type */
enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */
// enum dc_transfer_func_predefined tf;
enum spl_color_space color_space; // Color Space
unsigned int max_luminance; // Max Luminance TODO: Is determined in dc_hw_sequencer.c is_sdr
bool film_grain_applied; // Film Grain Applied // TODO: To check from where to get this?
int custom_width; // Width for non-standard segmentation - used when != 0
int custom_x; // Start x for non-standard segmentation - used when custom_width != 0
};
// Basic output information
struct basic_out {
struct spl_size output_size; // Output Size
struct spl_rect dst_rect; // Destination Rect
struct spl_rect src_rect; // Source rect
int odm_combine_factor; // deprecated
struct spl_rect odm_slice_rect; // OPP input rect in timing active
enum spl_view_3d view_format; // TODO: View format Check if it is chroma subsampling
bool always_scale; // Is always scale enabled? Required for getting SCL_MODE
int max_downscale_src_width; // Required to get optimal no of taps
bool alpha_en;
bool use_two_pixels_per_container;
};
enum sharpness_setting {
SHARPNESS_HW_OFF = 0,
SHARPNESS_ZERO,
SHARPNESS_CUSTOM
};
enum sharpness_range_source {
SHARPNESS_RANGE_DCN = 0,
SHARPNESS_RANGE_DCN_OVERRIDE
};
struct spl_sharpness_range {
int sdr_rgb_min;
int sdr_rgb_max;
int sdr_rgb_mid;
int sdr_yuv_min;
int sdr_yuv_max;
int sdr_yuv_mid;
int hdr_rgb_min;
int hdr_rgb_max;
int hdr_rgb_mid;
};
struct adaptive_sharpness {
bool enable;
unsigned int sharpness_level;
struct spl_sharpness_range sharpness_range;
};
enum linear_light_scaling { // convert it in translation logic
LLS_PREF_DONT_CARE = 0,
LLS_PREF_YES,
LLS_PREF_NO
};
enum sharpen_policy {
SHARPEN_ALWAYS = 0,
SHARPEN_YUV = 1,
SHARPEN_RGB_FULLSCREEN_YUV = 2,
SHARPEN_FULLSCREEN_ALL = 3
};
enum scale_to_sharpness_policy {
NO_SCALE_TO_SHARPNESS_ADJ = 0,
SCALE_TO_SHARPNESS_ADJ_YUV = 1,
SCALE_TO_SHARPNESS_ADJ_ALL = 2
};
struct spl_callbacks {
void (*spl_calc_lb_num_partitions)
(bool alpha_en,
const struct spl_scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
int *num_part_c);
};
struct spl_debug {
unsigned int visual_confirm_base_offset;
unsigned int visual_confirm_dpp_offset;
enum scale_to_sharpness_policy scale_to_sharpness_policy;
};
struct spl_in {
struct basic_out basic_out;
struct basic_in basic_in;
// Basic slice information
int odm_slice_index; // ODM Slice Index using get_odm_split_index
struct spl_taps scaling_quality; // Explicit Scaling Quality
struct spl_callbacks callbacks;
// Inputs for isharp and EASF
struct adaptive_sharpness adaptive_sharpness; // Adaptive Sharpness
enum linear_light_scaling lls_pref; // Linear Light Scaling
bool prefer_easf;
bool disable_easf;
bool override_easf; /* If true, keep EASF enabled but use provided in_taps */
struct spl_debug debug;
bool is_fullscreen;
bool is_hdr_on;
int h_active;
int v_active;
int min_viewport_size;
int sdr_white_level_nits;
enum sharpen_policy sharpen_policy;
#if defined(CONFIG_DRM_AMD_DC_DCN6_0) || !defined(TRIM_SPL_VPE)
enum upsp_mode upsp_mode;
#endif
};
// end of SPL inputs
#endif /* __DC_SPL_TYPES_H__ */

View file

@ -0,0 +1,152 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "spl_debug.h"
#include "spl_custom_float.h"
static bool spl_build_custom_float(struct spl_fixed31_32 value,
const struct spl_custom_float_format *format,
bool *negative,
uint32_t *mantissa,
uint32_t *exponenta)
{
uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
const struct spl_fixed31_32 mantissa_constant_plus_max_fraction =
SPL_NAMESPACE(spl_fixpt_from_fraction((1LL << (format->mantissa_bits + 1)) - 1,
1LL << format->mantissa_bits));
struct spl_fixed31_32 mantiss;
if (spl_fixpt_eq(value, spl_fixpt_zero)) {
*negative = false;
*mantissa = 0;
*exponenta = 0;
return true;
}
if (spl_fixpt_lt(value, spl_fixpt_zero)) {
*negative = format->sign;
value = spl_fixpt_neg(value);
} else {
*negative = false;
}
if (spl_fixpt_lt(value, spl_fixpt_one)) {
uint32_t i = 1;
do {
value = spl_fixpt_shl(value, 1);
++i;
} while (spl_fixpt_lt(value, spl_fixpt_one));
--i;
if (exp_offset <= i) {
*mantissa = 0;
*exponenta = 0;
return true;
}
*exponenta = exp_offset - i;
} else if (spl_fixpt_le(mantissa_constant_plus_max_fraction, value)) {
uint32_t i = 1;
do {
value = spl_fixpt_shr(value, 1);
++i;
} while (spl_fixpt_lt(mantissa_constant_plus_max_fraction, value));
*exponenta = exp_offset + i - 1;
} else {
*exponenta = exp_offset;
}
mantiss = spl_fixpt_sub(value, spl_fixpt_one);
if (spl_fixpt_lt(mantiss, spl_fixpt_zero) ||
spl_fixpt_lt(spl_fixpt_one, mantiss))
mantiss = spl_fixpt_zero;
else
mantiss = spl_fixpt_shl(mantiss, format->mantissa_bits);
*mantissa = spl_fixpt_floor(mantiss);
return true;
}
static bool spl_setup_custom_float(const struct spl_custom_float_format *format,
bool negative,
uint32_t mantissa,
uint32_t exponenta,
uint32_t *result)
{
uint32_t i = 0;
uint32_t j = 0;
uint32_t value = 0;
/* verification code:
* once calculation is ok we can remove it
*/
const uint32_t mantissa_mask =
(1 << (format->mantissa_bits + 1)) - 1;
const uint32_t exponenta_mask =
(1 << (format->exponenta_bits + 1)) - 1;
if (mantissa & ~mantissa_mask) {
SPL_BREAK_TO_DEBUGGER();
mantissa = mantissa_mask;
}
if (exponenta & ~exponenta_mask) {
SPL_BREAK_TO_DEBUGGER();
exponenta = exponenta_mask;
}
/* end of verification code */
while (i < format->mantissa_bits) {
uint32_t mask = 1 << i;
if (mantissa & mask)
value |= mask;
++i;
}
while (j < format->exponenta_bits) {
uint32_t mask = 1 << j;
if (exponenta & mask)
value |= mask << i;
++j;
}
if (negative && format->sign)
value |= 1 << (i + j);
*result = value;
return true;
}
bool SPL_NAMESPACE(spl_convert_to_custom_float_format(
struct spl_fixed31_32 value,
const struct spl_custom_float_format *format,
uint32_t *result))
{
uint32_t mantissa;
uint32_t exponenta;
bool negative;
return spl_build_custom_float(value, format, &negative, &mantissa, &exponenta) &&
spl_setup_custom_float(format,
negative,
mantissa,
exponenta,
result);
}

View file

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef SPL_CUSTOM_FLOAT_H_
#define SPL_CUSTOM_FLOAT_H_
#include "spl_os_types.h"
#include "spl_fixpt31_32.h"
struct spl_custom_float_format {
uint32_t mantissa_bits;
uint32_t exponenta_bits;
bool sign;
};
struct spl_custom_float_value {
uint32_t mantissa;
uint32_t exponenta;
uint32_t value;
bool negative;
};
bool SPL_NAMESPACE(spl_convert_to_custom_float_format(
struct spl_fixed31_32 value,
const struct spl_custom_float_format *format,
uint32_t *result));
#endif //SPL_CUSTOM_FLOAT_H_

View file

@ -0,0 +1,116 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef SPL_DEBUG_H
#define SPL_DEBUG_H
#if defined(LINUX_DM)
#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
#define SPL_ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
kgdb_breakpoint(); \
} \
} while (0)
#else
#define SPL_ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
; \
} \
} while (0)
#endif /* CONFIG_HAVE_KGDB || CONFIG_KGDB */
#if defined(CONFIG_DEBUG_KERNEL_DC)
#define SPL_ASSERT(expr) SPL_ASSERT_CRITICAL(expr)
#else
#define SPL_ASSERT(expr) WARN_ON(!(expr))
#endif /* CONFIG_DEBUG_KERNEL_DC */
#define SPL_BREAK_TO_DEBUGGER() SPL_ASSERT(0)
#else /* other DMs */
#ifdef DBG
/*
* Definition of a break to the debugger that should cover all platforms that
* we expect to run under. This break goes directly to the platform provided
* method for breaking. It does not use the MCIL interface.
*/
#if defined(__GNUC__)
#if defined(__i386__) || defined(__x86_64__)
#define SPL_BREAK_TO_DEBUGGER() __asm("int3;")
#elif defined(__powerpc__)
#define SPL_BREAK_TO_DEBUGGER() __asm(".long 0x7d821008 ")
#else
/*
* Unsupported GCC architecture. Define macro to
* generate error during compilation.
*/
#define SPL_BREAK_TO_DEBUGGER() 0
#endif
#elif defined(_WIN32)
/*
* Assume that we are using Microsoft compiler.
* Let's use compiler intrinsic
*/
#define SPL_BREAK_TO_DEBUGGER() __debugbreak()
#else
/*
* Unsupported Architecture. Define macro to
* generate error during compilation.
*/
#define SPL_BREAK_TO_DEBUGGER() 0
#endif
/*
* Hard assert with no message. Goes stright to debugger.
* Not supported through MCIL.
*/
#ifdef SPL_ASSERT
#undef SPL_ASSERT
#endif
#define SPL_ASSERT(b) {if (!(b)) {SPL_BREAK_TO_DEBUGGER(); }}
#define SPL_ASSERT_CRITICAL(expr) do {if (!(expr)) SPL_BREAK_TO_DEBUGGER(); } while (0)
/*
* DebugPrint() is a method of the DalBaseClass.
* This macro makes the assumption that it will be called from within a C++ object derived
* from the DalBaseClass.
*
* DALMSG uses the MCIL interface to display a runtime debug message.
*/
#define SPL_DALMSG(b) {DebugPrint b; }
#define SPL_DAL_ASSERT_MSG(b, m) {bool __bCondition_ = (b); if (!__bCondition_) {SPL_DALMSG(m) {SPL_BREAK_TO_DEBUGGER(); }; }; }
#else // DBG
#ifdef SPL_ASSERT
#undef SPL_ASSERT
#endif
//#define SPL_ASSERT(_bool) (do {} while (0))
#define SPL_ASSERT(_bool)
#define SPL_ASSERT_CRITICAL(expr) do {if (expr)/* Do nothing */; } while (0)
#ifdef SPL_BREAK_TO_DEBUGGER
#undef SPL_BREAK_TO_DEBUGGER
#endif
#define SPL_BREAK_TO_DEBUGGER()
#ifdef SPL_DALMSG
#undef SPL_DALMSG
#endif
#define SPL_DALMSG(b)
#ifdef SPL_DAL_ASSERT_MSG
#undef SPL_DAL_ASSERT_MSG
#endif
#define SPL_DAL_ASSERT_MSG(b, m)
#endif // DBG
#endif /* LINUX_DM */
#endif // SPL_DEBUG_H

View file

@ -0,0 +1,496 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "spl_fixpt31_32.h"
static const struct spl_fixed31_32 spl_fixpt_two_pi = { 26986075409LL };
static const struct spl_fixed31_32 spl_fixpt_ln2 = { 2977044471LL };
static const struct spl_fixed31_32 spl_fixpt_ln2_div_2 = { 1488522236LL };
static inline unsigned long long abs_i64(
long long arg)
{
if (arg > 0)
return (unsigned long long)arg;
else
return (unsigned long long)(-arg);
}
/*
* @brief
* result = dividend / divisor
* *remainder = dividend % divisor
*/
static inline unsigned long long spl_complete_integer_division_u64(
unsigned long long dividend,
unsigned long long divisor,
unsigned long long *remainder)
{
unsigned long long result;
result = spl_div64_u64_rem(dividend, divisor, (uint64_t *)remainder);
return result;
}
#define FRACTIONAL_PART_MASK \
((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1)
#define GET_INTEGER_PART(x) \
((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART)
#define GET_FRACTIONAL_PART(x) \
(FRACTIONAL_PART_MASK & (x))
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_fraction(
long long numerator, long long denominator))
{
struct spl_fixed31_32 res;
bool arg1_negative = numerator < 0;
bool arg2_negative = denominator < 0;
unsigned long long arg1_value = arg1_negative ? -numerator : numerator;
unsigned long long arg2_value = arg2_negative ? -denominator : denominator;
unsigned long long remainder;
/* determine integer part */
unsigned long long res_value = spl_complete_integer_division_u64(
arg1_value, arg2_value, &remainder);
SPL_ASSERT(res_value <= (unsigned long long)LONG_MAX);
/* determine fractional part */
{
unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART;
do {
remainder <<= 1;
res_value <<= 1;
if (remainder >= arg2_value) {
res_value |= 1;
remainder -= arg2_value;
}
} while (--i != 0);
}
/* round up LSB */
{
unsigned long long summand = (remainder << 1) >= arg2_value;
SPL_ASSERT(res_value <= (unsigned long long)LLONG_MAX - summand);
res_value += summand;
}
res.value = (long long)res_value;
if (arg1_negative ^ arg2_negative)
res.value = -res.value;
return res;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_mul(
struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2))
{
struct spl_fixed31_32 res;
bool arg1_negative = arg1.value < 0;
bool arg2_negative = arg2.value < 0;
unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value;
unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value;
unsigned long long arg1_int = GET_INTEGER_PART(arg1_value);
unsigned long long arg2_int = GET_INTEGER_PART(arg2_value);
unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value);
unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value);
unsigned long long tmp;
res.value = arg1_int * arg2_int;
SPL_ASSERT(res.value <= (long long)LONG_MAX);
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
tmp = arg1_int * arg2_fra;
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
tmp = arg2_int * arg1_fra;
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
tmp = arg1_fra * arg2_fra;
tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
(tmp >= (unsigned long long)spl_fixpt_half.value);
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
if (arg1_negative ^ arg2_negative)
res.value = -res.value;
return res;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sqr(struct spl_fixed31_32 arg))
{
struct spl_fixed31_32 res;
unsigned long long arg_value = abs_i64(arg.value);
unsigned long long arg_int = GET_INTEGER_PART(arg_value);
unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value);
unsigned long long tmp;
res.value = arg_int * arg_int;
SPL_ASSERT(res.value <= (long long)LONG_MAX);
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
tmp = arg_int * arg_fra;
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
tmp = arg_fra * arg_fra;
tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
(tmp >= (unsigned long long)spl_fixpt_half.value);
SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
return res;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_recip(struct spl_fixed31_32 arg))
{
/*
* @note
* Good idea to use Newton's method
*/
return SPL_NAMESPACE(spl_fixpt_from_fraction(
spl_fixpt_one.value,
arg.value));
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sinc(struct spl_fixed31_32 arg))
{
struct spl_fixed31_32 square;
struct spl_fixed31_32 res = spl_fixpt_one;
int n = 27;
struct spl_fixed31_32 arg_norm = arg;
if (spl_fixpt_le(
spl_fixpt_two_pi,
spl_fixpt_abs(arg))) {
arg_norm = spl_fixpt_sub(
arg_norm,
spl_fixpt_mul_int(
spl_fixpt_two_pi,
(int)spl_div64_s64(
arg_norm.value,
spl_fixpt_two_pi.value)));
}
square = SPL_NAMESPACE(spl_fixpt_sqr(arg_norm));
do {
res = spl_fixpt_sub(
spl_fixpt_one,
spl_fixpt_div_int(
SPL_NAMESPACE(spl_fixpt_mul(
square,
res)),
n * (n - 1)));
n -= 2;
} while (n > 2);
if (arg.value != arg_norm.value)
res = spl_fixpt_div(
SPL_NAMESPACE(spl_fixpt_mul(res, arg_norm)),
arg);
return res;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sin(struct spl_fixed31_32 arg))
{
return SPL_NAMESPACE(spl_fixpt_mul(
arg,
SPL_NAMESPACE(spl_fixpt_sinc(arg))));
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_cos(struct spl_fixed31_32 arg))
{
/* TODO implement argument normalization */
const struct spl_fixed31_32 square = SPL_NAMESPACE(spl_fixpt_sqr(arg));
struct spl_fixed31_32 res = spl_fixpt_one;
int n = 26;
do {
res = spl_fixpt_sub(
spl_fixpt_one,
spl_fixpt_div_int(
SPL_NAMESPACE(spl_fixpt_mul(
square,
res)),
n * (n - 1)));
n -= 2;
} while (n != 0);
return res;
}
/*
* @brief
* result = exp(arg),
* where abs(arg) < 1
*
* Calculated as Taylor series.
*/
static struct spl_fixed31_32 spl_fixed31_32_exp_from_taylor_series(struct spl_fixed31_32 arg)
{
unsigned int n = 9;
struct spl_fixed31_32 res = SPL_NAMESPACE(spl_fixpt_from_fraction(
n + 2,
n + 1));
/* TODO find correct res */
SPL_ASSERT(spl_fixpt_lt(arg, spl_fixpt_one));
do
res = spl_fixpt_add(
spl_fixpt_one,
spl_fixpt_div_int(
SPL_NAMESPACE(spl_fixpt_mul(
arg,
res)),
n));
while (--n != 1);
return spl_fixpt_add(
spl_fixpt_one,
SPL_NAMESPACE(spl_fixpt_mul(
arg,
res)));
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_exp(struct spl_fixed31_32 arg))
{
/*
* @brief
* Main equation is:
* exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r),
* where m = round(x / ln(2)), r = x - m * ln(2)
*/
if (spl_fixpt_le(
spl_fixpt_ln2_div_2,
spl_fixpt_abs(arg))) {
int m = spl_fixpt_round(
spl_fixpt_div(
arg,
spl_fixpt_ln2));
struct spl_fixed31_32 r = spl_fixpt_sub(
arg,
spl_fixpt_mul_int(
spl_fixpt_ln2,
m));
SPL_ASSERT(m != 0);
SPL_ASSERT(spl_fixpt_lt(
spl_fixpt_abs(r),
spl_fixpt_one));
if (m > 0)
return spl_fixpt_shl(
spl_fixed31_32_exp_from_taylor_series(r),
(unsigned int)m);
else
return spl_fixpt_div_int(
spl_fixed31_32_exp_from_taylor_series(r),
1LL << -m);
} else if (arg.value != 0)
return spl_fixed31_32_exp_from_taylor_series(arg);
else
return spl_fixpt_one;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_log(struct spl_fixed31_32 arg))
{
struct spl_fixed31_32 res = spl_fixpt_neg(spl_fixpt_one);
/* TODO improve 1st estimation */
struct spl_fixed31_32 error;
SPL_ASSERT(arg.value > 0);
/* TODO if arg is negative, return NaN */
/* TODO if arg is zero, return -INF */
do {
struct spl_fixed31_32 res1 = spl_fixpt_add(
spl_fixpt_sub(
res,
spl_fixpt_one),
spl_fixpt_div(
arg,
SPL_NAMESPACE(spl_fixpt_exp(res))));
error = spl_fixpt_sub(
res,
res1);
res = res1;
/* TODO determine max_allowed_error based on quality of exp() */
} while (abs_i64(error.value) > 100ULL);
return res;
}
/* this function is a generic helper to translate fixed point value to
* specified integer format that will consist of integer_bits integer part and
* fractional_bits fractional part. For example it is used in
* spl_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional
* part in 32 bits. It is used in hw programming (scaler)
*/
static inline unsigned int spl_ux_dy(
long long value,
unsigned int integer_bits,
unsigned int fractional_bits)
{
/* 1. create mask of integer part */
unsigned int result = (1 << integer_bits) - 1;
/* 2. mask out fractional part */
unsigned int fractional_part = FRACTIONAL_PART_MASK & value;
/* 3. shrink fixed point integer part to be of integer_bits width*/
result &= GET_INTEGER_PART(value);
/* 4. make space for fractional part to be filled in after integer */
result <<= fractional_bits;
/* 5. shrink fixed point fractional part to of fractional_bits width*/
fractional_part >>= FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits;
/* 6. merge the result */
return result | fractional_part;
}
static inline unsigned int spl_clamp_ux_dy(
long long value,
unsigned int integer_bits,
unsigned int fractional_bits,
unsigned int min_clamp)
{
unsigned int truncated_val = spl_ux_dy(value, integer_bits, fractional_bits);
if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART)))
return (1 << (integer_bits + fractional_bits)) - 1;
else if (truncated_val > min_clamp)
return truncated_val;
else
return min_clamp;
}
unsigned int SPL_NAMESPACE(spl_fixpt_u4d19(struct spl_fixed31_32 arg))
{
return spl_ux_dy(arg.value, 4, 19);
}
unsigned int SPL_NAMESPACE(spl_fixpt_u3d19(struct spl_fixed31_32 arg))
{
return spl_ux_dy(arg.value, 3, 19);
}
unsigned int SPL_NAMESPACE(spl_fixpt_u2d19(struct spl_fixed31_32 arg))
{
return spl_ux_dy(arg.value, 2, 19);
}
unsigned int SPL_NAMESPACE(spl_fixpt_u0d19(struct spl_fixed31_32 arg))
{
return spl_ux_dy(arg.value, 0, 19);
}
unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg))
{
return spl_clamp_ux_dy(arg.value, 0, 14, 1);
}
unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg))
{
return spl_clamp_ux_dy(arg.value, 0, 10, 1);
}
int SPL_NAMESPACE(spl_fixpt_s4d19(struct spl_fixed31_32 arg))
{
if (arg.value < 0)
return -(int)spl_ux_dy(spl_fixpt_abs(arg).value, 4, 19);
else
return spl_ux_dy(arg.value, 4, 19);
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_ux_dy(unsigned int value,
unsigned int integer_bits,
unsigned int fractional_bits))
{
struct spl_fixed31_32 fixpt_value = spl_fixpt_zero;
struct spl_fixed31_32 fixpt_int_value = spl_fixpt_zero;
long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
frac_mask = frac_mask << fractional_bits;
fixpt_int_value.value = value & frac_mask;
fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
fixpt_value.value |= fixpt_int_value.value;
return fixpt_value;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_int_dy(unsigned int int_value,
unsigned int frac_value,
unsigned int integer_bits,
unsigned int fractional_bits))
{
(void)integer_bits;
struct spl_fixed31_32 fixpt_value = spl_fixpt_from_int(int_value);
fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
return fixpt_value;
}

View file

@ -0,0 +1,526 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef __SPL_FIXED31_32_H__
#define __SPL_FIXED31_32_H__
#include "spl_debug.h"
#include "spl_os_types.h" // swap
#ifndef LLONG_MAX
#define LLONG_MAX 9223372036854775807ll
#endif
#ifndef LLONG_MIN
#define LLONG_MIN (-LLONG_MAX - 1ll)
#endif
#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
#ifndef LLONG_MIN
#define LLONG_MIN (1LL<<63)
#endif
#ifndef LLONG_MAX
#define LLONG_MAX (-1LL>>1)
#endif
/*
* @brief
* Arithmetic operations on real numbers
* represented as fixed-point numbers.
* There are: 1 bit for sign,
* 31 bit for integer part,
* 32 bits for fractional part.
*
* @note
* Currently, overflows and underflows are asserted;
* no special result returned.
*/
struct spl_fixed31_32 {
long long value;
};
/*
* @brief
* Useful constants
*/
static const struct spl_fixed31_32 spl_fixpt_zero = { 0 };
static const struct spl_fixed31_32 spl_fixpt_epsilon = { 1LL };
static const struct spl_fixed31_32 spl_fixpt_half = { 0x80000000LL };
static const struct spl_fixed31_32 spl_fixpt_one = { 0x100000000LL };
/*
* @brief
* Initialization routines
*/
/*
* @brief
* result = numerator / denominator
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_fraction(
long long numerator, long long denominator));
/*
* @brief
* result = arg
*/
static inline struct spl_fixed31_32 spl_fixpt_from_int(int arg)
{
struct spl_fixed31_32 res;
res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
return res;
}
/*
* @brief
* Unary operators
*/
/*
* @brief
* result = -arg
*/
static inline struct spl_fixed31_32 spl_fixpt_neg(struct spl_fixed31_32 arg)
{
struct spl_fixed31_32 res;
res.value = -arg.value;
return res;
}
/*
* @brief
* result = abs(arg) := (arg >= 0) ? arg : -arg
*/
static inline struct spl_fixed31_32 spl_fixpt_abs(struct spl_fixed31_32 arg)
{
if (arg.value < 0)
return spl_fixpt_neg(arg);
else
return arg;
}
/*
* @brief
* Binary relational operators
*/
/*
* @brief
* result = arg1 < arg2
*/
static inline bool spl_fixpt_lt(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
return arg1.value < arg2.value;
}
/*
* @brief
* result = arg1 <= arg2
*/
static inline bool spl_fixpt_le(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
return arg1.value <= arg2.value;
}
/*
* @brief
* result = arg1 == arg2
*/
static inline bool spl_fixpt_eq(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
return arg1.value == arg2.value;
}
/*
* @brief
* result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_min(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
if (arg1.value <= arg2.value)
return arg1;
else
return arg2;
}
/*
* @brief
* result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
*/
static inline struct spl_fixed31_32 spl_fixpt_max(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
if (arg1.value <= arg2.value)
return arg2;
else
return arg1;
}
/*
* @brief
* | min_value, when arg <= min_value
* result = | arg, when min_value < arg < max_value
* | max_value, when arg >= max_value
*/
static inline struct spl_fixed31_32 spl_fixpt_clamp(
struct spl_fixed31_32 arg,
struct spl_fixed31_32 min_value,
struct spl_fixed31_32 max_value)
{
if (spl_fixpt_le(arg, min_value))
return min_value;
else if (spl_fixpt_le(max_value, arg))
return max_value;
else
return arg;
}
/*
* @brief
* Binary shift operators
*/
/*
* @brief
* result = arg << shift
*/
static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned int shift)
{
SPL_ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
arg.value = arg.value << shift;
return arg;
}
/*
* @brief
* result = arg >> shift
*/
static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned int shift)
{
bool negative = arg.value < 0;
if (negative)
arg.value = -arg.value;
arg.value = arg.value >> shift;
if (negative)
arg.value = -arg.value;
return arg;
}
/*
* @brief
* Binary additive operators
*/
/*
* @brief
* result = arg1 + arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_add(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
struct spl_fixed31_32 res;
SPL_ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
res.value = arg1.value + arg2.value;
return res;
}
/*
* @brief
* result = arg1 + arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_add_int(struct spl_fixed31_32 arg1, int arg2)
{
return spl_fixpt_add(arg1, spl_fixpt_from_int(arg2));
}
/*
* @brief
* result = arg1 - arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_sub(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
struct spl_fixed31_32 res;
SPL_ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
res.value = arg1.value - arg2.value;
return res;
}
/*
* @brief
* result = arg1 - arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_sub_int(struct spl_fixed31_32 arg1, int arg2)
{
return spl_fixpt_sub(arg1, spl_fixpt_from_int(arg2));
}
/*
* @brief
* Binary multiplicative operators
*/
/*
* @brief
* result = arg1 * arg2
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_mul(
struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2));
/*
* @brief
* result = arg1 * arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_mul_int(struct spl_fixed31_32 arg1, int arg2)
{
return SPL_NAMESPACE(spl_fixpt_mul(arg1, spl_fixpt_from_int(arg2)));
}
/*
* @brief
* result = square(arg) := arg * arg
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sqr(struct spl_fixed31_32 arg));
/*
* @brief
* result = arg1 / arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_div_int(struct spl_fixed31_32 arg1, long long arg2)
{
return SPL_NAMESPACE(spl_fixpt_from_fraction(arg1.value,
spl_fixpt_from_int((int)arg2).value));
}
/*
* @brief
* result = arg1 / arg2
*/
static inline struct spl_fixed31_32 spl_fixpt_div(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
return SPL_NAMESPACE(spl_fixpt_from_fraction(arg1.value, arg2.value));
}
/*
* @brief
* Reciprocal function
*/
/*
* @brief
* result = reciprocal(arg) := 1 / arg
*
* @note
* No special actions taken in case argument is zero.
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_recip(struct spl_fixed31_32 arg));
/*
* @brief
* Trigonometric functions
*/
/*
* @brief
* result = sinc(arg) := sin(arg) / arg
*
* @note
* Argument specified in radians,
* internally it's normalized to [-2pi...2pi] range.
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sinc(struct spl_fixed31_32 arg));
/*
* @brief
* result = sin(arg)
*
* @note
* Argument specified in radians,
* internally it's normalized to [-2pi...2pi] range.
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sin(struct spl_fixed31_32 arg));
/*
* @brief
* result = cos(arg)
*
* @note
* Argument specified in radians
* and should be in [-2pi...2pi] range -
* passing arguments outside that range
* will cause incorrect result!
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_cos(struct spl_fixed31_32 arg));
/*
* @brief
* Transcendent functions
*/
/*
* @brief
* result = exp(arg)
*
* @note
* Currently, function is verified for abs(arg) <= 1.
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_exp(struct spl_fixed31_32 arg));
/*
* @brief
* result = log(arg)
*
* @note
* Currently, abs(arg) should be less than 1.
* No normalization is done.
* Currently, no special actions taken
* in case of invalid argument(s). Take care!
*/
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_log(struct spl_fixed31_32 arg));
/*
* @brief
* Power function
*/
/*
* @brief
* result = pow(arg1, arg2)
*
* @note
* Currently, abs(arg1) should be less than 1. Take care!
*/
static inline struct spl_fixed31_32 spl_fixpt_pow(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
{
if (arg1.value == 0)
return arg2.value == 0 ? spl_fixpt_one : spl_fixpt_zero;
return SPL_NAMESPACE(spl_fixpt_exp(
SPL_NAMESPACE(spl_fixpt_mul(
SPL_NAMESPACE(spl_fixpt_log(arg1)),
arg2))));
}
/*
* @brief
* Rounding functions
*/
/*
* @brief
* result = floor(arg) := greatest integer lower than or equal to arg
*/
static inline int spl_fixpt_floor(struct spl_fixed31_32 arg)
{
unsigned long long arg_value = (unsigned long long)(arg.value > 0 ? arg.value : -arg.value);
if (arg.value >= 0)
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
else
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
}
/*
* @brief
* result = round(arg) := integer nearest to arg
*/
static inline int spl_fixpt_round(struct spl_fixed31_32 arg)
{
unsigned long long arg_value = (unsigned long long)(arg.value > 0 ? arg.value : -arg.value);
const long long summand = spl_fixpt_half.value;
SPL_ASSERT(LLONG_MAX - (long long)arg_value >= summand);
arg_value += summand;
if (arg.value >= 0)
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
else
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
}
/*
* @brief
* result = ceil(arg) := lowest integer greater than or equal to arg
*/
static inline int spl_fixpt_ceil(struct spl_fixed31_32 arg)
{
unsigned long long arg_value = (unsigned long long)(arg.value > 0 ? arg.value : -arg.value);
const long long summand = spl_fixpt_one.value -
spl_fixpt_epsilon.value;
SPL_ASSERT(LLONG_MAX - (long long)arg_value >= summand);
arg_value += summand;
if (arg.value >= 0)
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
else
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
}
/* the following two function are used in scaler hw programming to convert fixed
* point value to format 2 bits from integer part and 19 bits from fractional
* part. The same applies for u0d19, 0 bits from integer part and 19 bits from
* fractional
*/
unsigned int SPL_NAMESPACE(spl_fixpt_u4d19(struct spl_fixed31_32 arg));
unsigned int SPL_NAMESPACE(spl_fixpt_u3d19(struct spl_fixed31_32 arg));
unsigned int SPL_NAMESPACE(spl_fixpt_u2d19(struct spl_fixed31_32 arg));
unsigned int SPL_NAMESPACE(spl_fixpt_u0d19(struct spl_fixed31_32 arg));
unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg));
unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg));
int SPL_NAMESPACE(spl_fixpt_s4d19(struct spl_fixed31_32 arg));
static inline struct spl_fixed31_32 spl_fixpt_truncate(struct spl_fixed31_32 arg, unsigned int frac_bits)
{
bool negative = arg.value < 0;
if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
SPL_ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
return arg;
}
if (negative)
arg.value = -arg.value;
arg.value &= (~0ULL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
if (negative)
arg.value = -arg.value;
return arg;
}
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_ux_dy(unsigned int value,
unsigned int integer_bits, unsigned int fractional_bits));
struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_int_dy(unsigned int int_value,
unsigned int frac_value,
unsigned int integer_bits,
unsigned int fractional_bits));
#endif

View file

@ -0,0 +1,122 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
/* Copyright 2019 Raptor Engineering, LLC */
#ifndef _SPL_OS_TYPES_H_
#define _SPL_OS_TYPES_H_
#include "spl_debug.h"
#ifdef LINUX_DM
#include <linux/slab.h>
#include <linux/kgdb.h>
#include <linux/kref.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/mm.h>
#else /* _WIN32 || DIAGS_BUILD */
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#endif /* LINUX_DM */
/*
*
* general debug capabilities
*
*/
#if defined(LINUX_DM)
static inline uint64_t spl_div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
return div_u64_rem(dividend, divisor, remainder);
}
static inline uint64_t spl_div_u64(uint64_t dividend, uint32_t divisor)
{
return div_u64(dividend, divisor);
}
static inline uint64_t spl_div64_u64(uint64_t dividend, uint64_t divisor)
{
return div64_u64(dividend, divisor);
}
static inline uint64_t spl_div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{
return div64_u64_rem(dividend, divisor, remainder);
}
static inline int64_t spl_div64_s64(int64_t dividend, int64_t divisor)
{
return div64_s64(dividend, divisor);
}
#else
static inline uint64_t spl_div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
if (remainder)
*remainder = dividend % divisor;
return dividend / divisor;
}
static inline uint64_t spl_div_u64(uint64_t dividend, uint32_t divisor)
{
return dividend / divisor;
}
static inline uint64_t spl_div64_u64(uint64_t dividend, uint64_t divisor)
{
return dividend / divisor;
}
static inline uint64_t spl_div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{
if (remainder)
*remainder = dividend % divisor;
return dividend / divisor;
}
static inline int64_t spl_div64_s64(int64_t dividend, int64_t divisor)
{
return dividend / divisor;
}
#endif /*LINUX_DM */
#if defined(_WIN32)
#define spl_swap(x, y) do { \
unsigned char swap_temp[sizeof(x) == sizeof(y) ? (signed int) sizeof(x) : -1]; \
memcpy(swap_temp, &y, sizeof(x)); \
y = x; \
memcpy(&x, swap_temp, sizeof(x)); \
} while (0)
#else
#define spl_swap(a, b) \
do { __typeof__(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
#endif /* _WIN32 */
#ifndef spl_min
#define spl_min(a, b) (((a) < (b)) ? (a):(b))
#endif
/* SPL namespace macros */
#ifndef SPL_PFX_
#define SPL_PFX_
#endif
#define SPL_EXPAND2(a, b) a##b
#define SPL_EXPAND(a, b) SPL_EXPAND2(a, b)
#define SPL_NAMESPACE(symbol) SPL_EXPAND(SPL_PFX_, symbol)
#endif /* _SPL_OS_TYPES_H_ */