amd,radeonsi: add libvpe

Signed-off-by: Peyton Lee <peytolee@amd.com>
Signed-off-by: Alan Liu <haoping.liu@amd.com>
Acked-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25713>
This commit is contained in:
Peyton Lee
2023-10-12 14:04:31 +08:00
committed by Marge Bot
parent 6b441ef6ab
commit 17c20ceda7
90 changed files with 38175 additions and 2 deletions
+4
View File
@@ -41,3 +41,7 @@ endif
if with_tools.contains('drm-shim')
subdir('drm-shim')
endif
if with_gallium_radeonsi
subdir('vpelib')
endif
+33
View File
@@ -0,0 +1,33 @@
# VPE-LIB
VPE C library for AMD drivers
Folder Architecture
===================
```text
[root]
|
+-- [inc] ## public header to external modules
|
+-- [src] ##internal implementation
|
+-- [chip] ## store chip specific files
| |
| +-- [vpeXX] ## asic specific files e.g. vpe10
| |
| +-- [inc] ## all headers for vpe[XX]
| |
| +-- [asic] ## store all headers that
| ## could conflict with headers in other asics
| ## src file has to explicitly include the files here
| ## without relying the compilation include directory path
|
|
+ -- [core] ## files that share for all asics
| |
| +-- [inc] ## define the base functions that each vpe[xx] should implement
|
-- [utils] ## utility functions like fixed point or u64 calculation
|
+-- [inc] ## utils headers
```
+256
View File
@@ -0,0 +1,256 @@
/* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
* Note: do *not* add any types which are *not* used for HW programming.
* this will ensure separation of Logic layer from HW layer
***********************************************************************/
union large_integer {
struct {
uint32_t low_part;
int32_t high_part;
};
struct {
uint32_t low_part;
int32_t high_part;
} u;
int64_t quad_part;
};
#define PHYSICAL_ADDRESS_LOC union large_integer
enum vpe_plane_addr_type {
VPE_PLN_ADDR_TYPE_GRAPHICS = 0,
VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE
};
struct vpe_plane_address {
enum vpe_plane_addr_type type;
bool tmz_surface;
union {
struct {
PHYSICAL_ADDRESS_LOC addr;
PHYSICAL_ADDRESS_LOC meta_addr;
union large_integer dcc_const_color;
} grph;
/*video progressive*/
struct {
PHYSICAL_ADDRESS_LOC luma_addr;
PHYSICAL_ADDRESS_LOC luma_meta_addr;
union large_integer luma_dcc_const_color;
PHYSICAL_ADDRESS_LOC chroma_addr;
PHYSICAL_ADDRESS_LOC chroma_meta_addr;
union large_integer chroma_dcc_const_color;
} video_progressive;
};
};
/* Rotation angle */
enum vpe_rotation_angle {
VPE_ROTATION_ANGLE_0 = 0,
VPE_ROTATION_ANGLE_90,
VPE_ROTATION_ANGLE_180,
VPE_ROTATION_ANGLE_270,
VPE_ROTATION_ANGLE_COUNT
};
/* mirror */
enum vpe_mirror {
VPE_MIRROR_NONE,
VPE_MIRROR_HORIZONTAL,
VPE_MIRROR_VERTICAL
};
enum vpe_scan_direction {
VPE_SCAN_DIRECTION_UNKNOWN = 0,
VPE_SCAN_DIRECTION_HORIZONTAL = 1, /* 0, 180 rotation */
VPE_SCAN_DIRECTION_VERTICAL = 2, /* 90, 270 rotation */
};
struct vpe_size {
uint32_t width;
uint32_t height;
};
struct vpe_rect {
int32_t x;
int32_t y;
uint32_t width;
uint32_t height;
};
struct vpe_plane_size {
struct vpe_rect surface_size;
struct vpe_rect chroma_size;
// actual aligned pitch and height
uint32_t surface_pitch;
uint32_t chroma_pitch;
uint32_t surface_aligned_height;
uint32_t chrome_aligned_height;
};
struct vpe_plane_dcc_param {
bool enable;
uint32_t meta_pitch;
bool independent_64b_blks;
uint8_t dcc_ind_blk;
uint32_t meta_pitch_c;
bool independent_64b_blks_c;
uint8_t dcc_ind_blk_c;
};
/** Displayable pixel format in fb */
enum vpe_surface_pixel_format {
VPE_SURFACE_PIXEL_FORMAT_GRPH_BEGIN = 0,
/*16 bpp*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555,
/*16 bpp*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565,
/*32 bpp*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888,
/*32 bpp swaped*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888,
/*32 bpp alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888,
/*32 bpp swaped & alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888,
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010,
/*swaped*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010,
/*alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102,
/*swaped & alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102,
/*64 bpp */
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616,
/*float*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F,
/*swaped & float*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F,
/*alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F,
/*swaped & alpha rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F,
VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888,
/*swaped*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888,
/*rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888,
/*swaped & rotated*/
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888,
/*grow graphics here if necessary */
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX,
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX,
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT,
VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT,
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE,
VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCrCb,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY,
VPE_SURFACE_PIXEL_FORMAT_SUBSAMPLE_END = VPE_SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888,
VPE_SURFACE_PIXEL_FORMAT_VIDEO_END = VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888,
VPE_SURFACE_PIXEL_FORMAT_INVALID
/*grow 444 video here if necessary */
};
enum vpe_swizzle_mode_values {
VPE_SW_LINEAR = 0,
VPE_SW_256B_S = 1,
VPE_SW_256B_D = 2,
VPE_SW_256B_R = 3,
VPE_SW_4KB_Z = 4,
VPE_SW_4KB_S = 5,
VPE_SW_4KB_D = 6,
VPE_SW_4KB_R = 7,
VPE_SW_64KB_Z = 8,
VPE_SW_64KB_S = 9,
VPE_SW_64KB_D = 10,
VPE_SW_64KB_R = 11,
VPE_SW_VAR_Z = 12,
VPE_SW_VAR_S = 13,
VPE_SW_VAR_D = 14,
VPE_SW_VAR_R = 15,
VPE_SW_64KB_Z_T = 16,
VPE_SW_64KB_S_T = 17,
VPE_SW_64KB_D_T = 18,
VPE_SW_64KB_R_T = 19,
VPE_SW_4KB_Z_X = 20,
VPE_SW_4KB_S_X = 21,
VPE_SW_4KB_D_X = 22,
VPE_SW_4KB_R_X = 23,
VPE_SW_64KB_Z_X = 24,
VPE_SW_64KB_S_X = 25,
VPE_SW_64KB_D_X = 26,
VPE_SW_64KB_R_X = 27,
VPE_SW_VAR_Z_X = 28,
VPE_SW_VAR_S_X = 29,
VPE_SW_VAR_D_X = 30,
VPE_SW_VAR_R_X = 31,
VPE_SW_MAX = 32,
VPE_SW_UNKNOWN = VPE_SW_MAX
};
/** specify the number of taps.
* if 0 is specified, it will use 4 taps by default */
struct vpe_scaling_taps {
uint32_t v_taps;
uint32_t h_taps;
uint32_t v_taps_c;
uint32_t h_taps_c;
};
#ifdef __cplusplus
}
#endif
+626
View File
@@ -0,0 +1,626 @@
/* 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 <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#include "vpe_hw_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe;
#define MAX_NB_POLYPHASE_COEFFS \
(8 * 33) /* currently vpe supports up to 8 taps and 64 phases, only (32+1) phases needed*/
enum vpe_status {
VPE_STATUS_OK = 1,
VPE_STATUS_ERROR,
VPE_STATUS_NO_MEMORY,
// errors for not supported operations
VPE_STATUS_NOT_SUPPORTED,
VPE_STATUS_DCC_NOT_SUPPORTED,
VPE_STATUS_SWIZZLE_NOT_SUPPORTED,
VPE_STATUS_NUM_STREAM_NOT_SUPPORTED,
VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED,
VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED,
VPE_STATUS_SCALING_RATIO_NOT_SUPPORTED,
VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED,
VPE_STATUS_ROTATION_NOT_SUPPORTED,
VPE_STATUS_MIRROR_NOT_SUPPORTED,
VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED,
VPE_STATUS_VIEWPORT_SIZE_NOT_SUPPORTED,
VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED,
VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED,
VPE_STATUS_ADJUSTMENT_NOT_SUPPORTED,
VPE_STATUS_CMD_OVERFLOW_ERROR,
VPE_STATUS_SEGMENT_WIDTH_ERROR,
VPE_STATUS_PARAM_CHECK_ERROR,
VPE_STATUS_TONE_MAP_NOT_SUPPORTED,
VPE_STATUS_BAD_TONE_MAP_PARAMS,
VPE_STATUS_BAD_HDR_METADATA,
VPE_STATUS_BUFFER_OVERFLOW,
VPE_STATUS_BUFFER_UNDERRUN,
VPE_STATUS_BG_COLOR_OUT_OF_RANGE,
VPE_STATUS_REPEAT_ITEM,
VPE_STATUS_PATCH_OVER_MAXSIZE,
VPE_STATUS_INVALID_BUFFER_SIZE,
VPE_STATUS_SCALER_NOT_SET
};
/** HW IP level */
enum vpe_ip_level {
VPE_IP_LEVEL_UNKNOWN = (-1),
VPE_IP_LEVEL_1_0,
};
/****************************************
* Plane Caps
****************************************/
struct vpe_pixel_format_support {
uint32_t argb_packed_32b : 1;
uint32_t nv12 : 1;
uint32_t fp16 : 1;
uint32_t p010 : 1; /**< planar 4:2:0 10-bit */
uint32_t p016 : 1; /**< planar 4:2:0 16-bit */
uint32_t ayuv : 1; /**< packed 4:4:4 */
uint32_t yuy2 : 1; /**< packed 4:2:2 */
};
struct vpe_plane_caps {
uint32_t per_pixel_alpha : 1;
struct vpe_pixel_format_support input_pixel_format_support;
struct vpe_pixel_format_support output_pixel_format_support;
/* max upscaling factor x 1000
* upscaling factors are always >= 1
* e.g. 1080p -> 8K is 4.0 => 4000
*/
uint32_t max_upscale_factor;
/* max downscale factor x1000
* downscale factors are always <= 1
* e.g 8K -> 1080p is 0.25 => 250
*/
uint32_t max_downscale_factor;
uint32_t pitch_alignment; /**< alignment in bytes */
uint32_t addr_alignment; /**< alignment in bytes */
uint32_t max_viewport_width;
};
/*************************
* Color management caps
*************************/
struct vpe_rom_curve_caps {
uint32_t srgb : 1;
uint32_t bt2020 : 1;
uint32_t gamma2_2 : 1;
uint32_t pq : 1;
uint32_t hlg : 1;
};
struct dpp_color_caps {
uint32_t pre_csc : 1;
uint32_t luma_key : 1;
uint32_t dgam_ram : 1;
uint32_t post_csc : 1; /**< before gamut remap */
uint32_t gamma_corr : 1;
uint32_t hw_3dlut : 1;
uint32_t ogam_ram : 1;
uint32_t ocsc : 1;
struct vpe_rom_curve_caps dgam_rom_caps;
};
struct mpc_color_caps {
uint32_t gamut_remap : 1;
uint32_t ogam_ram : 1;
uint32_t ocsc : 1;
uint32_t shared_3d_lut : 1; /**< can be in either dpp or mpc, but single instance */
uint32_t global_alpha : 1; /**< e.g. top plane 30 %. bottom 70 % */
uint32_t top_bottom_blending : 1; /**< two-layer blending */
};
struct vpe_color_caps {
struct dpp_color_caps dpp;
struct mpc_color_caps mpc;
};
/**************************************************
* VPE Capabilities.
*
* Those depend on the condition like input format
* shall be queried by vpe_cap_funcs
**************************************************/
struct vpe_caps {
uint32_t max_downscale_ratio; /**< max downscaling ratio in hundred.
ratio as src/dest x 100. e.g 600 */
uint64_t lut_size; /**< 3dlut size */
uint32_t rotation_support : 1;
uint32_t h_mirror_support : 1;
uint32_t v_mirror_support : 1;
uint32_t is_apu : 1;
uint32_t bg_color_check_support : 1;
struct {
int num_dpp;
int num_opp;
int num_mpc_3dlut;
int num_queue; /**< num of hw queue */
} resource_caps;
struct vpe_color_caps color_caps;
struct vpe_plane_caps plane_caps;
};
/***********************************
* Conditional Capabilities
***********************************/
/** DCC CAP */
struct vpe_dcc_surface_param {
struct vpe_size surface_size;
enum vpe_surface_pixel_format format;
enum vpe_swizzle_mode_values swizzle_mode;
enum vpe_scan_direction scan;
};
struct vpe_dcc_setting {
unsigned int max_compressed_blk_size;
unsigned int max_uncompressed_blk_size;
bool independent_64b_blks;
struct {
uint32_t dcc_256_64_64 : 1;
uint32_t dcc_128_128_uncontrained : 1;
uint32_t dcc_256_128_128 : 1;
uint32_t dcc_256_256_unconstrained : 1;
} dcc_controls;
};
struct vpe_surface_dcc_cap {
union {
struct {
struct vpe_dcc_setting rgb;
} grph;
struct {
struct vpe_dcc_setting luma;
struct vpe_dcc_setting chroma;
} video;
};
bool capable;
bool const_color_support;
};
/** Conditional Capability functions */
struct vpe_cap_funcs {
/**
* Get DCC support and setting according to the format,
* scan direction and swizzle mdoe.
*
* @param[in] vpe vpe instance
* @param[in] input surface and scan properties
* @param[in/out] output dcc capable result and related settings
* @return true if supported
*/
bool (*get_dcc_compression_cap)(const struct vpe *vpe,
const struct vpe_dcc_surface_param *input, struct vpe_surface_dcc_cap *output);
};
/****************************************
* VPE Init Param
****************************************/
/** Log function
* @param[in] log_ctx given in the struct vpe_init_params
* @param[in] fmt format string
*/
typedef void (*vpe_log_func_t)(void *log_ctx, const char *fmt, ...);
/** system memory zalloc, allocated memory initailized with 0
*
* @param[in] mem_ctx given in the struct vpe_init_params
* @param[in] size number of bytes
* @return allocated memory
*/
typedef void *(*vpe_zalloc_func_t)(void *mem_ctx, size_t size);
/** system memory free
* @param[in] mem_ctx given in the struct vpe_init_params
* @param[in] ptr number of bytes
*/
typedef void (*vpe_free_func_t)(void *mem_ctx, void *ptr);
struct vpe_callback_funcs {
void *log_ctx; /**< optional. provided by the caller and pass back to callback */
vpe_log_func_t log;
void *mem_ctx; /**< optional. provided by the caller and pass back to callback */
vpe_zalloc_func_t zalloc;
vpe_free_func_t free;
};
struct vpe_mem_low_power_enable_options {
// override flags
struct {
uint32_t dscl : 1;
uint32_t cm : 1;
uint32_t mpc : 1;
} flags;
struct {
uint32_t dscl : 1;
uint32_t cm : 1;
uint32_t mpc : 1;
} bits;
};
enum vpe_expansion_mode {
VPE_EXPANSION_MODE_DYNAMIC,
VPE_EXPANSION_MODE_ZERO
};
enum vpe_clamping_range {
VPE_CLAMPING_FULL_RANGE = 0, /* No Clamping */
VPE_CLAMPING_LIMITED_RANGE_8BPC, /* 8 bpc: Clamping 1 to FE */
VPE_CLAMPING_LIMITED_RANGE_10BPC, /* 10 bpc: Clamping 4 to 3FB */
VPE_CLAMPING_LIMITED_RANGE_12BPC, /* 12 bpc: Clamping 10 to FEF */
/* Use programmable clampping value on FMT_CLAMP_COMPONENT_R/G/B. */
VPE_CLAMPING_LIMITED_RANGE_PROGRAMMABLE
};
struct vpe_clamping_params {
enum vpe_clamping_range clamping_range;
uint32_t r_clamp_component_upper;
uint32_t b_clamp_component_upper;
uint32_t g_clamp_component_upper;
uint32_t r_clamp_component_lower;
uint32_t b_clamp_component_lower;
uint32_t g_clamp_component_lower;
};
struct vpe_visual_confirm {
union {
struct {
uint32_t input_format : 1;
uint32_t output_format : 1;
uint32_t reserved : 30;
};
uint32_t value;
};
};
/** configurable params for debugging purpose */
struct vpe_debug_options {
// override flags
struct {
uint32_t cm_in_bypass : 1;
uint32_t vpcnvc_bypass : 1;
uint32_t mpc_bypass : 1;
uint32_t identity_3dlut : 1;
uint32_t sce_3dlut : 1;
uint32_t disable_reuse_bit : 1;
uint32_t bg_color_fill_only : 1;
uint32_t assert_when_not_support : 1;
uint32_t bypass_gamcor : 1;
uint32_t bypass_ogam : 1;
uint32_t force_tf_calculation : 1;
uint32_t bypass_dpp_gamut_remap : 1;
uint32_t bypass_post_csc : 1;
uint32_t clamping_setting : 1;
uint32_t expansion_mode : 1;
uint32_t bypass_per_pixel_alpha : 1;
uint32_t dpp_crc_ctrl : 1;
uint32_t opp_pipe_crc_ctrl : 1;
uint32_t mpc_crc_ctrl : 1;
uint32_t bg_bit_depth : 1;
uint32_t visual_confirm : 1;
} flags;
// valid only if the corresponding flag is set
uint32_t cm_in_bypass : 1;
uint32_t vpcnvc_bypass : 1;
uint32_t mpc_bypass : 1;
uint32_t identity_3dlut : 1;
uint32_t sce_3dlut : 1;
uint32_t disable_reuse_bit : 1;
uint32_t bg_color_fill_only : 1;
uint32_t assert_when_not_support : 1;
uint32_t bypass_gamcor : 1;
uint32_t bypass_ogam : 1;
uint32_t force_tf_calculation : 1;
uint32_t bypass_dpp_gamut_remap : 1;
uint32_t bypass_post_csc : 1;
uint32_t clamping_setting : 1;
uint32_t bypass_per_pixel_alpha : 1;
uint32_t dpp_crc_ctrl : 1;
uint32_t opp_pipe_crc_ctrl : 1;
uint32_t mpc_crc_ctrl : 1;
uint32_t bg_bit_depth;
struct vpe_mem_low_power_enable_options enable_mem_low_power;
enum vpe_expansion_mode expansion_mode;
struct vpe_clamping_params clamping_params;
struct vpe_visual_confirm visual_confirm_params;
};
struct vpe_init_data {
/** vpe ip info */
uint8_t ver_major;
uint8_t ver_minor;
uint8_t ver_rev;
/** function callbacks */
struct vpe_callback_funcs funcs;
/** debug options */
struct vpe_debug_options debug;
};
/** VPE instance created through vpelib entry function vpe_create() */
struct vpe {
uint32_t version; /**< API version */
enum vpe_ip_level level; /**< HW IP level */
struct vpe_caps *caps; /**< general static chip caps */
struct vpe_cap_funcs *cap_funcs; /**< conditional caps */
};
/*****************************************************
* Structures for build VPE command
*****************************************************/
enum vpe_pixel_encoding {
VPE_PIXEL_ENCODING_YCbCr,
VPE_PIXEL_ENCODING_RGB,
VPE_PIXEL_ENCODING_COUNT
};
enum vpe_color_range {
VPE_COLOR_RANGE_FULL,
VPE_COLOR_RANGE_STUDIO,
VPE_COLOR_RANGE_COUNT
};
enum vpe_chroma_cositing {
VPE_CHROMA_COSITING_NONE,
VPE_CHROMA_COSITING_LEFT,
VPE_CHROMA_COSITING_TOPLEFT,
VPE_CHROMA_COSITING_COUNT
};
enum vpe_color_primaries {
VPE_PRIMARIES_BT601,
VPE_PRIMARIES_BT709,
VPE_PRIMARIES_BT2020,
VPE_PRIMARIES_JFIF,
VPE_PRIMARIES_COUNT
};
enum vpe_transfer_function {
VPE_TF_G22,
VPE_TF_G24,
VPE_TF_G10,
VPE_TF_PQ,
VPE_TF_PQ_NORMALIZED,
VPE_TF_HLG,
VPE_TF_COUNT
};
enum vpe_alpha_mode {
VPE_ALPHA_OPAQUE,
VPE_ALPHA_BGCOLOR
};
struct vpe_color_space {
enum vpe_pixel_encoding encoding;
enum vpe_color_range range;
enum vpe_transfer_function tf;
enum vpe_chroma_cositing cositing;
enum vpe_color_primaries primaries;
};
/* component values are in the range: 0 - 1.0f */
struct vpe_color_rgba {
float r;
float g;
float b;
float a;
};
struct vpe_color_ycbcra {
float y;
float cb;
float cr;
float a;
};
struct vpe_color {
bool is_ycbcr;
union {
struct vpe_color_rgba rgba;
struct vpe_color_ycbcra ycbcra;
};
};
/**
* Adjustment Min Max default step
* Brightness -100.0f, 100.0f, 0.0f, 0.1f
* Contrast 0.0f, 2.0f, 1.0f, 0.01f
* Hue -180.0f, 180.0f, 0.0f, 1.0f
* Saturation 0.0f, 3.0f, 1.0f, 0.01f
*
*/
struct vpe_color_adjust {
float brightness;
float contrast;
float hue;
float saturation;
};
struct vpe_surface_info {
/** surface addressing info */
struct vpe_plane_address address;
enum vpe_swizzle_mode_values swizzle;
/** surface properties */
struct vpe_plane_size plane_size; /**< pitch */
struct vpe_plane_dcc_param dcc;
enum vpe_surface_pixel_format format;
struct vpe_color_space cs;
};
struct vpe_blend_info {
bool blending; /**< enable blending */
bool pre_multiplied_alpha; /**< is the pixel value pre-multiplied with alpha */
bool global_alpha; /**< enable global alpha */
float global_alpha_value; /**< global alpha value, should be 0.0~1.0 */
};
struct vpe_scaling_info {
struct vpe_rect src_rect;
struct vpe_rect dst_rect;
struct vpe_scaling_taps taps;
};
struct vpe_scaling_filter_coeffs {
struct vpe_scaling_taps taps;
unsigned int nb_phases;
uint16_t horiz_polyphase_coeffs[MAX_NB_POLYPHASE_COEFFS]; /*max nb of taps is 4, max nb of
phases 33 = (32+1)*/
uint16_t vert_polyphase_coeffs[MAX_NB_POLYPHASE_COEFFS]; /*max nb of taps is 4, max nb of phases
33 = (32+1)*/
};
struct vpe_hdr_metadata {
uint16_t redX;
uint16_t redY;
uint16_t greenX;
uint16_t greenY;
uint16_t blueX;
uint16_t blueY;
uint16_t whiteX;
uint16_t whiteY;
uint32_t min_mastering; // luminance in 1/10000 nits
uint32_t max_mastering; // luminance in nits
uint32_t max_content;
uint32_t avg_content;
};
struct vpe_tonemap_params {
enum vpe_transfer_function shaper_tf;
enum vpe_transfer_function lut_out_tf;
enum vpe_color_primaries lut_in_gamut;
enum vpe_color_primaries lut_out_gamut;
uint16_t lut_dim;
uint16_t *lut_data;
bool update_3dlut;
bool enable_3dlut;
};
struct vpe_stream {
struct vpe_surface_info surface_info;
struct vpe_scaling_info scaling_info;
struct vpe_blend_info blend_info;
struct vpe_color_adjust color_adj;
struct vpe_tonemap_params tm_params;
struct vpe_hdr_metadata hdr_metadata;
struct vpe_scaling_filter_coeffs polyphase_scaling_coeffs;
enum vpe_rotation_angle rotation;
bool horizontal_mirror;
bool vertical_mirror;
bool use_external_scaling_coeffs;
bool enable_luma_key;
float lower_luma_bound;
float upper_luma_bound;
struct {
uint32_t hdr_metadata : 1;
uint32_t reserved : 31;
} flags;
};
struct vpe_build_param {
/** source */
uint32_t num_streams;
struct vpe_stream *streams;
/** destination */
struct vpe_surface_info dst_surface;
struct vpe_rect target_rect; /**< rectangle in target surface to be blt'd. Ranges out of rect
won't be touched */
struct vpe_color bg_color;
enum vpe_alpha_mode alpha_mode;
struct vpe_hdr_metadata hdr_metadata;
// data flags
struct {
uint32_t hdr_metadata : 1;
uint32_t reserved : 31;
} flags;
};
/** reported through vpe_check_support()
* Once the operation is supported,
* it returns the required memory for storing
* 1. command buffer
* 2. embedded buffer
* - Pointed by the command buffer content.
* - Shall be free'ed together with command buffer once
* command is finished.
*/
struct vpe_bufs_req {
uint64_t cmd_buf_size; /**< total command buffer size for all vpe commands */
uint64_t emb_buf_size; /**< total size for storing all embedded data */
};
struct vpe_buf {
uint64_t gpu_va; /**< GPU start address of the buffer */
uint64_t cpu_va;
int64_t size;
bool tmz; /**< allocated from tmz */
};
struct vpe_build_bufs {
struct vpe_buf cmd_buf; /**< Command buffer. gpu_va is optional */
struct vpe_buf emb_buf; /**< Embedded buffer */
};
#ifdef __cplusplus
}
#endif
+55
View File
@@ -0,0 +1,55 @@
/* 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
#define VPELIB_API_VERSION_MAJOR 0
#define VPELIB_API_VERSION_MINOR 3
#define VPELIB_API_VERSION_MAJOR_SHIFT 16
#define VPELIB_API_VERSION_MINOR_SHIFT 0
#define VPELIB_API_VERSION_MAJOR_MASK 0xFFFF0000
#define VPELIB_API_VERSION_MINOR_MASK 0x0000FFFF
#define VPELIB_GET_API_MAJOR(version) \
((version & VPELIB_API_VERSION_MAJOR_MASK) >> VPELIB_API_VERSION_MAJOR_SHIFT)
#define VPELIB_GET_API_MINOR(version) \
((version & VPELIB_API_VERSION_MINOR_MASK) >> VPELIB_API_VERSION_MINOR_SHIFT)
#define VPE_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv))
#define VPE_VERSION_MAJ(ver) ((ver) >> 16)
#define VPE_VERSION_MIN(ver) (((ver) >> 8) & 0xFF)
#define VPE_VERSION_REV(ver) ((ver) & 0xFF)
#define VPE_VERSION_6_1_0(ver) ((ver) == VPE_VERSION(6, 1, 0))
#define VPE_VERSION_6_1_1(ver) ((ver) == VPE_VERSION(6, 1, 1))
#ifdef __cplusplus
}
#endif
+106
View File
@@ -0,0 +1,106 @@
/* 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 "vpe_types.h"
#include "vpe_version.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @brief Create the VPE lib instance.
*
* Caler provides the current asic info,
* logging and system memory APIs.
* It initializes all the necessary resources for the asic
* and returns the general capabilities of the engines.
*
* For capabilities based on conditions,
* shall be done by vpe->cap_funcs.*
*
*
* @param[in] params provide the asic version, APIs for logging and memory
* @return vpe instance if supported. NULL otherwise
*/
struct vpe *vpe_create(const struct vpe_init_data *params);
/* @brief Destroy the VPE lib instance and resources
*
* @param[in] vpe the vpe instance created by vpe_create
*/
void vpe_destroy(struct vpe **vpe);
/**
* @brief Check if the VPE operation is supported.
*
* Caller must call this to check if the VPE supports
* the requested operation before calling vpe_build_commands().
* If operation is supported, it returns the memory requirement.
*
* The caller has to prepare those required memories
* and pass them to the vpe_build_commands().
*
* @param[in] vpe vpe instance returned by vpe_initialize()
* @param[in] param build params
* @param[out] req memory required for the command buffer and
embedded data if return VPE_OK.
caller has to alloc them and provide it to build_vpbilts API.
* @return VPE_OK if supported
*/
enum vpe_status vpe_check_support(
struct vpe *vpe, const struct vpe_build_param *param, struct vpe_bufs_req *req);
/************************************
* Command building functions
************************************/
/**
* Build the command descriptors for No-Op operation
* @param[in] vpe vpe instance created by vpe_create()
* @param[in] num_dwords number of noops
* @param[in,out] ppcmd_space in: dword aligned command buffer start address
* out: dword aligned next good write address
* @return status
*/
enum vpe_status vpe_build_noops(struct vpe *vpe, uint32_t num_dwords, uint32_t **ppcmd_space);
/**
* build the command descriptors for the given param.
* caller must call vpe_check_support() before this function,
* unexpected result otherwise.
*
* @param[in] vpe vpe instance created by vpe_create()
* @param[in] param vpe build params
* @param[in,out] bufs [in] memory allocated for the command buffer, embedded buffer and 3dlut.
* If size is 0, it reports the required size for this checked
* operation. [out] the next write address and the filled sizes.
* @return status
*/
enum vpe_status vpe_build_commands(
struct vpe *vpe, const struct vpe_build_param *param, struct vpe_build_bufs *bufs);
#ifdef __cplusplus
}
#endif
+146
View File
@@ -0,0 +1,146 @@
# Copyright 2022 Advanced Micro Devices, Inc.
# All Rights Reserved.
# 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
# AUTHORS OR COPYRIGHT HOLDERS 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.
c_args_vpe = cc.get_supported_arguments([
'-Wall',
'-Wextra',
'-Wno-unused',
'-Wno-unused-parameter',
'-Wno-unused-command-line-argument',
'-Wno-ignored-qualifiers',
'-Wno-missing-field-initializers',
'-Wno-self-assign',
'-Wno-implicit-fallthrough',
'-Werror=comment',
'-Werror=missing-braces',
'-Werror=override-init',
'-Werror=enum-conversion',
'-Werror=enum-compare',
'-Werror=maybe-uninitialized',
])
c_args_vpe += [
'-DLITTLEENDIAN_CPU',
'-DVPE_BUILD_1_0',
'-DVPE_BUILD_1_X',
]
vpe_files = files(
'src/core/inc/reg_helper.h',
'src/core/inc/vpe_priv.h',
'src/core/inc/vpe_command.h',
'src/core/inc/color_pwl.h',
'src/core/inc/color_gamut.h',
'src/core/inc/vpe_assert.h',
'src/core/inc/vpec.h',
'src/core/inc/plane_desc_writer.h',
'src/core/inc/color_table.h',
'src/core/inc/hw_shared.h',
'src/core/inc/cdc.h',
'src/core/inc/dpp.h',
'src/core/inc/color_test_values.h',
'src/core/inc/vpe_visual_confirm.h',
'src/core/inc/color_cs.h',
'src/core/inc/diag_reg_helper.h',
'src/core/inc/shaper_builder.h',
'src/core/inc/color_bg.h',
'src/core/inc/transform.h',
'src/core/inc/common.h',
'src/core/inc/color.h',
'src/core/inc/mpc.h',
'src/core/inc/3dlut_builder.h',
'src/core/inc/cmd_builder.h',
'src/core/inc/background.h',
'src/core/inc/color_gamma.h',
'src/core/inc/opp.h',
'src/core/inc/resource.h',
'src/core/inc/vpe_desc_writer.h',
'src/core/inc/config_writer.h',
'src/core/color_gamma.c',
'src/core/color_bg.c',
'src/core/vpe_scl_filters.c',
'src/core/background.c',
'src/core/vpe_visual_confirm.c',
'src/core/mpc.c',
'src/core/config_writer.c',
'src/core/plane_desc_writer.c',
'src/core/color_gamut.c',
'src/core/vpelib.c',
'src/core/vpe_desc_writer.c',
'src/core/3dlut_builder.c',
'src/core/color_test_values.c',
'src/core/resource.c',
'src/core/color_table.c',
'src/core/color.c',
'src/core/color_cs.c',
'src/core/common.c',
'src/core/shaper_builder.c',
'src/utils/inc/custom_fp16.h',
'src/utils/inc/custom_float.h',
'src/utils/inc/fixed31_32.h',
'src/utils/inc/conversion.h',
'src/utils/inc/calc_u64.h',
'src/utils/custom_fp16.c',
'src/utils/custom_float.c',
'src/utils/conversion.c',
'src/utils/fixpt31_32.c',
'src/chip/vpe10/inc/vpe10_background.h',
'src/chip/vpe10/inc/vpe10_cm_common.h',
'src/chip/vpe10/inc/vpe10_vpec.h',
'src/chip/vpe10/inc/vpe10_mpc.h',
'src/chip/vpe10/inc/vpe10_cmd_builder.h',
'src/chip/vpe10/inc/vpe10_opp.h',
'src/chip/vpe10/inc/asic/bringup_vpe_6_1_0_default.h',
'src/chip/vpe10/inc/asic/bringup_vpe_6_1_0_offset.h',
'src/chip/vpe10/inc/asic/bringup_vpe_6_1_0_sh_mask.h',
'src/chip/vpe10/inc/asic/vpe_1_0_offset.h',
'src/chip/vpe10/inc/vpe10_resource.h',
'src/chip/vpe10/inc/vpe10_cdc.h',
'src/chip/vpe10/inc/vpe10_dpp.h',
'src/chip/vpe10/vpe10_cm_common.c',
'src/chip/vpe10/vpe10_dpp.c',
'src/chip/vpe10/vpe10_resource.c',
'src/chip/vpe10/vpe10_mpc.c',
'src/chip/vpe10/vpe10_cmd_builder.c',
'src/chip/vpe10/vpe10_dpp_dscl.c',
'src/chip/vpe10/vpe10_dpp_cm.c',
'src/chip/vpe10/vpe10_opp.c',
'src/chip/vpe10/vpe10_background.c',
'src/chip/vpe10/vpe10_cdc.c',
'src/chip/vpe10/vpe10_vpec.c',
)
inc_amd_vpe = include_directories(
'inc',
'src',
'src/core/inc',
'src/chip',
'src/utils/inc',
'src/chip/vpe10/inc',
)
libvpe = static_library(
'libvpe.a',
vpe_files,
install : false,
c_args : c_args_vpe,
include_directories : inc_amd_vpe
)
@@ -0,0 +1,872 @@
// Headers from LSDp CL1744173
#ifndef _vpe_6_1_0_DEFAULT_HEADER
#define _vpe_6_1_0_DEFAULT_HEADER
// addressBlock: vpe_vpedec
#define regVPEC_DEC_START_DEFAULT 0x00000000
#define regVPEC_UCODE_ADDR_DEFAULT 0x00000000
#define regVPEC_UCODE_DATA_DEFAULT 0x00000000
#define regVPEC_F32_CNTL_DEFAULT 0x08084001
#define regVPEC_MMHUB_CNTL_DEFAULT 0x00000000
#define regVPEC_MMHUB_TRUSTLVL_DEFAULT 0x77777777
#define regVPEC_VPEP_CTRL_DEFAULT 0x00000002
#define regVPEC_CLK_CTRL_DEFAULT 0x00000000
#define regVPEC_PG_CNTL_DEFAULT 0x00000015
#define regVPEC_POWER_CNTL_DEFAULT 0x00000000
#define regVPEC_CNTL_DEFAULT 0x0150c401
#define regVPEC_CNTL1_DEFAULT 0x05001000
#define regVPEC_CNTL2_DEFAULT 0x400400c9
#define regVPEC_GB_ADDR_CONFIG_DEFAULT 0x00000242
#define regVPEC_GB_ADDR_CONFIG_READ_DEFAULT 0x00000242
#define regVPEC_PROCESS_QUANTUM0_DEFAULT 0x00000000
#define regVPEC_PROCESS_QUANTUM1_DEFAULT 0x00000000
#define regVPEC_CONTEXT_SWITCH_THRESHOLD_DEFAULT 0x0000006b
#define regVPEC_GLOBAL_QUANTUM_DEFAULT 0x00000000
#define regVPEC_WATCHDOG_CNTL_DEFAULT 0x00000000
#define regVPEC_ATOMIC_CNTL_DEFAULT 0x00000200
#define regVPEC_UCODE_VERSION_DEFAULT 0x00000000
#define regVPEC_MEMREQ_BURST_CNTL_DEFAULT 0x000006ff
#define regVPEC_TIMESTAMP_CNTL_DEFAULT 0x00000000
#define regVPEC_GLOBAL_TIMESTAMP_LO_DEFAULT 0x00000000
#define regVPEC_GLOBAL_TIMESTAMP_HI_DEFAULT 0x00000000
#define regVPEC_FREEZE_DEFAULT 0x00000000
#define regVPEC_CE_CTRL_DEFAULT 0x00000000
#define regVPEC_RELAX_ORDERING_LUT_DEFAULT 0xc0000806
#define regVPEC_CREDIT_CNTL_DEFAULT 0x00014840
#define regVPEC_SCRATCH_RAM_DATA_DEFAULT 0x00000000
#define regVPEC_SCRATCH_RAM_ADDR_DEFAULT 0x00000000
#define regVPEC_QUEUE_RESET_REQ_DEFAULT 0x00000000
#define regVPEC_PERFCNT_PERFCOUNTER0_CFG_DEFAULT 0x0000ffff
#define regVPEC_PERFCNT_PERFCOUNTER1_CFG_DEFAULT 0x0000ffff
#define regVPEC_PERFCNT_PERFCOUNTER_RSLT_CNTL_DEFAULT 0x04000000
#define regVPEC_PERFCNT_MISC_CNTL_DEFAULT 0x00010000
#define regVPEC_PERFCNT_PERFCOUNTER_LO_DEFAULT 0x00000000
#define regVPEC_PERFCNT_PERFCOUNTER_HI_DEFAULT 0x00000000
#define regVPEC_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPEC_DEBUG_DATA_DEFAULT 0x00000000
#define regVPEC_CRC_CTRL_DEFAULT 0x00000000
#define regVPEC_CRC_DATA_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY0_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY1_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY2_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY3_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY4_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY5_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY6_DEFAULT 0x00000000
#define regVPEC_PUB_DUMMY7_DEFAULT 0x00000000
#define regVPEC_UCODE1_CHECKSUM_DEFAULT 0x00000000
#define regVPEC_VERSION_DEFAULT 0x00000601
#define regVPEC_UCODE_CHECKSUM_DEFAULT 0x00000000
#define regVPEC_CLOCK_GATING_STATUS_DEFAULT 0x00000000
#define regVPEC_RB_RPTR_FETCH_DEFAULT 0x00000000
#define regVPEC_RB_RPTR_FETCH_HI_DEFAULT 0x00000000
#define regVPEC_IB_OFFSET_FETCH_DEFAULT 0x00000000
#define regVPEC_CMDIB_OFFSET_FETCH_DEFAULT 0x00000000
#define regVPEC_ATOMIC_PREOP_LO_DEFAULT 0x00000000
#define regVPEC_ATOMIC_PREOP_HI_DEFAULT 0x00000000
#define regVPEC_CE_BUSY_DEFAULT 0x00000000
#define regVPEC_F32_COUNTER_DEFAULT 0x00000000
#define regVPEC_HOLE_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_HOLE_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_ERROR_LOG_DEFAULT 0x0000000f
#define regVPEC_INT_STATUS_DEFAULT 0x00000000
#define regVPEC_STATUS_DEFAULT 0x46dee557
#define regVPEC_STATUS1_DEFAULT 0x0003ffff
#define regVPEC_STATUS2_DEFAULT 0x00000000
#define regVPEC_STATUS3_DEFAULT 0x03f00000
#define regVPEC_STATUS4_DEFAULT 0x00000001
#define regVPEC_STATUS5_DEFAULT 0x00000000
#define regVPEC_STATUS6_DEFAULT 0x00000000
#define regVPEC_STATUS7_DEFAULT 0x00000000
#define regVPEC_INST_DEFAULT 0x00000000
#define regVPEC_QUEUE_STATUS0_DEFAULT 0x22222222
#define regVPEC_QUEUE_HANG_STATUS_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE0_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE0_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE0_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE0_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE0_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE0_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE0_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE0_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE0_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE0_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE0_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE0_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE1_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE1_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE1_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE1_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE1_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE1_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE1_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE1_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE1_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE1_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE1_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE1_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE2_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE2_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE2_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE2_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE2_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE2_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE2_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE2_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE2_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE2_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE2_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE2_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE3_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE3_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE3_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE3_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE3_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE3_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE3_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE3_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE3_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE3_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE3_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE3_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE4_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE4_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE4_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE4_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE4_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE4_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE4_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE4_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE4_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE4_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE4_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE4_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE5_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE5_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE5_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE5_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE5_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE5_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE5_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE5_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE5_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE5_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE5_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE5_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE6_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE6_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE6_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE6_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE6_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE6_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE6_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE6_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE6_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE6_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE6_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE6_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_CNTL_DEFAULT 0x00040800
#define regVPEC_QUEUE7_SCHEDULE_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_BASE_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_RPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_WPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_WPTR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_RPTR_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_RPTR_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_AQL_CNTL_DEFAULT 0x00004000
#define regVPEC_QUEUE7_MINOR_PTR_UPDATE_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CD_INFO_DEFAULT 0x00000000
#define regVPEC_QUEUE7_RB_PREEMPT_DEFAULT 0x00000000
#define regVPEC_QUEUE7_SKIP_CNTL_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DOORBELL_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DOORBELL_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DUMMY0_DEFAULT 0x0000000f
#define regVPEC_QUEUE7_DUMMY1_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DUMMY2_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DUMMY3_DEFAULT 0x00000000
#define regVPEC_QUEUE7_DUMMY4_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_CNTL_DEFAULT 0x00000100
#define regVPEC_QUEUE7_IB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CMDIB_CNTL_DEFAULT 0x00000101
#define regVPEC_QUEUE7_CMDIB_RPTR_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CMDIB_OFFSET_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CMDIB_BASE_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CMDIB_BASE_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CMDIB_SIZE_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CSA_ADDR_LO_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CSA_ADDR_HI_DEFAULT 0x00000000
#define regVPEC_QUEUE7_CONTEXT_STATUS_DEFAULT 0x00000804
#define regVPEC_QUEUE7_DOORBELL_LOG_DEFAULT 0x00000000
#define regVPEC_QUEUE7_IB_SUB_REMAIN_DEFAULT 0x00000000
#define regVPEC_QUEUE7_PREEMPT_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpdpp0_dispdec_vpcnvc_cfg_dispdec
#define regVPCNVC_SURFACE_PIXEL_FORMAT_DEFAULT 0x00000008
#define regVPCNVC_FORMAT_CONTROL_DEFAULT 0x00000000
#define regVPCNVC_FCNV_FP_BIAS_R_DEFAULT 0x00000000
#define regVPCNVC_FCNV_FP_BIAS_G_DEFAULT 0x00000000
#define regVPCNVC_FCNV_FP_BIAS_B_DEFAULT 0x00000000
#define regVPCNVC_FCNV_FP_SCALE_R_DEFAULT 0x0001f000
#define regVPCNVC_FCNV_FP_SCALE_G_DEFAULT 0x0001f000
#define regVPCNVC_FCNV_FP_SCALE_B_DEFAULT 0x0001f000
#define regVPCNVC_COLOR_KEYER_CONTROL_DEFAULT 0x00000000
#define regVPCNVC_COLOR_KEYER_ALPHA_DEFAULT 0x00000000
#define regVPCNVC_COLOR_KEYER_RED_DEFAULT 0x00000000
#define regVPCNVC_COLOR_KEYER_GREEN_DEFAULT 0x00000000
#define regVPCNVC_COLOR_KEYER_BLUE_DEFAULT 0x00000000
#define regVPCNVC_ALPHA_2BIT_LUT_DEFAULT 0xffaa5500
#define regVPCNVC_PRE_DEALPHA_DEFAULT 0x00000000
#define regVPCNVC_PRE_CSC_MODE_DEFAULT 0x00000000
#define regVPCNVC_PRE_CSC_C11_C12_DEFAULT 0x00002000
#define regVPCNVC_PRE_CSC_C13_C14_DEFAULT 0x00000000
#define regVPCNVC_PRE_CSC_C21_C22_DEFAULT 0x20000000
#define regVPCNVC_PRE_CSC_C23_C24_DEFAULT 0x00000000
#define regVPCNVC_PRE_CSC_C31_C32_DEFAULT 0x00000000
#define regVPCNVC_PRE_CSC_C33_C34_DEFAULT 0x00002000
#define regVPCNVC_COEF_FORMAT_DEFAULT 0x00000000
#define regVPCNVC_PRE_DEGAM_DEFAULT 0x00000000
#define regVPCNVC_PRE_REALPHA_DEFAULT 0x00000000
#define regVPCNVC_CFG_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPCNVC_CFG_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpdpp0_dispdec_vpdscl_dispdec
#define regVPDSCL_COEF_RAM_TAP_SELECT_DEFAULT 0x00000000
#define regVPDSCL_COEF_RAM_TAP_DATA_DEFAULT 0x00000000
#define regVPDSCL_MODE_DEFAULT 0x00000000
#define regVPDSCL_TAP_CONTROL_DEFAULT 0x00000000
#define regVPDSCL_CONTROL_DEFAULT 0x00000000
#define regVPDSCL_2TAP_CONTROL_DEFAULT 0x01000100
#define regVPDSCL_MANUAL_REPLICATE_CONTROL_DEFAULT 0x00000000
#define regVPDSCL_HORZ_FILTER_SCALE_RATIO_DEFAULT 0x00000000
#define regVPDSCL_HORZ_FILTER_INIT_DEFAULT 0x01000000
#define regVPDSCL_HORZ_FILTER_SCALE_RATIO_C_DEFAULT 0x00000000
#define regVPDSCL_HORZ_FILTER_INIT_C_DEFAULT 0x01000000
#define regVPDSCL_VERT_FILTER_SCALE_RATIO_DEFAULT 0x00000000
#define regVPDSCL_VERT_FILTER_INIT_DEFAULT 0x01000000
#define regVPDSCL_VERT_FILTER_INIT_BOT_DEFAULT 0x01000000
#define regVPDSCL_VERT_FILTER_SCALE_RATIO_C_DEFAULT 0x00000000
#define regVPDSCL_VERT_FILTER_INIT_C_DEFAULT 0x01000000
#define regVPDSCL_VERT_FILTER_INIT_BOT_C_DEFAULT 0x01000000
#define regVPDSCL_BLACK_COLOR_DEFAULT 0x3c000000
#define regVPDSCL_UPDATE_DEFAULT 0x00000000
#define regVPDSCL_AUTOCAL_DEFAULT 0x00000000
#define regVPDSCL_EXT_OVERSCAN_LEFT_RIGHT_DEFAULT 0x00000000
#define regVPDSCL_EXT_OVERSCAN_TOP_BOTTOM_DEFAULT 0x00000000
#define regVPOTG_H_BLANK_DEFAULT 0x00000000
#define regVPOTG_V_BLANK_DEFAULT 0x00000000
#define regVPDSCL_RECOUT_START_DEFAULT 0x00000000
#define regVPDSCL_RECOUT_SIZE_DEFAULT 0x00000000
#define regVPMPC_SIZE_DEFAULT 0x00000000
#define regVPLB_DATA_FORMAT_DEFAULT 0x00000000
#define regVPLB_MEMORY_CTRL_DEFAULT 0x00003f00
#define regVPLB_V_COUNTER_DEFAULT 0x00000000
#define regVPDSCL_MEM_PWR_CTRL_DEFAULT 0x00000000
#define regVPDSCL_MEM_PWR_STATUS_DEFAULT 0x00000000
#define regVPDSCL_DEBUG_DEFAULT 0x00000000
#define regVPDSCL_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPDSCL_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpdpp0_dispdec_vpcm_dispdec
#define regVPCM_CONTROL_DEFAULT 0x00000000
#define regVPCM_POST_CSC_CONTROL_DEFAULT 0x00000000
#define regVPCM_POST_CSC_C11_C12_DEFAULT 0x00002000
#define regVPCM_POST_CSC_C13_C14_DEFAULT 0x00000000
#define regVPCM_POST_CSC_C21_C22_DEFAULT 0x20000000
#define regVPCM_POST_CSC_C23_C24_DEFAULT 0x00000000
#define regVPCM_POST_CSC_C31_C32_DEFAULT 0x00000000
#define regVPCM_POST_CSC_C33_C34_DEFAULT 0x00002000
#define regVPCM_GAMUT_REMAP_CONTROL_DEFAULT 0x00000000
#define regVPCM_GAMUT_REMAP_C11_C12_DEFAULT 0x00002000
#define regVPCM_GAMUT_REMAP_C13_C14_DEFAULT 0x00000000
#define regVPCM_GAMUT_REMAP_C21_C22_DEFAULT 0x20000000
#define regVPCM_GAMUT_REMAP_C23_C24_DEFAULT 0x00000000
#define regVPCM_GAMUT_REMAP_C31_C32_DEFAULT 0x00000000
#define regVPCM_GAMUT_REMAP_C33_C34_DEFAULT 0x00002000
#define regVPCM_BIAS_CR_R_DEFAULT 0x00000000
#define regVPCM_BIAS_Y_G_CB_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_CONTROL_DEFAULT 0x00000000
#define regVPCM_GAMCOR_LUT_INDEX_DEFAULT 0x00000000
#define regVPCM_GAMCOR_LUT_DATA_DEFAULT 0x00000000
#define regVPCM_GAMCOR_LUT_CONTROL_DEFAULT 0x00000007
#define regVPCM_GAMCOR_RAMA_START_CNTL_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_CNTL_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_CNTL_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_SLOPE_CNTL_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_SLOPE_CNTL_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_SLOPE_CNTL_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_BASE_CNTL_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_BASE_CNTL_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_START_BASE_CNTL_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL1_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL2_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL1_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL2_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL1_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_END_CNTL2_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_OFFSET_B_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_OFFSET_G_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_OFFSET_R_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_0_1_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_2_3_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_4_5_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_6_7_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_8_9_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_10_11_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_12_13_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_14_15_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_16_17_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_18_19_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_20_21_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_22_23_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_24_25_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_26_27_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_28_29_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_30_31_DEFAULT 0x00000000
#define regVPCM_GAMCOR_RAMA_REGION_32_33_DEFAULT 0x00000000
#define regVPCM_HDR_MULT_COEF_DEFAULT 0x0001f000
#define regVPCM_MEM_PWR_CTRL_DEFAULT 0x00000000
#define regVPCM_MEM_PWR_STATUS_DEFAULT 0x00000000
#define regVPCM_DEALPHA_DEFAULT 0x00000000
#define regVPCM_COEF_FORMAT_DEFAULT 0x00000000
#define regVPCM_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPCM_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpdpp0_dispdec_vpdpp_top_dispdec
#define regVPDPP_CONTROL_DEFAULT 0x70000000
#define regVPDPP_SOFT_RESET_DEFAULT 0x00000000
#define regVPDPP_CRC_VAL_R_G_DEFAULT 0x00000000
#define regVPDPP_CRC_VAL_B_A_DEFAULT 0x00000000
#define regVPDPP_CRC_CTRL_DEFAULT 0x00000000
#define regVPHOST_READ_CONTROL_DEFAULT 0x00000000
#define regVPDPP_DEBUG_SEL_DEFAULT 0x00000000
#define regVPDPP_DEBUG_SPARE_DEFAULT 0x00000000
#define regVPDPP_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPDPP_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpmpc_vpmpcc0_dispdec
#define regVPMPCC_TOP_SEL_DEFAULT 0x0000000f
#define regVPMPCC_BOT_SEL_DEFAULT 0x0000000f
#define regVPMPCC_VPOPP_ID_DEFAULT 0x0000000f
#define regVPMPCC_CONTROL_DEFAULT 0xffff0461
#define regVPMPCC_TOP_GAIN_DEFAULT 0x0001f000
#define regVPMPCC_BOT_GAIN_INSIDE_DEFAULT 0x0001f000
#define regVPMPCC_BOT_GAIN_OUTSIDE_DEFAULT 0x0001f000
#define regVPMPCC_MOVABLE_CM_LOCATION_CONTROL_DEFAULT 0x00000001
#define regVPMPCC_BG_R_CR_DEFAULT 0x00000000
#define regVPMPCC_BG_G_Y_DEFAULT 0x00000000
#define regVPMPCC_BG_B_CB_DEFAULT 0x00000000
#define regVPMPCC_MEM_PWR_CTRL_DEFAULT 0x00000010
#define regVPMPCC_STATUS_DEFAULT 0x00000000
#define regVPMPCC_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPMPCC_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpmpc_vpmpc_cfg_dispdec
#define regVPMPC_CLOCK_CONTROL_DEFAULT 0x00000000
#define regVPMPC_SOFT_RESET_DEFAULT 0x00000000
#define regVPMPC_CRC_CTRL_DEFAULT 0x00000000
#define regVPMPC_CRC_SEL_CONTROL_DEFAULT 0x00000000
#define regVPMPC_CRC_RESULT_AR_DEFAULT 0x00000000
#define regVPMPC_CRC_RESULT_GB_DEFAULT 0x00000000
#define regVPMPC_CRC_RESULT_C_DEFAULT 0x00000000
#define regVPMPC_DEBUG_CONTROL_DEFAULT 0x0000ff00
#define regVPMPCC_DEBUG_DATA_SELECT_DEFAULT 0x3f2f1f0f
#define regVPMPC_BYPASS_BG_AR_DEFAULT 0x00000000
#define regVPMPC_BYPASS_BG_GB_DEFAULT 0x00000000
#define regVPMPC_HOST_READ_CONTROL_DEFAULT 0x00000000
#define regVPMPC_PENDING_STATUS_MISC_DEFAULT 0x00000000
#define regVPMPC_CFG_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPMPC_CFG_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpmpc_vpmpcc_ogam0_dispdec
#define regVPMPCC_OGAM_CONTROL_DEFAULT 0x00000000
#define regVPMPCC_OGAM_LUT_INDEX_DEFAULT 0x00000000
#define regVPMPCC_OGAM_LUT_DATA_DEFAULT 0x00000000
#define regVPMPCC_OGAM_LUT_CONTROL_DEFAULT 0x00000007
#define regVPMPCC_OGAM_RAMA_START_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_SLOPE_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_SLOPE_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_SLOPE_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_BASE_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_BASE_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_START_BASE_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL1_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL2_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL1_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL2_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL1_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_END_CNTL2_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_OFFSET_B_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_OFFSET_G_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_OFFSET_R_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_0_1_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_2_3_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_4_5_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_6_7_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_8_9_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_10_11_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_12_13_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_14_15_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_16_17_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_18_19_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_20_21_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_22_23_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_24_25_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_26_27_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_28_29_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_30_31_DEFAULT 0x00000000
#define regVPMPCC_OGAM_RAMA_REGION_32_33_DEFAULT 0x00000000
#define regVPMPCC_GAMUT_REMAP_COEF_FORMAT_DEFAULT 0x00000000
#define regVPMPCC_GAMUT_REMAP_MODE_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C11_C12_A_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C13_C14_A_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C21_C22_A_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C23_C24_A_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C31_C32_A_DEFAULT 0x00000000
#define regVPMPC_GAMUT_REMAP_C33_C34_A_DEFAULT 0x00000000
#define regVPMPCC_OGAM_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPMPCC_OGAM_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpmpc_vpmpcc_mcm0_dispdec
#define regVPMPCC_MCM_SHAPER_CONTROL_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_OFFSET_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_OFFSET_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_OFFSET_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_SCALE_R_DEFAULT 0x00007000
#define regVPMPCC_MCM_SHAPER_SCALE_G_B_DEFAULT 0x70007000
#define regVPMPCC_MCM_SHAPER_LUT_INDEX_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_LUT_DATA_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_LUT_WRITE_EN_MASK_DEFAULT 0x00000007
#define regVPMPCC_MCM_SHAPER_RAMA_START_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_START_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_START_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_END_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_END_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_END_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_0_1_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_2_3_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_4_5_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_6_7_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_8_9_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_10_11_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_12_13_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_14_15_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_16_17_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_18_19_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_20_21_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_22_23_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_24_25_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_26_27_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_28_29_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_30_31_DEFAULT 0x00000000
#define regVPMPCC_MCM_SHAPER_RAMA_REGION_32_33_DEFAULT 0x00000000
#define regVPMPCC_MCM_3DLUT_MODE_DEFAULT 0x00000000
#define regVPMPCC_MCM_3DLUT_INDEX_DEFAULT 0x00000000
#define regVPMPCC_MCM_3DLUT_DATA_DEFAULT 0x00000000
#define regVPMPCC_MCM_3DLUT_DATA_30BIT_DEFAULT 0x00000000
#define regVPMPCC_MCM_3DLUT_READ_WRITE_CONTROL_DEFAULT 0x0000000f
#define regVPMPCC_MCM_3DLUT_OUT_NORM_FACTOR_DEFAULT 0x00008008
#define regVPMPCC_MCM_3DLUT_OUT_OFFSET_R_DEFAULT 0x3c000000
#define regVPMPCC_MCM_3DLUT_OUT_OFFSET_G_DEFAULT 0x3c000000
#define regVPMPCC_MCM_3DLUT_OUT_OFFSET_B_DEFAULT 0x3c000000
#define regVPMPCC_MCM_1DLUT_CONTROL_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_LUT_INDEX_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_LUT_DATA_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_LUT_CONTROL_DEFAULT 0x00000007
#define regVPMPCC_MCM_1DLUT_RAMA_START_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_BASE_CNTL_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_BASE_CNTL_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_START_BASE_CNTL_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL1_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL2_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL1_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL2_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL1_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_END_CNTL2_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_OFFSET_B_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_OFFSET_G_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_OFFSET_R_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_0_1_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_2_3_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_4_5_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_6_7_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_8_9_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_10_11_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_12_13_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_14_15_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_16_17_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_18_19_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_20_21_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_22_23_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_24_25_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_26_27_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_28_29_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_30_31_DEFAULT 0x00000000
#define regVPMPCC_MCM_1DLUT_RAMA_REGION_32_33_DEFAULT 0x00000000
#define regVPMPCC_MCM_MEM_PWR_CTRL_DEFAULT 0x00101010
#define regVPMPCC_MCM_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPMPCC_MCM_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpmpc_vpmpc_ocsc_dispdec
#define regVPMPC_OUT0_MUX_DEFAULT 0x0000000f
#define regVPMPC_OUT0_FLOAT_CONTROL_DEFAULT 0x00000000
#define regVPMPC_OUT0_DENORM_CONTROL_DEFAULT 0x00fff000
#define regVPMPC_OUT0_DENORM_CLAMP_G_Y_DEFAULT 0x00fff000
#define regVPMPC_OUT0_DENORM_CLAMP_B_CB_DEFAULT 0x00fff000
#define regVPMPC_OUT_CSC_COEF_FORMAT_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_MODE_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C11_C12_A_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C13_C14_A_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C21_C22_A_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C23_C24_A_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C31_C32_A_DEFAULT 0x00000000
#define regVPMPC_OUT0_CSC_C33_C34_A_DEFAULT 0x00000000
#define regVPMPC_OCSC_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPMPC_OCSC_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpopp_vpfmt0_dispdec
#define regVPFMT_CLAMP_COMPONENT_R_DEFAULT 0x00000000
#define regVPFMT_CLAMP_COMPONENT_G_DEFAULT 0x00000000
#define regVPFMT_CLAMP_COMPONENT_B_DEFAULT 0x00000000
#define regVPFMT_DYNAMIC_EXP_CNTL_DEFAULT 0x00000000
#define regVPFMT_CONTROL_DEFAULT 0x00000000
#define regVPFMT_BIT_DEPTH_CONTROL_DEFAULT 0x00000000
#define regVPFMT_DITHER_RAND_R_SEED_DEFAULT 0x00000000
#define regVPFMT_DITHER_RAND_G_SEED_DEFAULT 0x00000099
#define regVPFMT_DITHER_RAND_B_SEED_DEFAULT 0x000000dd
#define regVPFMT_CLAMP_CNTL_DEFAULT 0x00000000
#define regVPFMT_DEBUG_CNTL_DEFAULT 0x00000000
#define regVPFMT_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPFMT_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpopp_vpopp_pipe0_dispdec
#define regVPOPP_PIPE_CONTROL_DEFAULT 0x00000000
#define regVPOPP_PIPE_SPARE_DEBUG_DEFAULT 0x00000000
#define regVPOPP_PIPE_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPOPP_PIPE_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpopp_vpopp_pipe_crc0_dispdec
#define regVPOPP_PIPE_CRC_CONTROL_DEFAULT 0x00000000
#define regVPOPP_PIPE_CRC_MASK_DEFAULT 0x0000ffff
#define regVPOPP_PIPE_CRC_RESULT0_DEFAULT 0x00000000
#define regVPOPP_PIPE_CRC_RESULT1_DEFAULT 0x00000000
#define regVPOPP_PIPE_CRC_RESULT2_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpopp_vpopp_top_dispdec
#define regVPOPP_TOP_CLK_CONTROL_DEFAULT 0x00000000
#define regVPOPP_DEBUG_CONTROL_DEFAULT 0x00000000
#define regVPOPP_TOP_SPARE_DEBUG_DEFAULT 0x00000000
#define regVPOPP_TOP_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPOPP_TOP_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpcdc_cdc_dispdec
#define regVPEP_MGCG_CNTL_DEFAULT 0x00000000
#define regVPCDC_SOFT_RESET_DEFAULT 0x00000000
#define regVPCDC_FE0_SURFACE_CONFIG_DEFAULT 0x00000000
#define regVPCDC_FE0_CROSSBAR_CONFIG_DEFAULT 0x00000000
#define regVPCDC_FE0_VIEWPORT_START_CONFIG_DEFAULT 0x00000000
#define regVPCDC_FE0_VIEWPORT_DIMENSION_CONFIG_DEFAULT 0x00000000
#define regVPCDC_FE0_VIEWPORT_START_C_CONFIG_DEFAULT 0x00000000
#define regVPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG_DEFAULT 0x00000000
#define regVPCDC_BE0_P2B_CONFIG_DEFAULT 0x00000036
#define regVPCDC_BE0_GLOBAL_SYNC_CONFIG_DEFAULT 0x00000000
#define regVPCDC_GLOBAL_SYNC_TRIGGER_DEFAULT 0x00000000
#define regVPCDC_VREADY_STATUS_DEFAULT 0x00000000
#define regVPEP_MEM_GLOBAL_PWR_REQ_CNTL_DEFAULT 0x00000000
#define regVPFE_MEM_PWR_CNTL_DEFAULT 0x00000000
#define regVPBE_MEM_PWR_CNTL_DEFAULT 0x00000000
#define regVPEP_RBBMIF_TIMEOUT_DEFAULT 0x01f00100
#define regVPEP_RBBMIF_STATUS_DEFAULT 0x00000000
#define regVPEP_RBBMIF_TIMEOUT_DIS_DEFAULT 0x00000000
#define regVPCDC_DEBUG_CTRL0_DEFAULT 0x00000000
#define regVPCDC_DEBUG_CTRL1_DEFAULT 0x00000000
#define regVPCDC_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regVPCDC_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: vpe_vpep_vpcdc_vpcdc_dcperfmon_dc_perfmon_dispdec
#define regPERFCOUNTER_CNTL_DEFAULT 0x00000000
#define regPERFCOUNTER_CNTL2_DEFAULT 0x00000000
#define regPERFCOUNTER_STATE_DEFAULT 0x00000000
#define regPERFMON_CNTL_DEFAULT 0x00000100
#define regPERFMON_CNTL2_DEFAULT 0x00000000
#define regPERFMON_CVALUE_INT_MISC_DEFAULT 0x00000000
#define regPERFMON_CVALUE_LOW_DEFAULT 0x00000000
#define regPERFMON_HI_DEFAULT 0x00000000
#define regPERFMON_LOW_DEFAULT 0x00000000
#define regPERFMON_TEST_DEBUG_INDEX_DEFAULT 0x00000000
#define regPERFMON_TEST_DEBUG_DATA_DEFAULT 0x00000000
// addressBlock: dc_perfmon_dc_perfmondebugind
#define ixPERFMON_DEBUG_ID_DEFAULT 0x00000000
#define ixPERFMON_DEBUG01_DEFAULT 0x00000000
#define ixPERFMON_DEBUG02_DEFAULT 0x00000000
#define ixPERFMON_DEBUG03_DEFAULT 0x00000000
#define ixPERFMON_DEBUG04_DEFAULT 0x00000000
#define ixPERFMON_DEBUG05_DEFAULT 0x00000000
#define ixPERFMON_DEBUG06_DEFAULT 0x00000000
#define ixPERFMON_DEBUG07_DEFAULT 0x00000000
#define ixPERFMON_DEBUG08_DEFAULT 0x00000000
#define ixPERFMON_DEBUG09_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0A_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0B_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0C_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0D_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0E_DEFAULT 0x00000000
#define ixPERFMON_DEBUG0F_DEFAULT 0x00000000
#define ixPERFMON_DEBUG10_DEFAULT 0x00000000
#define ixPERFMON_DEBUG11_DEFAULT 0x00000000
#define ixPERFMON_DEBUG12_DEFAULT 0x00000000
// addressBlock: vpfmt0_vpfmtdebugind
#define ixVPFMT_DEBUG_ID_DEFAULT 0x00000000
#define ixVPFMT_DEBUG0_DEFAULT 0x00000000
#define ixVPFMT_DEBUG1_DEFAULT 0x00000000
#define ixVPFMT_DEBUG2_DEFAULT 0x00000000
#define ixVPFMT_DEBUG3_DEFAULT 0x00000000
#define ixVPFMT_DEBUG4_DEFAULT 0x00000000
#define ixVPFMT_DEBUG5_DEFAULT 0x00000000
#define ixVPFMT_DEBUG6_DEFAULT 0x00000000
#define ixVPFMT_DEBUG7_DEFAULT 0x00000000
#define ixVPFMT_DEBUG8_DEFAULT 0x00000000
#define ixVPFMT_DEBUG9_DEFAULT 0x00000000
#define ixVPFMT_DEBUG10_DEFAULT 0x00000000
#define ixVPFMT_DEBUG11_DEFAULT 0x00000000
// addressBlock: vpopp_pipe0_vpopppipedebugind
#define ixVPOPP_PIPE_DEBUG_ID_DEFAULT 0x00000000
#define ixVPOPP_PIPE_DEBUG_0_DEFAULT 0x00000000
#define ixVPOPP_PIPE_DEBUG_1_DEFAULT 0x00000000
#define ixVPOPP_PIPE_DEBUG_2_DEFAULT 0x00000000
// addressBlock: vpopp_top_vpopp_topdebugind
#define ixVPOPP_TOP_DEBUG_ID_DEFAULT 0x00000000
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,111 @@
#ifndef VPE_1_0_OFFSET_H
#define VPE_1_0_OFFSET_H
#define MAX_INSTANCE 9
#define MAX_SEGMENT 7
struct IP_BASE_INSTANCE
{
unsigned int segment[MAX_SEGMENT];
};
struct IP_BASE
{
struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
};
struct IP_SIZE
{
unsigned int segment[1][MAX_SEGMENT];
};
static const struct IP_BASE VPE_BASE = { { { { 0x00011800, 0x02456C00, 0x3C56C000, 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 const struct IP_SIZE VPE_SIZE = { { { 0x00001400, 0x00000400, 0x00004000, 0, 0, 0, 0 } } };
#define VPE_BASE__INST0_SEG0 0x00011800
#define VPE_BASE__INST0_SEG1 0x02456C00
#define VPE_BASE__INST0_SEG2 0x3C56C000
#define VPE_BASE__INST0_SEG3 0
#define VPE_BASE__INST0_SEG4 0
#define VPE_BASE__INST0_SEG5 0
#define VPE_BASE__INST0_SEG6 0
#define VPE_BASE__INST1_SEG0 0
#define VPE_BASE__INST1_SEG1 0
#define VPE_BASE__INST1_SEG2 0
#define VPE_BASE__INST1_SEG3 0
#define VPE_BASE__INST1_SEG4 0
#define VPE_BASE__INST1_SEG5 0
#define VPE_BASE__INST1_SEG6 0
#define VPE_BASE__INST2_SEG0 0
#define VPE_BASE__INST2_SEG1 0
#define VPE_BASE__INST2_SEG2 0
#define VPE_BASE__INST2_SEG3 0
#define VPE_BASE__INST2_SEG4 0
#define VPE_BASE__INST2_SEG5 0
#define VPE_BASE__INST2_SEG6 0
#define VPE_BASE__INST3_SEG0 0
#define VPE_BASE__INST3_SEG1 0
#define VPE_BASE__INST3_SEG2 0
#define VPE_BASE__INST3_SEG3 0
#define VPE_BASE__INST3_SEG4 0
#define VPE_BASE__INST3_SEG5 0
#define VPE_BASE__INST3_SEG6 0
#define VPE_BASE__INST4_SEG0 0
#define VPE_BASE__INST4_SEG1 0
#define VPE_BASE__INST4_SEG2 0
#define VPE_BASE__INST4_SEG3 0
#define VPE_BASE__INST4_SEG4 0
#define VPE_BASE__INST4_SEG5 0
#define VPE_BASE__INST4_SEG6 0
#define VPE_BASE__INST5_SEG0 0
#define VPE_BASE__INST5_SEG1 0
#define VPE_BASE__INST5_SEG2 0
#define VPE_BASE__INST5_SEG3 0
#define VPE_BASE__INST5_SEG4 0
#define VPE_BASE__INST5_SEG5 0
#define VPE_BASE__INST5_SEG6 0
#define VPE_BASE__INST6_SEG0 0
#define VPE_BASE__INST6_SEG1 0
#define VPE_BASE__INST6_SEG2 0
#define VPE_BASE__INST6_SEG3 0
#define VPE_BASE__INST6_SEG4 0
#define VPE_BASE__INST6_SEG5 0
#define VPE_BASE__INST6_SEG6 0
#define VPE_BASE__INST7_SEG0 0
#define VPE_BASE__INST7_SEG1 0
#define VPE_BASE__INST7_SEG2 0
#define VPE_BASE__INST7_SEG3 0
#define VPE_BASE__INST7_SEG4 0
#define VPE_BASE__INST7_SEG5 0
#define VPE_BASE__INST7_SEG6 0
#define VPE_BASE__INST8_SEG0 0
#define VPE_BASE__INST8_SEG1 0
#define VPE_BASE__INST8_SEG2 0
#define VPE_BASE__INST8_SEG3 0
#define VPE_BASE__INST8_SEG4 0
#define VPE_BASE__INST8_SEG5 0
#define VPE_BASE__INST8_SEG6 0
#endif
@@ -0,0 +1,37 @@
/* Copyright 2023 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
bool vpe10_split_bg_gap(struct vpe_rect *gaps, const struct vpe_rect *target_rect,
uint32_t max_width, uint16_t max_gaps, uint16_t *num_gaps, uint16_t num_multiple);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,201 @@
/* 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 "cdc.h"
#include "reg_helper.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VPE10_CDC_VUPDATE_OFFSET_DEFAULT (21)
#define VPE10_CDC_VUPDATE_WIDTH_DEFAULT (60)
#define VPE10_CDC_VREADY_OFFSET_DEFAULT (150)
/* macros for filing variable or field list
SRI, SFRB should be defined in the resource file */
#define CDC_REG_LIST_VPE10(id) \
SRIDFVL(VPEP_MGCG_CNTL, CDC, id), SRIDFVL(VPCDC_SOFT_RESET, CDC, id), \
SRIDFVL(VPCDC_FE0_SURFACE_CONFIG, CDC, id), SRIDFVL(VPCDC_FE0_CROSSBAR_CONFIG, CDC, id), \
SRIDFVL(VPCDC_FE0_VIEWPORT_START_CONFIG, CDC, id), \
SRIDFVL(VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG, CDC, id), \
SRIDFVL(VPCDC_FE0_VIEWPORT_START_C_CONFIG, CDC, id), \
SRIDFVL(VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG, CDC, id), \
SRIDFVL(VPCDC_BE0_P2B_CONFIG, CDC, id), SRIDFVL(VPCDC_BE0_GLOBAL_SYNC_CONFIG, CDC, id), \
SRIDFVL(VPCDC_GLOBAL_SYNC_TRIGGER, CDC, id), \
SRIDFVL(VPEP_MEM_GLOBAL_PWR_REQ_CNTL, CDC, id), SRIDFVL(VPFE_MEM_PWR_CNTL, CDC, id), \
SRIDFVL(VPBE_MEM_PWR_CNTL, CDC, id)
#define CDC_FLIED_LIST_VPE10(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(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(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(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, VPFE_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_MODE, VPFE_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_STATE, VPFE_MEM_PWR_CNTL, post_fix), \
SFRB(VPFE0_MEM_PWR_DIS, VPFE_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_FORCE, VPBE_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_MODE, VPBE_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_STATE, VPBE_MEM_PWR_CNTL, post_fix), \
SFRB(VPBE0_MEM_PWR_DIS, VPBE_MEM_PWR_CNTL, post_fix)
/* define all structure register variables below */
#define CDC_REG_VARIABLE_LIST_VPE10 \
reg_id_val VPEP_MGCG_CNTL; \
reg_id_val VPCDC_SOFT_RESET; \
reg_id_val VPCDC_FE0_SURFACE_CONFIG; \
reg_id_val VPCDC_FE0_CROSSBAR_CONFIG; \
reg_id_val VPCDC_FE0_VIEWPORT_START_CONFIG; \
reg_id_val VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG; \
reg_id_val VPCDC_FE0_VIEWPORT_START_C_CONFIG; \
reg_id_val VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG; \
reg_id_val VPCDC_BE0_P2B_CONFIG; \
reg_id_val VPCDC_BE0_GLOBAL_SYNC_CONFIG; \
reg_id_val VPCDC_GLOBAL_SYNC_TRIGGER; \
reg_id_val VPEP_MEM_GLOBAL_PWR_REQ_CNTL; \
reg_id_val VPFE_MEM_PWR_CNTL; \
reg_id_val VPBE_MEM_PWR_CNTL;
#define CDC_FIELD_VARIABLE_LIST_VPE10(type) \
type VPDPP0_CLK_GATE_DIS; \
type VPMPC_CLK_GATE_DIS; \
type VPOPP_CLK_GATE_DIS; \
type VPCDC_SOCCLK_G_GATE_DIS; \
type VPCDC_SOCCLK_R_GATE_DIS; \
type VPCDC_VPECLK_G_GATE_DIS; \
type VPCDC_VPECLK_R_GATE_DIS; \
type VPCDC_SOCCLK_SOFT_RESET; \
type VPCDC_VPECLK_SOFT_RESET; \
type SURFACE_PIXEL_FORMAT_FE0; \
type ROTATION_ANGLE_FE0; \
type H_MIRROR_EN_FE0; \
type PIX_SURFACE_LINEAR_FE0; \
type CROSSBAR_SRC_ALPHA_FE0; \
type CROSSBAR_SRC_Y_G_FE0; \
type CROSSBAR_SRC_CB_B_FE0; \
type CROSSBAR_SRC_CR_R_FE0; \
type VIEWPORT_X_START_FE0; \
type VIEWPORT_Y_START_FE0; \
type VIEWPORT_WIDTH_FE0; \
type VIEWPORT_HEIGHT_FE0; \
type VIEWPORT_X_START_C_FE0; \
type VIEWPORT_Y_START_C_FE0; \
type VIEWPORT_WIDTH_C_FE0; \
type VIEWPORT_HEIGHT_C_FE0; \
type VPCDC_BE0_P2B_XBAR_SEL0; \
type VPCDC_BE0_P2B_XBAR_SEL1; \
type VPCDC_BE0_P2B_XBAR_SEL2; \
type VPCDC_BE0_P2B_XBAR_SEL3; \
type VPCDC_BE0_P2B_FORMAT_SEL; \
type BE0_VUPDATE_OFFSET; \
type BE0_VUPDATE_WIDTH; \
type BE0_VREADY_OFFSET; \
type VPBE_GS_TRIG; \
type VPFE_VR_STATUS; \
type MEM_GLOBAL_PWR_REQ_DIS; \
type VPFE0_MEM_PWR_FORCE; \
type VPFE0_MEM_PWR_MODE; \
type VPFE0_MEM_PWR_STATE; \
type VPFE0_MEM_PWR_DIS; \
type VPBE0_MEM_PWR_FORCE; \
type VPBE0_MEM_PWR_MODE; \
type VPBE0_MEM_PWR_STATE; \
type VPBE0_MEM_PWR_DIS;
struct vpe10_cdc_registers {
CDC_REG_VARIABLE_LIST_VPE10
};
struct vpe10_cdc_shift {
CDC_FIELD_VARIABLE_LIST_VPE10(uint8_t)
};
struct vpe10_cdc_mask {
CDC_FIELD_VARIABLE_LIST_VPE10(uint32_t)
};
struct vpe10_cdc {
struct cdc base; // base class, must be the first field
struct vpe10_cdc_registers *regs;
const struct vpe10_cdc_shift *shift;
const struct vpe10_cdc_mask *mask;
};
void vpe10_construct_cdc(struct vpe_priv *vpe_priv, struct cdc *cdc);
bool vpe10_cdc_check_input_format(struct cdc *cdc, enum vpe_surface_pixel_format format);
bool vpe10_cdc_check_output_format(struct cdc *cdc, enum vpe_surface_pixel_format format);
void vpe10_cdc_program_surface_config(struct cdc *cdc, enum vpe_surface_pixel_format format,
enum vpe_rotation_angle rotation, bool horizontal_mirror, enum vpe_swizzle_mode_values swizzle);
void vpe10_cdc_program_crossbar_config(struct cdc *cdc, enum vpe_surface_pixel_format format);
void vpe10_cdc_program_global_sync(
struct cdc *cdc, uint32_t vupdate_offset, uint32_t vupdate_width, uint32_t vready_offset);
void vpe10_cdc_program_p2b_config(struct cdc *cdc, enum vpe_surface_pixel_format format);
/***** segment register programming *****/
void vpe10_cdc_program_viewport(
struct cdc *cdc, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,135 @@
/* 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 "color_pwl.h"
#ifdef __cplusplus
extern "C" {
#endif
struct config_writer;
#define TF_HELPER_REG_FIELD_LIST(type) \
type exp_region0_lut_offset; \
type exp_region0_num_segments; \
type exp_region1_lut_offset; \
type exp_region1_num_segments; \
type field_region_end; \
type field_region_end_slope; \
type field_region_end_base; \
type exp_region_start; \
type exp_region_start_segment; \
type field_region_linear_slope; \
type field_region_start_base; \
type field_offset
#define TF_HELPER_REG_LIST \
uint32_t start_cntl_b; \
uint32_t start_cntl_g; \
uint32_t start_cntl_r; \
uint32_t start_slope_cntl_b; \
uint32_t start_slope_cntl_g; \
uint32_t start_slope_cntl_r; \
uint32_t start_end_cntl1_b; \
uint32_t start_end_cntl2_b; \
uint32_t start_end_cntl1_g; \
uint32_t start_end_cntl2_g; \
uint32_t start_end_cntl1_r; \
uint32_t start_end_cntl2_r; \
uint32_t region_start; \
uint32_t region_end
struct vpe10_xfer_func_shift {
TF_HELPER_REG_FIELD_LIST(uint8_t);
};
struct vpe10_xfer_func_mask {
TF_HELPER_REG_FIELD_LIST(uint32_t);
};
struct vpe10_xfer_func_reg {
struct vpe10_xfer_func_shift shifts;
struct vpe10_xfer_func_mask masks;
TF_HELPER_REG_LIST;
uint32_t offset_b;
uint32_t offset_g;
uint32_t offset_r;
uint32_t start_base_cntl_b;
uint32_t start_base_cntl_g;
uint32_t start_base_cntl_r;
};
#define TF_CM_REG_FIELD_LIST(type) \
type csc_c11; \
type csc_c12
struct cm_color_matrix_shift {
TF_CM_REG_FIELD_LIST(uint8_t);
};
struct cm_color_matrix_mask {
TF_CM_REG_FIELD_LIST(uint32_t);
};
struct color_matrices_reg {
struct cm_color_matrix_shift shifts;
struct cm_color_matrix_mask masks;
uint32_t csc_c11_c12;
uint32_t csc_c33_c34;
};
enum cm_rgb_channel {
CM_PWL_R,
CM_PWL_G,
CM_PWL_B
};
void vpe10_cm_helper_program_pwl(struct config_writer *config_writer,
const struct pwl_result_data *rgb, uint32_t last_base_value, uint32_t num,
uint32_t lut_data_reg_offset, uint8_t lut_data_reg_shift, uint32_t lut_data_reg_mask,
enum cm_rgb_channel channel);
void vpe10_cm_helper_program_color_matrices(struct config_writer *config_writer,
const uint16_t *regval, const struct color_matrices_reg *reg);
void vpe10_cm_helper_program_gamcor_xfer_func(struct config_writer *config_writer,
const struct pwl_params *params, const struct vpe10_xfer_func_reg *reg);
bool vpe10_cm_helper_translate_curve_to_hw_format(
const struct transfer_func *output_tf, struct pwl_params *lut_params, bool fixpoint);
bool vpe10_cm_helper_translate_curve_to_degamma_hw_format(
const struct transfer_func *output_tf, struct pwl_params *lut_params);
void vpe10_cm_get_tf_pwl_params(const struct transfer_func *output_tf,
struct pwl_params **lut_params, enum cm_type vpe_cm_type);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,44 @@
/* 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 "cmd_builder.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe10_construct_cmd_builder(struct vpe_priv *vpe_priv, struct cmd_builder *cmd_builder);
enum vpe_status vpe10_build_noops(struct vpe_priv *vpe_priv, uint32_t **ppbuf, uint32_t num_dwords);
enum vpe_status vpe10_build_vpe_cmd(
struct vpe_priv *vpe_priv, struct vpe_build_bufs *cur_bufs, uint32_t cmd_idx);
enum vpe_status vpe10_build_plane_descriptor(
struct vpe_priv *vpe_priv, struct vpe_buf *buf, uint32_t cmd_idx);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,887 @@
/* 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 "dpp.h"
#include "transform.h"
#include "reg_helper.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_VPE10(id) \
SRIDFVL(VPCNVC_SURFACE_PIXEL_FORMAT, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FORMAT_CONTROL, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_BIAS_R, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_BIAS_G, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_BIAS_B, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_SCALE_R, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_SCALE_G, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_FCNV_FP_SCALE_B, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COLOR_KEYER_CONTROL, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COLOR_KEYER_ALPHA, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COLOR_KEYER_RED, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COLOR_KEYER_GREEN, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COLOR_KEYER_BLUE, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_ALPHA_2BIT_LUT, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_DEALPHA, VPCNVC_CFG, id), SRIDFVL(VPCNVC_PRE_CSC_MODE, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C11_C12, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C13_C14, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C21_C22, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C23_C24, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C31_C32, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_CSC_C33_C34, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_COEF_FORMAT, VPCNVC_CFG, id), SRIDFVL(VPCNVC_PRE_DEGAM, VPCNVC_CFG, id), \
SRIDFVL(VPCNVC_PRE_REALPHA, VPCNVC_CFG, id), \
SRIDFVL(VPDSCL_COEF_RAM_TAP_SELECT, VPDSCL, id), \
SRIDFVL(VPDSCL_COEF_RAM_TAP_DATA, VPDSCL, id), SRIDFVL(VPDSCL_MODE, VPDSCL, id), \
SRIDFVL(VPDSCL_TAP_CONTROL, VPDSCL, id), SRIDFVL(VPDSCL_CONTROL, VPDSCL, id), \
SRIDFVL(VPDSCL_2TAP_CONTROL, VPDSCL, id), \
SRIDFVL(VPDSCL_MANUAL_REPLICATE_CONTROL, VPDSCL, id), \
SRIDFVL(VPDSCL_HORZ_FILTER_SCALE_RATIO, VPDSCL, id), \
SRIDFVL(VPDSCL_HORZ_FILTER_INIT, VPDSCL, id), \
SRIDFVL(VPDSCL_HORZ_FILTER_SCALE_RATIO_C, VPDSCL, id), \
SRIDFVL(VPDSCL_HORZ_FILTER_INIT_C, VPDSCL, id), \
SRIDFVL(VPDSCL_VERT_FILTER_SCALE_RATIO, VPDSCL, id), \
SRIDFVL(VPDSCL_VERT_FILTER_INIT, VPDSCL, id), \
SRIDFVL(VPDSCL_VERT_FILTER_SCALE_RATIO_C, VPDSCL, id), \
SRIDFVL(VPDSCL_VERT_FILTER_INIT_C, VPDSCL, id), SRIDFVL(VPDSCL_BLACK_COLOR, VPDSCL, id), \
SRIDFVL(VPDSCL_UPDATE, VPDSCL, id), SRIDFVL(VPDSCL_AUTOCAL, VPDSCL, id), \
SRIDFVL(VPDSCL_EXT_OVERSCAN_LEFT_RIGHT, VPDSCL, id), \
SRIDFVL(VPDSCL_EXT_OVERSCAN_TOP_BOTTOM, VPDSCL, id), SRIDFVL(VPOTG_H_BLANK, VPDSCL, id), \
SRIDFVL(VPOTG_V_BLANK, VPDSCL, id), SRIDFVL(VPDSCL_RECOUT_START, VPDSCL, id), \
SRIDFVL(VPDSCL_RECOUT_SIZE, VPDSCL, id), SRIDFVL(VPMPC_SIZE, VPDSCL, id), \
SRIDFVL(VPLB_DATA_FORMAT, VPDSCL, id), SRIDFVL(VPLB_MEMORY_CTRL, VPDSCL, id), \
SRIDFVL(VPLB_V_COUNTER, VPDSCL, id), SRIDFVL(VPDSCL_MEM_PWR_CTRL, VPDSCL, id), \
SRIDFVL(VPDSCL_MEM_PWR_STATUS, VPDSCL, id), SRIDFVL(VPCM_CONTROL, VPCM, id), \
SRIDFVL(VPCM_POST_CSC_CONTROL, VPCM, id), SRIDFVL(VPCM_POST_CSC_C11_C12, VPCM, id), \
SRIDFVL(VPCM_POST_CSC_C13_C14, VPCM, id), SRIDFVL(VPCM_POST_CSC_C21_C22, VPCM, id), \
SRIDFVL(VPCM_POST_CSC_C23_C24, VPCM, id), SRIDFVL(VPCM_POST_CSC_C31_C32, VPCM, id), \
SRIDFVL(VPCM_POST_CSC_C33_C34, VPCM, id), SRIDFVL(VPCM_GAMUT_REMAP_CONTROL, VPCM, id), \
SRIDFVL(VPCM_GAMUT_REMAP_C11_C12, VPCM, id), SRIDFVL(VPCM_GAMUT_REMAP_C13_C14, VPCM, id), \
SRIDFVL(VPCM_GAMUT_REMAP_C21_C22, VPCM, id), SRIDFVL(VPCM_GAMUT_REMAP_C23_C24, VPCM, id), \
SRIDFVL(VPCM_GAMUT_REMAP_C31_C32, VPCM, id), SRIDFVL(VPCM_GAMUT_REMAP_C33_C34, VPCM, id), \
SRIDFVL(VPCM_BIAS_CR_R, VPCM, id), SRIDFVL(VPCM_BIAS_Y_G_CB_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_CONTROL, VPCM, id), SRIDFVL(VPCM_GAMCOR_LUT_INDEX, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_LUT_DATA, VPCM, id), SRIDFVL(VPCM_GAMCOR_LUT_CONTROL, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_CNTL_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_CNTL_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_CNTL_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_BASE_CNTL_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_BASE_CNTL_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_START_BASE_CNTL_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL1_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL2_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL1_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL2_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL1_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_END_CNTL2_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_OFFSET_B, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_OFFSET_G, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_OFFSET_R, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_0_1, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_2_3, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_4_5, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_6_7, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_8_9, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_10_11, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_12_13, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_14_15, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_16_17, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_18_19, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_20_21, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_22_23, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_24_25, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_26_27, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_28_29, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_30_31, VPCM, id), \
SRIDFVL(VPCM_GAMCOR_RAMA_REGION_32_33, VPCM, id), SRIDFVL(VPCM_HDR_MULT_COEF, VPCM, id), \
SRIDFVL(VPCM_MEM_PWR_CTRL, VPCM, id), SRIDFVL(VPCM_MEM_PWR_STATUS, VPCM, id), \
SRIDFVL(VPCM_DEALPHA, VPCM, id), SRIDFVL(VPCM_COEF_FORMAT, VPCM, id), \
SRIDFVL(VPDPP_CONTROL, VPDPP_TOP, id), SRIDFVL(VPDPP_CRC_CTRL, VPDPP_TOP, id),
#define DPP_FIELD_LIST_VPE10(post_fix) \
SFRB(VPCNVC_SURFACE_PIXEL_FORMAT, VPCNVC_SURFACE_PIXEL_FORMAT, post_fix), \
SFRB(FORMAT_EXPANSION_MODE, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(FORMAT_CNV16, VPCNVC_FORMAT_CONTROL, post_fix), \
DPP_SFRB(FORMAT_CONTROL__ALPHA_EN, VPCNVC, post_fix), \
SFRB(VPCNVC_BYPASS, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(VPCNVC_BYPASS_MSB_ALIGN, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(CLAMP_POSITIVE, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(CLAMP_POSITIVE_C, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(VPCNVC_UPDATE_PENDING, VPCNVC_FORMAT_CONTROL, post_fix), \
SFRB(FCNV_FP_BIAS_R, VPCNVC_FCNV_FP_BIAS_R, post_fix), \
SFRB(FCNV_FP_BIAS_G, VPCNVC_FCNV_FP_BIAS_G, post_fix), \
SFRB(FCNV_FP_BIAS_B, VPCNVC_FCNV_FP_BIAS_B, post_fix), \
SFRB(FCNV_FP_SCALE_R, VPCNVC_FCNV_FP_SCALE_R, post_fix), \
SFRB(FCNV_FP_SCALE_G, VPCNVC_FCNV_FP_SCALE_G, post_fix), \
SFRB(FCNV_FP_SCALE_B, VPCNVC_FCNV_FP_SCALE_B, post_fix), \
SFRB(COLOR_KEYER_EN, VPCNVC_COLOR_KEYER_CONTROL, post_fix), \
SFRB(COLOR_KEYER_MODE, VPCNVC_COLOR_KEYER_CONTROL, post_fix), \
SFRB(COLOR_KEYER_ALPHA_LOW, VPCNVC_COLOR_KEYER_ALPHA, post_fix), \
SFRB(COLOR_KEYER_ALPHA_HIGH, VPCNVC_COLOR_KEYER_ALPHA, post_fix), \
SFRB(COLOR_KEYER_RED_LOW, VPCNVC_COLOR_KEYER_RED, post_fix), \
SFRB(COLOR_KEYER_RED_HIGH, VPCNVC_COLOR_KEYER_RED, post_fix), \
SFRB(COLOR_KEYER_GREEN_LOW, VPCNVC_COLOR_KEYER_GREEN, post_fix), \
SFRB(COLOR_KEYER_GREEN_HIGH, VPCNVC_COLOR_KEYER_GREEN, post_fix), \
SFRB(COLOR_KEYER_BLUE_LOW, VPCNVC_COLOR_KEYER_BLUE, post_fix), \
SFRB(COLOR_KEYER_BLUE_HIGH, VPCNVC_COLOR_KEYER_BLUE, post_fix), \
SFRB(ALPHA_2BIT_LUT0, VPCNVC_ALPHA_2BIT_LUT, post_fix), \
SFRB(ALPHA_2BIT_LUT1, VPCNVC_ALPHA_2BIT_LUT, post_fix), \
SFRB(ALPHA_2BIT_LUT2, VPCNVC_ALPHA_2BIT_LUT, post_fix), \
SFRB(ALPHA_2BIT_LUT3, VPCNVC_ALPHA_2BIT_LUT, post_fix), \
SFRB(PRE_DEALPHA_EN, VPCNVC_PRE_DEALPHA, post_fix), \
SFRB(PRE_DEALPHA_ABLND_EN, VPCNVC_PRE_DEALPHA, post_fix), \
SFRB(PRE_CSC_MODE, VPCNVC_PRE_CSC_MODE, post_fix), \
SFRB(PRE_CSC_MODE_CURRENT, VPCNVC_PRE_CSC_MODE, post_fix), \
SFRB(PRE_CSC_C11, VPCNVC_PRE_CSC_C11_C12, post_fix), \
SFRB(PRE_CSC_C12, VPCNVC_PRE_CSC_C11_C12, post_fix), \
SFRB(PRE_CSC_C13, VPCNVC_PRE_CSC_C13_C14, post_fix), \
SFRB(PRE_CSC_C14, VPCNVC_PRE_CSC_C13_C14, post_fix), \
SFRB(PRE_CSC_C21, VPCNVC_PRE_CSC_C21_C22, post_fix), \
SFRB(PRE_CSC_C22, VPCNVC_PRE_CSC_C21_C22, post_fix), \
SFRB(PRE_CSC_C23, VPCNVC_PRE_CSC_C23_C24, post_fix), \
SFRB(PRE_CSC_C24, VPCNVC_PRE_CSC_C23_C24, post_fix), \
SFRB(PRE_CSC_C31, VPCNVC_PRE_CSC_C31_C32, post_fix), \
SFRB(PRE_CSC_C32, VPCNVC_PRE_CSC_C31_C32, post_fix), \
SFRB(PRE_CSC_C33, VPCNVC_PRE_CSC_C33_C34, post_fix), \
SFRB(PRE_CSC_C34, VPCNVC_PRE_CSC_C33_C34, post_fix), \
SFRB(PRE_CSC_COEF_FORMAT, VPCNVC_COEF_FORMAT, post_fix), \
SFRB(PRE_DEGAM_MODE, VPCNVC_PRE_DEGAM, post_fix), \
SFRB(PRE_DEGAM_SELECT, VPCNVC_PRE_DEGAM, post_fix), \
SFRB(PRE_REALPHA_EN, VPCNVC_PRE_REALPHA, post_fix), \
SFRB(PRE_REALPHA_ABLND_EN, VPCNVC_PRE_REALPHA, post_fix), \
SFRB(SCL_COEF_RAM_TAP_PAIR_IDX, VPDSCL_COEF_RAM_TAP_SELECT, post_fix), \
SFRB(SCL_COEF_RAM_PHASE, VPDSCL_COEF_RAM_TAP_SELECT, post_fix), \
SFRB(SCL_COEF_RAM_FILTER_TYPE, VPDSCL_COEF_RAM_TAP_SELECT, post_fix), \
SFRB(SCL_COEF_RAM_EVEN_TAP_COEF, VPDSCL_COEF_RAM_TAP_DATA, post_fix), \
SFRB(SCL_COEF_RAM_EVEN_TAP_COEF_EN, VPDSCL_COEF_RAM_TAP_DATA, post_fix), \
SFRB(SCL_COEF_RAM_ODD_TAP_COEF, VPDSCL_COEF_RAM_TAP_DATA, post_fix), \
SFRB(SCL_COEF_RAM_ODD_TAP_COEF_EN, VPDSCL_COEF_RAM_TAP_DATA, post_fix), \
SFRB(VPDSCL_MODE, VPDSCL_MODE, post_fix), \
SFRB(SCL_COEF_RAM_SELECT_CURRENT, VPDSCL_MODE, post_fix), \
SFRB(SCL_CHROMA_COEF_MODE, VPDSCL_MODE, post_fix), \
SFRB(SCL_ALPHA_COEF_MODE, VPDSCL_MODE, post_fix), \
SFRB(SCL_COEF_RAM_SELECT_RD, VPDSCL_MODE, post_fix), \
SFRB(SCL_V_NUM_TAPS, VPDSCL_TAP_CONTROL, post_fix), \
SFRB(SCL_H_NUM_TAPS, VPDSCL_TAP_CONTROL, post_fix), \
SFRB(SCL_V_NUM_TAPS_C, VPDSCL_TAP_CONTROL, post_fix), \
SFRB(SCL_H_NUM_TAPS_C, VPDSCL_TAP_CONTROL, post_fix), \
SFRB(SCL_BOUNDARY_MODE, VPDSCL_CONTROL, post_fix), \
SFRB(SCL_H_2TAP_HARDCODE_COEF_EN, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_H_2TAP_SHARP_EN, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_H_2TAP_SHARP_FACTOR, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_V_2TAP_HARDCODE_COEF_EN, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_V_2TAP_SHARP_EN, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_V_2TAP_SHARP_FACTOR, VPDSCL_2TAP_CONTROL, post_fix), \
SFRB(SCL_V_MANUAL_REPLICATE_FACTOR, VPDSCL_MANUAL_REPLICATE_CONTROL, post_fix), \
SFRB(SCL_H_MANUAL_REPLICATE_FACTOR, VPDSCL_MANUAL_REPLICATE_CONTROL, post_fix), \
SFRB(SCL_H_SCALE_RATIO, VPDSCL_HORZ_FILTER_SCALE_RATIO, post_fix), \
SFRB(SCL_H_INIT_FRAC, VPDSCL_HORZ_FILTER_INIT, post_fix), \
SFRB(SCL_H_INIT_INT, VPDSCL_HORZ_FILTER_INIT, post_fix), \
SFRB(SCL_H_SCALE_RATIO_C, VPDSCL_HORZ_FILTER_SCALE_RATIO_C, post_fix), \
SFRB(SCL_H_INIT_FRAC_C, VPDSCL_HORZ_FILTER_INIT_C, post_fix), \
SFRB(SCL_H_INIT_INT_C, VPDSCL_HORZ_FILTER_INIT_C, post_fix), \
SFRB(SCL_V_SCALE_RATIO, VPDSCL_VERT_FILTER_SCALE_RATIO, post_fix), \
SFRB(SCL_V_INIT_FRAC, VPDSCL_VERT_FILTER_INIT, post_fix), \
SFRB(SCL_V_INIT_INT, VPDSCL_VERT_FILTER_INIT, post_fix), \
SFRB(SCL_V_SCALE_RATIO_C, VPDSCL_VERT_FILTER_SCALE_RATIO_C, post_fix), \
SFRB(SCL_V_INIT_FRAC_C, VPDSCL_VERT_FILTER_INIT_C, post_fix), \
SFRB(SCL_V_INIT_INT_C, VPDSCL_VERT_FILTER_INIT_C, post_fix), \
SFRB(SCL_BLACK_COLOR_RGB_Y, VPDSCL_BLACK_COLOR, post_fix), \
SFRB(SCL_BLACK_COLOR_CBCR, VPDSCL_BLACK_COLOR, post_fix), \
SFRB(SCL_UPDATE_PENDING, VPDSCL_UPDATE, post_fix), \
SFRB(AUTOCAL_MODE, VPDSCL_AUTOCAL, post_fix), \
SFRB(EXT_OVERSCAN_RIGHT, VPDSCL_EXT_OVERSCAN_LEFT_RIGHT, post_fix), \
SFRB(EXT_OVERSCAN_LEFT, VPDSCL_EXT_OVERSCAN_LEFT_RIGHT, post_fix), \
SFRB(EXT_OVERSCAN_BOTTOM, VPDSCL_EXT_OVERSCAN_TOP_BOTTOM, post_fix), \
SFRB(EXT_OVERSCAN_TOP, VPDSCL_EXT_OVERSCAN_TOP_BOTTOM, post_fix), \
SFRB(OTG_H_BLANK_START, VPOTG_H_BLANK, post_fix), \
SFRB(OTG_H_BLANK_END, VPOTG_H_BLANK, post_fix), \
SFRB(OTG_V_BLANK_START, VPOTG_V_BLANK, post_fix), \
SFRB(OTG_V_BLANK_END, VPOTG_V_BLANK, post_fix), \
SFRB(RECOUT_START_X, VPDSCL_RECOUT_START, post_fix), \
SFRB(RECOUT_START_Y, VPDSCL_RECOUT_START, post_fix), \
SFRB(RECOUT_WIDTH, VPDSCL_RECOUT_SIZE, post_fix), \
SFRB(RECOUT_HEIGHT, VPDSCL_RECOUT_SIZE, post_fix), \
SFRB(VPMPC_WIDTH, VPMPC_SIZE, post_fix), SFRB(VPMPC_HEIGHT, VPMPC_SIZE, post_fix), \
SFRB(ALPHA_EN, VPLB_DATA_FORMAT, post_fix), \
SFRB(MEMORY_CONFIG, VPLB_MEMORY_CTRL, post_fix), \
SFRB(LB_MAX_PARTITIONS, VPLB_MEMORY_CTRL, post_fix), \
SFRB(LB_NUM_PARTITIONS, VPLB_MEMORY_CTRL, post_fix), \
SFRB(LB_NUM_PARTITIONS_C, VPLB_MEMORY_CTRL, post_fix), \
SFRB(V_COUNTER, VPLB_V_COUNTER, post_fix), SFRB(V_COUNTER_C, VPLB_V_COUNTER, post_fix), \
SFRB(LUT_MEM_PWR_FORCE, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LUT_MEM_PWR_DIS, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LB_G1_MEM_PWR_FORCE, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LB_G1_MEM_PWR_DIS, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LB_G2_MEM_PWR_FORCE, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LB_G2_MEM_PWR_DIS, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LB_MEM_PWR_MODE, VPDSCL_MEM_PWR_CTRL, post_fix), \
SFRB(LUT_MEM_PWR_STATE, VPDSCL_MEM_PWR_STATUS, post_fix), \
SFRB(LB_G1_MEM_PWR_STATE, VPDSCL_MEM_PWR_STATUS, post_fix), \
SFRB(LB_G2_MEM_PWR_STATE, VPDSCL_MEM_PWR_STATUS, post_fix), \
SFRB(VPCM_BYPASS, VPCM_CONTROL, post_fix), \
SFRB(VPCM_UPDATE_PENDING, VPCM_CONTROL, post_fix), \
SFRB(VPCM_POST_CSC_MODE, VPCM_POST_CSC_CONTROL, post_fix), \
SFRB(VPCM_POST_CSC_MODE_CURRENT, VPCM_POST_CSC_CONTROL, post_fix), \
SFRB(VPCM_POST_CSC_C11, VPCM_POST_CSC_C11_C12, post_fix), \
SFRB(VPCM_POST_CSC_C12, VPCM_POST_CSC_C11_C12, post_fix), \
SFRB(VPCM_POST_CSC_C13, VPCM_POST_CSC_C13_C14, post_fix), \
SFRB(VPCM_POST_CSC_C14, VPCM_POST_CSC_C13_C14, post_fix), \
SFRB(VPCM_POST_CSC_C21, VPCM_POST_CSC_C21_C22, post_fix), \
SFRB(VPCM_POST_CSC_C22, VPCM_POST_CSC_C21_C22, post_fix), \
SFRB(VPCM_POST_CSC_C23, VPCM_POST_CSC_C23_C24, post_fix), \
SFRB(VPCM_POST_CSC_C24, VPCM_POST_CSC_C23_C24, post_fix), \
SFRB(VPCM_POST_CSC_C31, VPCM_POST_CSC_C31_C32, post_fix), \
SFRB(VPCM_POST_CSC_C32, VPCM_POST_CSC_C31_C32, post_fix), \
SFRB(VPCM_POST_CSC_C33, VPCM_POST_CSC_C33_C34, post_fix), \
SFRB(VPCM_POST_CSC_C34, VPCM_POST_CSC_C33_C34, post_fix), \
SFRB(VPCM_GAMUT_REMAP_MODE, VPCM_GAMUT_REMAP_CONTROL, post_fix), \
SFRB(VPCM_GAMUT_REMAP_MODE_CURRENT, VPCM_GAMUT_REMAP_CONTROL, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C11, VPCM_GAMUT_REMAP_C11_C12, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C12, VPCM_GAMUT_REMAP_C11_C12, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C13, VPCM_GAMUT_REMAP_C13_C14, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C14, VPCM_GAMUT_REMAP_C13_C14, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C21, VPCM_GAMUT_REMAP_C21_C22, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C22, VPCM_GAMUT_REMAP_C21_C22, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C23, VPCM_GAMUT_REMAP_C23_C24, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C24, VPCM_GAMUT_REMAP_C23_C24, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C31, VPCM_GAMUT_REMAP_C31_C32, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C32, VPCM_GAMUT_REMAP_C31_C32, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C33, VPCM_GAMUT_REMAP_C33_C34, post_fix), \
SFRB(VPCM_GAMUT_REMAP_C34, VPCM_GAMUT_REMAP_C33_C34, post_fix), \
SFRB(VPCM_BIAS_CR_R, VPCM_BIAS_CR_R, post_fix), \
SFRB(VPCM_BIAS_Y_G, VPCM_BIAS_Y_G_CB_B, post_fix), \
SFRB(VPCM_BIAS_CB_B, VPCM_BIAS_Y_G_CB_B, post_fix), \
SFRB(VPCM_GAMCOR_MODE, VPCM_GAMCOR_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_PWL_DISABLE, VPCM_GAMCOR_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_MODE_CURRENT, VPCM_GAMCOR_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_SELECT_CURRENT, VPCM_GAMCOR_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_LUT_INDEX, VPCM_GAMCOR_LUT_INDEX, post_fix), \
SFRB(VPCM_GAMCOR_LUT_DATA, VPCM_GAMCOR_LUT_DATA, post_fix), \
SFRB(VPCM_GAMCOR_LUT_WRITE_COLOR_MASK, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_LUT_READ_COLOR_SEL, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_LUT_READ_DBG, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_LUT_HOST_SEL, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_LUT_CONFIG_MODE, VPCM_GAMCOR_LUT_CONTROL, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_B, VPCM_GAMCOR_RAMA_START_CNTL_B, post_fix), \
SFRB( \
VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B, VPCM_GAMCOR_RAMA_START_CNTL_B, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_G, VPCM_GAMCOR_RAMA_START_CNTL_G, post_fix), \
SFRB( \
VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_G, VPCM_GAMCOR_RAMA_START_CNTL_G, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_R, VPCM_GAMCOR_RAMA_START_CNTL_R, post_fix), \
SFRB( \
VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_R, VPCM_GAMCOR_RAMA_START_CNTL_R, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B, VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_B, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_G, VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_G, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_R, VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_R, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_B, VPCM_GAMCOR_RAMA_START_BASE_CNTL_B, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_G, VPCM_GAMCOR_RAMA_START_BASE_CNTL_G, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_R, VPCM_GAMCOR_RAMA_START_BASE_CNTL_R, \
post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_B, VPCM_GAMCOR_RAMA_END_CNTL1_B, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_B, VPCM_GAMCOR_RAMA_END_CNTL2_B, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B, VPCM_GAMCOR_RAMA_END_CNTL2_B, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_G, VPCM_GAMCOR_RAMA_END_CNTL1_G, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_G, VPCM_GAMCOR_RAMA_END_CNTL2_G, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_G, VPCM_GAMCOR_RAMA_END_CNTL2_G, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_R, VPCM_GAMCOR_RAMA_END_CNTL1_R, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_R, VPCM_GAMCOR_RAMA_END_CNTL2_R, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_R, VPCM_GAMCOR_RAMA_END_CNTL2_R, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_OFFSET_B, VPCM_GAMCOR_RAMA_OFFSET_B, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_OFFSET_G, VPCM_GAMCOR_RAMA_OFFSET_G, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_OFFSET_R, VPCM_GAMCOR_RAMA_OFFSET_R, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_0_1, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_0_1, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_0_1, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_0_1, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION2_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_2_3, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION2_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_2_3, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION3_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_2_3, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION3_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_2_3, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION4_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_4_5, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION4_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_4_5, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION5_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_4_5, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION5_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_4_5, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION6_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_6_7, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION6_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_6_7, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION7_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_6_7, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION7_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_6_7, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION8_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_8_9, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION8_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_8_9, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION9_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_8_9, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION9_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_8_9, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION10_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_10_11, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION10_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_10_11, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION11_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_10_11, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION11_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_10_11, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION12_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_12_13, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION12_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_12_13, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION13_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_12_13, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION13_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_12_13, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION14_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_14_15, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION14_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_14_15, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION15_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_14_15, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION15_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_14_15, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION16_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_16_17, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION16_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_16_17, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION17_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_16_17, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION17_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_16_17, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION18_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_18_19, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION18_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_18_19, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION19_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_18_19, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION19_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_18_19, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION20_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_20_21, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION20_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_20_21, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION21_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_20_21, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION21_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_20_21, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION22_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_22_23, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION22_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_22_23, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION23_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_22_23, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION23_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_22_23, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION24_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_24_25, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION24_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_24_25, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION25_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_24_25, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION25_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_24_25, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION26_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_26_27, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION26_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_26_27, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION27_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_26_27, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION27_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_26_27, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION28_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_28_29, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION28_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_28_29, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION29_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_28_29, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION29_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_28_29, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION30_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_30_31, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION30_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_30_31, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION31_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_30_31, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION31_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_30_31, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION32_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_32_33, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION32_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_32_33, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION33_LUT_OFFSET, VPCM_GAMCOR_RAMA_REGION_32_33, post_fix), \
SFRB(VPCM_GAMCOR_RAMA_EXP_REGION33_NUM_SEGMENTS, VPCM_GAMCOR_RAMA_REGION_32_33, post_fix), \
SFRB(VPCM_HDR_MULT_COEF, VPCM_HDR_MULT_COEF, post_fix), \
SFRB(GAMCOR_MEM_PWR_FORCE, VPCM_MEM_PWR_CTRL, post_fix), \
SFRB(GAMCOR_MEM_PWR_DIS, VPCM_MEM_PWR_CTRL, post_fix), \
SFRB(GAMCOR_MEM_PWR_STATE, VPCM_MEM_PWR_STATUS, post_fix), \
SFRB(VPCM_DEALPHA_EN, VPCM_DEALPHA, post_fix), \
SFRB(VPCM_DEALPHA_ABLND, VPCM_DEALPHA, post_fix), \
SFRB(VPCM_BIAS_FORMAT, VPCM_COEF_FORMAT, post_fix), \
SFRB(VPCM_POST_CSC_COEF_FORMAT, VPCM_COEF_FORMAT, post_fix), \
SFRB(VPCM_GAMUT_REMAP_COEF_FORMAT, VPCM_COEF_FORMAT, post_fix), \
SFRB(VPDPP_CLOCK_ENABLE, VPDPP_CONTROL, post_fix), \
SFRB(VPECLK_G_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(VPECLK_G_DYN_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(VPECLK_G_VPDSCL_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(VPECLK_R_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(DISPCLK_R_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(DISPCLK_G_GATE_DISABLE, VPDPP_CONTROL, post_fix), \
SFRB(VPDPP_FGCG_REP_DIS, VPDPP_CONTROL, post_fix), \
SFRB(VPDPP_TEST_CLK_SEL, VPDPP_CONTROL, post_fix), \
SFRB(VPDPP_CRC_EN, VPDPP_CRC_CTRL, post_fix), \
SFRB(VPDPP_CRC_CONT_EN, VPDPP_CRC_CTRL, post_fix), \
SFRB(VPDPP_CRC_420_COMP_SEL, VPDPP_CRC_CTRL, post_fix), \
SFRB(VPDPP_CRC_SRC_SEL, VPDPP_CRC_CTRL, post_fix), \
SFRB(VPDPP_CRC_PIX_FORMAT_SEL, VPDPP_CRC_CTRL, post_fix), \
SFRB(VPDPP_CRC_MASK, VPDPP_CRC_CTRL, post_fix)
#define DPP_REG_VARIABLE_LIST_VPE10 \
reg_id_val VPCNVC_SURFACE_PIXEL_FORMAT; \
reg_id_val VPCNVC_FORMAT_CONTROL; \
reg_id_val VPCNVC_FCNV_FP_BIAS_R; \
reg_id_val VPCNVC_FCNV_FP_BIAS_G; \
reg_id_val VPCNVC_FCNV_FP_BIAS_B; \
reg_id_val VPCNVC_FCNV_FP_SCALE_R; \
reg_id_val VPCNVC_FCNV_FP_SCALE_G; \
reg_id_val VPCNVC_FCNV_FP_SCALE_B; \
reg_id_val VPCNVC_COLOR_KEYER_CONTROL; \
reg_id_val VPCNVC_COLOR_KEYER_ALPHA; \
reg_id_val VPCNVC_COLOR_KEYER_RED; \
reg_id_val VPCNVC_COLOR_KEYER_GREEN; \
reg_id_val VPCNVC_COLOR_KEYER_BLUE; \
reg_id_val VPCNVC_ALPHA_2BIT_LUT; \
reg_id_val VPCNVC_PRE_DEALPHA; \
reg_id_val VPCNVC_PRE_CSC_MODE; \
reg_id_val VPCNVC_PRE_CSC_C11_C12; \
reg_id_val VPCNVC_PRE_CSC_C13_C14; \
reg_id_val VPCNVC_PRE_CSC_C21_C22; \
reg_id_val VPCNVC_PRE_CSC_C23_C24; \
reg_id_val VPCNVC_PRE_CSC_C31_C32; \
reg_id_val VPCNVC_PRE_CSC_C33_C34; \
reg_id_val VPCNVC_COEF_FORMAT; \
reg_id_val VPCNVC_PRE_DEGAM; \
reg_id_val VPCNVC_PRE_REALPHA; \
reg_id_val VPDSCL_COEF_RAM_TAP_SELECT; \
reg_id_val VPDSCL_COEF_RAM_TAP_DATA; \
reg_id_val VPDSCL_MODE; \
reg_id_val VPDSCL_TAP_CONTROL; \
reg_id_val VPDSCL_CONTROL; \
reg_id_val VPDSCL_2TAP_CONTROL; \
reg_id_val VPDSCL_MANUAL_REPLICATE_CONTROL; \
reg_id_val VPDSCL_HORZ_FILTER_SCALE_RATIO; \
reg_id_val VPDSCL_HORZ_FILTER_INIT; \
reg_id_val VPDSCL_HORZ_FILTER_SCALE_RATIO_C; \
reg_id_val VPDSCL_HORZ_FILTER_INIT_C; \
reg_id_val VPDSCL_VERT_FILTER_SCALE_RATIO; \
reg_id_val VPDSCL_VERT_FILTER_INIT; \
reg_id_val VPDSCL_VERT_FILTER_SCALE_RATIO_C; \
reg_id_val VPDSCL_VERT_FILTER_INIT_C; \
reg_id_val VPDSCL_BLACK_COLOR; \
reg_id_val VPDSCL_UPDATE; \
reg_id_val VPDSCL_AUTOCAL; \
reg_id_val VPDSCL_EXT_OVERSCAN_LEFT_RIGHT; \
reg_id_val VPDSCL_EXT_OVERSCAN_TOP_BOTTOM; \
reg_id_val VPOTG_H_BLANK; \
reg_id_val VPOTG_V_BLANK; \
reg_id_val VPDSCL_RECOUT_START; \
reg_id_val VPDSCL_RECOUT_SIZE; \
reg_id_val VPMPC_SIZE; \
reg_id_val VPLB_DATA_FORMAT; \
reg_id_val VPLB_MEMORY_CTRL; \
reg_id_val VPLB_V_COUNTER; \
reg_id_val VPDSCL_MEM_PWR_CTRL; \
reg_id_val VPDSCL_MEM_PWR_STATUS; \
reg_id_val VPCM_CONTROL; \
reg_id_val VPCM_POST_CSC_CONTROL; \
reg_id_val VPCM_POST_CSC_C11_C12; \
reg_id_val VPCM_POST_CSC_C13_C14; \
reg_id_val VPCM_POST_CSC_C21_C22; \
reg_id_val VPCM_POST_CSC_C23_C24; \
reg_id_val VPCM_POST_CSC_C31_C32; \
reg_id_val VPCM_POST_CSC_C33_C34; \
reg_id_val VPCM_GAMUT_REMAP_CONTROL; \
reg_id_val VPCM_GAMUT_REMAP_C11_C12; \
reg_id_val VPCM_GAMUT_REMAP_C13_C14; \
reg_id_val VPCM_GAMUT_REMAP_C21_C22; \
reg_id_val VPCM_GAMUT_REMAP_C23_C24; \
reg_id_val VPCM_GAMUT_REMAP_C31_C32; \
reg_id_val VPCM_GAMUT_REMAP_C33_C34; \
reg_id_val VPCM_BIAS_CR_R; \
reg_id_val VPCM_BIAS_Y_G_CB_B; \
reg_id_val VPCM_GAMCOR_CONTROL; \
reg_id_val VPCM_GAMCOR_LUT_INDEX; \
reg_id_val VPCM_GAMCOR_LUT_DATA; \
reg_id_val VPCM_GAMCOR_LUT_CONTROL; \
reg_id_val VPCM_GAMCOR_RAMA_START_CNTL_B; \
reg_id_val VPCM_GAMCOR_RAMA_START_CNTL_G; \
reg_id_val VPCM_GAMCOR_RAMA_START_CNTL_R; \
reg_id_val VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_B; \
reg_id_val VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_G; \
reg_id_val VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_R; \
reg_id_val VPCM_GAMCOR_RAMA_START_BASE_CNTL_B; \
reg_id_val VPCM_GAMCOR_RAMA_START_BASE_CNTL_G; \
reg_id_val VPCM_GAMCOR_RAMA_START_BASE_CNTL_R; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL1_B; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL2_B; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL1_G; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL2_G; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL1_R; \
reg_id_val VPCM_GAMCOR_RAMA_END_CNTL2_R; \
reg_id_val VPCM_GAMCOR_RAMA_OFFSET_B; \
reg_id_val VPCM_GAMCOR_RAMA_OFFSET_G; \
reg_id_val VPCM_GAMCOR_RAMA_OFFSET_R; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_0_1; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_2_3; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_4_5; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_6_7; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_8_9; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_10_11; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_12_13; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_14_15; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_16_17; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_18_19; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_20_21; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_22_23; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_24_25; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_26_27; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_28_29; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_30_31; \
reg_id_val VPCM_GAMCOR_RAMA_REGION_32_33; \
reg_id_val VPCM_HDR_MULT_COEF; \
reg_id_val VPCM_MEM_PWR_CTRL; \
reg_id_val VPCM_MEM_PWR_STATUS; \
reg_id_val VPCM_DEALPHA; \
reg_id_val VPCM_COEF_FORMAT; \
reg_id_val VPDPP_CONTROL; \
reg_id_val VPDPP_CRC_CTRL;
#define DPP_FIELD_VARIABLE_LIST_VPE10(type) \
type VPCNVC_SURFACE_PIXEL_FORMAT; \
type FORMAT_EXPANSION_MODE; \
type FORMAT_CNV16; \
type FORMAT_CONTROL__ALPHA_EN; \
type VPCNVC_BYPASS; \
type VPCNVC_BYPASS_MSB_ALIGN; \
type CLAMP_POSITIVE; \
type CLAMP_POSITIVE_C; \
type VPCNVC_UPDATE_PENDING; \
type FCNV_FP_BIAS_R; \
type FCNV_FP_BIAS_G; \
type FCNV_FP_BIAS_B; \
type FCNV_FP_SCALE_R; \
type FCNV_FP_SCALE_G; \
type FCNV_FP_SCALE_B; \
type COLOR_KEYER_EN; \
type COLOR_KEYER_MODE; \
type COLOR_KEYER_ALPHA_LOW; \
type COLOR_KEYER_ALPHA_HIGH; \
type COLOR_KEYER_RED_LOW; \
type COLOR_KEYER_RED_HIGH; \
type COLOR_KEYER_GREEN_LOW; \
type COLOR_KEYER_GREEN_HIGH; \
type COLOR_KEYER_BLUE_LOW; \
type COLOR_KEYER_BLUE_HIGH; \
type ALPHA_2BIT_LUT0; \
type ALPHA_2BIT_LUT1; \
type ALPHA_2BIT_LUT2; \
type ALPHA_2BIT_LUT3; \
type PRE_DEALPHA_EN; \
type PRE_DEALPHA_ABLND_EN; \
type PRE_CSC_MODE; \
type PRE_CSC_MODE_CURRENT; \
type PRE_CSC_C11; \
type PRE_CSC_C12; \
type PRE_CSC_C13; \
type PRE_CSC_C14; \
type PRE_CSC_C21; \
type PRE_CSC_C22; \
type PRE_CSC_C23; \
type PRE_CSC_C24; \
type PRE_CSC_C31; \
type PRE_CSC_C32; \
type PRE_CSC_C33; \
type PRE_CSC_C34; \
type PRE_CSC_COEF_FORMAT; \
type PRE_DEGAM_MODE; \
type PRE_DEGAM_SELECT; \
type PRE_REALPHA_EN; \
type PRE_REALPHA_ABLND_EN; \
type SCL_COEF_RAM_TAP_PAIR_IDX; \
type SCL_COEF_RAM_PHASE; \
type SCL_COEF_RAM_FILTER_TYPE; \
type SCL_COEF_RAM_EVEN_TAP_COEF; \
type SCL_COEF_RAM_EVEN_TAP_COEF_EN; \
type SCL_COEF_RAM_ODD_TAP_COEF; \
type SCL_COEF_RAM_ODD_TAP_COEF_EN; \
type VPDSCL_MODE; \
type SCL_COEF_RAM_SELECT_CURRENT; \
type SCL_CHROMA_COEF_MODE; \
type SCL_ALPHA_COEF_MODE; \
type SCL_COEF_RAM_SELECT_RD; \
type SCL_V_NUM_TAPS; \
type SCL_H_NUM_TAPS; \
type SCL_V_NUM_TAPS_C; \
type SCL_H_NUM_TAPS_C; \
type SCL_BOUNDARY_MODE; \
type SCL_H_2TAP_HARDCODE_COEF_EN; \
type SCL_H_2TAP_SHARP_EN; \
type SCL_H_2TAP_SHARP_FACTOR; \
type SCL_V_2TAP_HARDCODE_COEF_EN; \
type SCL_V_2TAP_SHARP_EN; \
type SCL_V_2TAP_SHARP_FACTOR; \
type SCL_V_MANUAL_REPLICATE_FACTOR; \
type SCL_H_MANUAL_REPLICATE_FACTOR; \
type SCL_H_SCALE_RATIO; \
type SCL_H_INIT_FRAC; \
type SCL_H_INIT_INT; \
type SCL_H_SCALE_RATIO_C; \
type SCL_H_INIT_FRAC_C; \
type SCL_H_INIT_INT_C; \
type SCL_V_SCALE_RATIO; \
type SCL_V_INIT_FRAC; \
type SCL_V_INIT_INT; \
type SCL_V_SCALE_RATIO_C; \
type SCL_V_INIT_FRAC_C; \
type SCL_V_INIT_INT_C; \
type SCL_BLACK_COLOR_RGB_Y; \
type SCL_BLACK_COLOR_CBCR; \
type SCL_UPDATE_PENDING; \
type AUTOCAL_MODE; \
type EXT_OVERSCAN_RIGHT; \
type EXT_OVERSCAN_LEFT; \
type EXT_OVERSCAN_BOTTOM; \
type EXT_OVERSCAN_TOP; \
type OTG_H_BLANK_START; \
type OTG_H_BLANK_END; \
type OTG_V_BLANK_START; \
type OTG_V_BLANK_END; \
type RECOUT_START_X; \
type RECOUT_START_Y; \
type RECOUT_WIDTH; \
type RECOUT_HEIGHT; \
type VPMPC_WIDTH; \
type VPMPC_HEIGHT; \
type ALPHA_EN; \
type MEMORY_CONFIG; \
type LB_MAX_PARTITIONS; \
type LB_NUM_PARTITIONS; \
type LB_NUM_PARTITIONS_C; \
type V_COUNTER; \
type V_COUNTER_C; \
type LUT_MEM_PWR_FORCE; \
type LUT_MEM_PWR_DIS; \
type LB_G1_MEM_PWR_FORCE; \
type LB_G1_MEM_PWR_DIS; \
type LB_G2_MEM_PWR_FORCE; \
type LB_G2_MEM_PWR_DIS; \
type LB_MEM_PWR_MODE; \
type LUT_MEM_PWR_STATE; \
type LB_G1_MEM_PWR_STATE; \
type LB_G2_MEM_PWR_STATE; \
type VPCM_BYPASS; \
type VPCM_UPDATE_PENDING; \
type VPCM_POST_CSC_MODE; \
type VPCM_POST_CSC_MODE_CURRENT; \
type VPCM_POST_CSC_C11; \
type VPCM_POST_CSC_C12; \
type VPCM_POST_CSC_C13; \
type VPCM_POST_CSC_C14; \
type VPCM_POST_CSC_C21; \
type VPCM_POST_CSC_C22; \
type VPCM_POST_CSC_C23; \
type VPCM_POST_CSC_C24; \
type VPCM_POST_CSC_C31; \
type VPCM_POST_CSC_C32; \
type VPCM_POST_CSC_C33; \
type VPCM_POST_CSC_C34; \
type VPCM_GAMUT_REMAP_MODE; \
type VPCM_GAMUT_REMAP_MODE_CURRENT; \
type VPCM_GAMUT_REMAP_C11; \
type VPCM_GAMUT_REMAP_C12; \
type VPCM_GAMUT_REMAP_C13; \
type VPCM_GAMUT_REMAP_C14; \
type VPCM_GAMUT_REMAP_C21; \
type VPCM_GAMUT_REMAP_C22; \
type VPCM_GAMUT_REMAP_C23; \
type VPCM_GAMUT_REMAP_C24; \
type VPCM_GAMUT_REMAP_C31; \
type VPCM_GAMUT_REMAP_C32; \
type VPCM_GAMUT_REMAP_C33; \
type VPCM_GAMUT_REMAP_C34; \
type VPCM_BIAS_CR_R; \
type VPCM_BIAS_Y_G; \
type VPCM_BIAS_CB_B; \
type VPCM_GAMCOR_MODE; \
type VPCM_GAMCOR_PWL_DISABLE; \
type VPCM_GAMCOR_MODE_CURRENT; \
type VPCM_GAMCOR_SELECT_CURRENT; \
type VPCM_GAMCOR_LUT_INDEX; \
type VPCM_GAMCOR_LUT_DATA; \
type VPCM_GAMCOR_LUT_WRITE_COLOR_MASK; \
type VPCM_GAMCOR_LUT_READ_COLOR_SEL; \
type VPCM_GAMCOR_LUT_READ_DBG; \
type VPCM_GAMCOR_LUT_HOST_SEL; \
type VPCM_GAMCOR_LUT_CONFIG_MODE; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_G; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_R; \
type VPCM_GAMCOR_RAMA_OFFSET_B; \
type VPCM_GAMCOR_RAMA_OFFSET_G; \
type VPCM_GAMCOR_RAMA_OFFSET_R; \
type VPCM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION2_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION2_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION3_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION3_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION4_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION4_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION5_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION5_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION6_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION6_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION7_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION7_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION8_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION8_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION9_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION9_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION10_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION10_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION11_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION11_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION12_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION12_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION13_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION13_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION14_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION14_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION15_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION15_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION16_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION16_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION17_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION17_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION18_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION18_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION19_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION19_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION20_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION20_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION21_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION21_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION22_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION22_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION23_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION23_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION24_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION24_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION25_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION25_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION26_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION26_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION27_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION27_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION28_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION28_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION29_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION29_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION30_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION30_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION31_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION31_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION32_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION32_NUM_SEGMENTS; \
type VPCM_GAMCOR_RAMA_EXP_REGION33_LUT_OFFSET; \
type VPCM_GAMCOR_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type VPCM_HDR_MULT_COEF; \
type GAMCOR_MEM_PWR_FORCE; \
type GAMCOR_MEM_PWR_DIS; \
type GAMCOR_MEM_PWR_STATE; \
type VPCM_DEALPHA_EN; \
type VPCM_DEALPHA_ABLND; \
type VPCM_BIAS_FORMAT; \
type VPCM_POST_CSC_COEF_FORMAT; \
type VPCM_GAMUT_REMAP_COEF_FORMAT; \
type VPDPP_CLOCK_ENABLE; \
type VPECLK_G_GATE_DISABLE; \
type VPECLK_G_DYN_GATE_DISABLE; \
type VPECLK_G_VPDSCL_GATE_DISABLE; \
type VPECLK_R_GATE_DISABLE; \
type DISPCLK_R_GATE_DISABLE; \
type DISPCLK_G_GATE_DISABLE; \
type VPDPP_FGCG_REP_DIS; \
type VPDPP_TEST_CLK_SEL; \
type VPDPP_CRC_EN; \
type VPDPP_CRC_CONT_EN; \
type VPDPP_CRC_420_COMP_SEL; \
type VPDPP_CRC_SRC_SEL; \
type VPDPP_CRC_PIX_FORMAT_SEL; \
type VPDPP_CRC_MASK;
#define IDENTITY_RATIO(ratio) (vpe_fixpt_u3d19(ratio) == (1 << 19))
struct vpe10_dpp_registers {
DPP_REG_VARIABLE_LIST_VPE10
};
struct vpe10_dpp_shift {
DPP_FIELD_VARIABLE_LIST_VPE10(uint8_t)
};
struct vpe10_dpp_mask {
DPP_FIELD_VARIABLE_LIST_VPE10(uint32_t)
};
struct vpe10_dpp {
struct dpp base; // base class, must be the 1st field
struct vpe10_dpp_registers *regs;
const struct vpe10_dpp_shift *shift;
const struct vpe10_dpp_mask *mask;
};
void vpe10_construct_dpp(struct vpe_priv *vpe_priv, struct dpp *dpp);
bool vpe10_dpp_get_optimal_number_of_taps(
struct dpp *dpp, struct scaler_data *scl_data, const struct vpe_scaling_taps *in_taps);
void vpe10_dscl_calc_lb_num_partitions(const struct scaler_data *scl_data,
enum lb_memory_config lb_config, uint32_t *num_part_y, uint32_t *num_part_c);
/***** share register programming *****/
void vpe10_dpp_program_cnv(
struct dpp *dpp, enum vpe_surface_pixel_format format, enum vpe_expansion_mode mode);
void vpe10_dpp_cnv_program_pre_dgam(struct dpp *dpp, enum color_transfer_func tr);
void vpe10_dpp_program_cnv_bias_scale(struct dpp *dpp, struct bias_and_scale *bias_and_scale);
void vpe10_dpp_cnv_program_alpha_keyer(struct dpp *dpp, struct cnv_color_keyer_params *color_keyer);
void vpe10_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf);
void vpe10_dpp_program_gamut_remap(struct dpp *dpp, struct colorspace_transform *gamut_remap);
/*program post scaler scs block in dpp CM*/
void vpe10_dpp_program_post_csc(struct dpp *dpp, enum color_space color_space,
enum input_csc_select input_select, struct vpe_csc_matrix *input_cs);
void vpe10_dpp_set_hdr_multiplier(struct dpp *dpp, uint32_t multiplier);
/*Program Scaler*/
void vpe10_dpp_set_segment_scaler(struct dpp *dpp, const struct scaler_data *scl_data);
void vpe10_dpp_set_frame_scaler(struct dpp *dpp, const struct scaler_data *scl_data);
uint32_t vpe10_get_line_buffer_size(void);
bool vpe10_dpp_validate_number_of_taps(struct dpp *dpp, struct scaler_data *scl_data);
void vpe10_dpp_program_crc(struct dpp *dpp, bool enable);
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,182 @@
/* 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 "opp.h"
#include "reg_helper.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OPP_REG_LIST_VPE10(id) \
SRIDFVL(VPFMT_CLAMP_COMPONENT_R, VPFMT, id), SRIDFVL(VPFMT_CLAMP_COMPONENT_G, VPFMT, id), \
SRIDFVL(VPFMT_CLAMP_COMPONENT_B, VPFMT, id), SRIDFVL(VPFMT_DYNAMIC_EXP_CNTL, VPFMT, id), \
SRIDFVL(VPFMT_CONTROL, VPFMT, id), SRIDFVL(VPFMT_BIT_DEPTH_CONTROL, VPFMT, id), \
SRIDFVL(VPFMT_DITHER_RAND_R_SEED, VPFMT, id), \
SRIDFVL(VPFMT_DITHER_RAND_G_SEED, VPFMT, id), \
SRIDFVL(VPFMT_DITHER_RAND_B_SEED, VPFMT, id), SRIDFVL(VPFMT_CLAMP_CNTL, VPFMT, id), \
SRIDFVL(VPOPP_PIPE_CONTROL, VPOPP_PIPE, id), \
SRIDFVL(VPOPP_TOP_CLK_CONTROL, VPOPP_TOP, id), \
SRIDFVL(VPOPP_PIPE_CRC_CONTROL, VPOPP_PIPE_CRC, id),
#define OPP_FIELD_LIST_VPE10(post_fix) \
SFRB(VPFMT_CLAMP_LOWER_R, VPFMT_CLAMP_COMPONENT_R, post_fix), \
SFRB(VPFMT_CLAMP_UPPER_R, VPFMT_CLAMP_COMPONENT_R, post_fix), \
SFRB(VPFMT_CLAMP_LOWER_G, VPFMT_CLAMP_COMPONENT_G, post_fix), \
SFRB(VPFMT_CLAMP_UPPER_G, VPFMT_CLAMP_COMPONENT_G, post_fix), \
SFRB(VPFMT_CLAMP_LOWER_B, VPFMT_CLAMP_COMPONENT_B, post_fix), \
SFRB(VPFMT_CLAMP_UPPER_B, VPFMT_CLAMP_COMPONENT_B, post_fix), \
SFRB(VPFMT_DYNAMIC_EXP_EN, VPFMT_DYNAMIC_EXP_CNTL, post_fix), \
SFRB(VPFMT_DYNAMIC_EXP_MODE, VPFMT_DYNAMIC_EXP_CNTL, 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_CBCR_BIT_REDUCTION_BYPASS, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_DOUBLE_BUFFER_REG_UPDATE_PENDING, VPFMT_CONTROL, post_fix), \
SFRB(VPFMT_TRUNCATE_EN, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_TRUNCATE_MODE, VPFMT_BIT_DEPTH_CONTROL, post_fix), \
SFRB(VPFMT_TRUNCATE_DEPTH, VPFMT_BIT_DEPTH_CONTROL, 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_RAND_R_SEED, VPFMT_DITHER_RAND_R_SEED, post_fix), \
SFRB(VPFMT_OFFSET_R_CR, VPFMT_DITHER_RAND_R_SEED, post_fix), \
SFRB(VPFMT_RAND_G_SEED, VPFMT_DITHER_RAND_G_SEED, post_fix), \
SFRB(VPFMT_OFFSET_G_Y, VPFMT_DITHER_RAND_G_SEED, post_fix), \
SFRB(VPFMT_RAND_B_SEED, VPFMT_DITHER_RAND_B_SEED, post_fix), \
SFRB(VPFMT_OFFSET_B_CB, VPFMT_DITHER_RAND_B_SEED, post_fix), \
SFRB(VPFMT_CLAMP_DATA_EN, VPFMT_CLAMP_CNTL, post_fix), \
SFRB(VPFMT_CLAMP_COLOR_FORMAT, VPFMT_CLAMP_CNTL, post_fix), \
SFRB(VPOPP_PIPE_CLOCK_ON, VPOPP_PIPE_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_DIGITAL_BYPASS_EN, VPOPP_PIPE_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_ALPHA, VPOPP_PIPE_CONTROL, post_fix), \
SFRB(VPOPP_VPECLK_R_GATE_DIS, VPOPP_TOP_CLK_CONTROL, post_fix), \
SFRB(VPOPP_VPECLK_G_GATE_DIS, VPOPP_TOP_CLK_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_CRC_EN, VPOPP_PIPE_CRC_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_CRC_CONT_EN, VPOPP_PIPE_CRC_CONTROL, post_fix), \
SFRB(VPOPP_PIPE_CRC_PIXEL_SELECT, VPOPP_PIPE_CRC_CONTROL, post_fix)
#define OPP_REG_VARIABLE_LIST_VPE10 \
reg_id_val VPFMT_CLAMP_COMPONENT_R; \
reg_id_val VPFMT_CLAMP_COMPONENT_G; \
reg_id_val VPFMT_CLAMP_COMPONENT_B; \
reg_id_val VPFMT_DYNAMIC_EXP_CNTL; \
reg_id_val VPFMT_CONTROL; \
reg_id_val VPFMT_BIT_DEPTH_CONTROL; \
reg_id_val VPFMT_DITHER_RAND_R_SEED; \
reg_id_val VPFMT_DITHER_RAND_G_SEED; \
reg_id_val VPFMT_DITHER_RAND_B_SEED; \
reg_id_val VPFMT_CLAMP_CNTL; \
reg_id_val VPOPP_PIPE_CONTROL; \
reg_id_val VPOPP_TOP_CLK_CONTROL; \
reg_id_val VPOPP_PIPE_CRC_CONTROL;
#define OPP_FIELD_VARIABLE_LIST_VPE10(type) \
type VPFMT_CLAMP_LOWER_R; \
type VPFMT_CLAMP_UPPER_R; \
type VPFMT_CLAMP_LOWER_G; \
type VPFMT_CLAMP_UPPER_G; \
type VPFMT_CLAMP_LOWER_B; \
type VPFMT_CLAMP_UPPER_B; \
type VPFMT_DYNAMIC_EXP_EN; \
type VPFMT_DYNAMIC_EXP_MODE; \
type VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \
type VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \
type VPFMT_CBCR_BIT_REDUCTION_BYPASS; \
type VPFMT_DOUBLE_BUFFER_REG_UPDATE_PENDING; \
type VPFMT_TRUNCATE_EN; \
type VPFMT_TRUNCATE_MODE; \
type VPFMT_TRUNCATE_DEPTH; \
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_RAND_R_SEED; \
type VPFMT_OFFSET_R_CR; \
type VPFMT_RAND_G_SEED; \
type VPFMT_OFFSET_G_Y; \
type VPFMT_RAND_B_SEED; \
type VPFMT_OFFSET_B_CB; \
type VPFMT_CLAMP_DATA_EN; \
type VPFMT_CLAMP_COLOR_FORMAT; \
type VPOPP_PIPE_CLOCK_ON; \
type VPOPP_PIPE_DIGITAL_BYPASS_EN; \
type VPOPP_PIPE_ALPHA; \
type VPOPP_VPECLK_R_GATE_DIS; \
type VPOPP_VPECLK_G_GATE_DIS; \
type VPOPP_PIPE_CRC_EN; \
type VPOPP_PIPE_CRC_CONT_EN; \
type VPOPP_PIPE_CRC_PIXEL_SELECT;
struct vpe10_opp_registers {
OPP_REG_VARIABLE_LIST_VPE10
};
struct vpe10_opp_shift {
OPP_FIELD_VARIABLE_LIST_VPE10(uint8_t)
};
struct vpe10_opp_mask {
OPP_FIELD_VARIABLE_LIST_VPE10(uint32_t)
};
struct vpe10_opp {
struct opp base;
struct vpe10_opp_registers *regs;
const struct vpe10_opp_shift *shift;
const struct vpe10_opp_mask *mask;
};
void vpe10_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp);
enum color_depth vpe10_opp_check_color_depth(enum vpe_surface_pixel_format format);
void vpe10_opp_set_clamping(
struct opp *opp, const struct clamping_and_pixel_encoding_params *params);
void vpe10_opp_set_dyn_expansion(struct opp *opp, bool enable, enum color_depth color_dpth);
void vpe10_opp_set_truncation(struct opp *opp, const struct bit_depth_reduction_params *params);
void vpe10_opp_set_spatial_dither(struct opp *opp, const struct bit_depth_reduction_params *params);
void vpe10_opp_program_bit_depth_reduction(
struct opp *opp, const struct bit_depth_reduction_params *fmt_bit_depth);
void vpe10_opp_program_fmt(struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth,
struct clamping_and_pixel_encoding_params *clamping);
void vpe10_opp_program_pipe_alpha(struct opp *opp, uint16_t alpha);
void vpe10_opp_program_pipe_bypass(struct opp *opp, bool enable);
void vpe10_opp_program_pipe_crc(struct opp *opp, bool enable);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,80 @@
/* 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 "resource.h"
#ifdef __cplusplus
extern "C" {
#endif
enum vpe_status vpe10_construct_resource(struct vpe_priv *vpe_priv, struct resource *res);
void vpe10_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res);
enum vpe_status vpe10_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);
bool vpe10_get_dcc_compression_cap(const struct vpe *vpe, const struct vpe_dcc_surface_param *input,
struct vpe_surface_dcc_cap *output);
bool vpe10_check_input_color_space(struct vpe_priv *vpe_priv, enum vpe_surface_pixel_format format,
const struct vpe_color_space *vcs);
bool vpe10_check_output_color_space(struct vpe_priv *vpe_priv, enum vpe_surface_pixel_format format,
const struct vpe_color_space *vcs);
bool vpe10_check_h_mirror_support(bool *input_mirror, bool *output_mirror);
enum vpe_status vpe10_calculate_segments(
struct vpe_priv *vpe_priv, const struct vpe_build_param *params);
int32_t vpe10_program_frontend(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx,
uint32_t cmd_input_idx, bool seg_only);
int32_t vpe10_program_backend(
struct vpe_priv *vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx, bool seg_only);
enum vpe_status vpe10_populate_cmd_info(struct vpe_priv *vpe_priv);
void vpe10_calculate_dst_viewport_and_active(
struct segment_ctx *segment_ctx, uint32_t max_seg_width);
void vpe10_create_stream_ops_config(struct vpe_priv *vpe_priv, uint32_t pipe_idx,
struct stream_ctx *stream_ctx, struct vpe_cmd_input *cmd_input, enum vpe_cmd_ops ops);
void vpe10_get_bufs_req(struct vpe_priv *vpe_priv, struct vpe_bufs_req *req);
struct opp *vpe10_opp_create(struct vpe_priv *vpe_priv, int inst);
struct mpc *vpe10_mpc_create(struct vpe_priv *vpe_priv, int inst);
struct dpp *vpe10_dpp_create(struct vpe_priv *vpe_priv, int inst);
struct cdc *vpe10_cdc_create(struct vpe_priv *vpe_priv, int inst);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,44 @@
/* 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 "vpec.h"
#ifdef __cplusplus
extern "C" {
#endif
void vpe10_construct_vpec(struct vpe_priv *vpe_priv, struct vpec *vpec);
/** functions for capability check */
bool vpe10_vpec_check_swmode_support(struct vpec *vpec, enum vpe_swizzle_mode_values sw_mode);
bool vpe10_vpec_get_dcc_compression_cap(struct vpec *vpec,
const struct vpe_dcc_surface_param *input, struct vpe_surface_dcc_cap *output);
/** functions for generating command buffer */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,66 @@
/* Copyright 2023 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 "vpe10_background.h"
#include "common.h"
#include "vpe_priv.h"
bool vpe10_split_bg_gap(struct vpe_rect *gaps, const struct vpe_rect *target_rect,
uint32_t max_width, uint16_t max_gaps, uint16_t *num_gaps, uint16_t num_multiple)
{
uint16_t gap_cnt, gap_idx, num_gaps_t;
uint16_t prev_idx = *num_gaps - 1;
uint32_t gap_width, gap_height;
int32_t gap_x, gap_y;
// -1 is for removing the previous "going-to-be" splitted segment
num_gaps_t = *num_gaps - 1;
gap_x = gaps[prev_idx].x;
gap_y = gaps[prev_idx].y;
gap_width = gaps[prev_idx].width;
gap_height = gaps[prev_idx].height;
gap_cnt = (uint16_t)((gap_width + max_width - 1) / max_width);
if (gap_cnt % num_multiple != 0) {
gap_cnt += (num_multiple - (gap_cnt % num_multiple));
max_width = (uint16_t)((gap_width + gap_cnt - 1) / gap_cnt);
}
if (num_gaps_t + gap_cnt > max_gaps)
return false;
for (gap_idx = prev_idx; gap_idx < num_gaps_t + gap_cnt; gap_idx++) {
gaps[gap_idx].y = gap_y;
gaps[gap_idx].height = gap_height;
gaps[gap_idx].x = gap_x;
gaps[gap_idx].width = gap_width < max_width ? gap_width : max_width;
gap_x = gap_x + (int32_t)gaps[gap_idx].width;
gap_width = gap_width - gaps[gap_idx].width;
}
*num_gaps = num_gaps_t + gap_cnt;
return true;
}
+317
View File
@@ -0,0 +1,317 @@
/* 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 "common.h"
#include "vpe_priv.h"
#include "vpe10_cdc.h"
#include "reg_helper.h"
#define CTX_BASE cdc
#define CTX vpe10_cdc
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_funcs cdc_func = {
.check_input_format = vpe10_cdc_check_input_format,
.check_output_format = vpe10_cdc_check_output_format,
.program_surface_config = vpe10_cdc_program_surface_config,
.program_crossbar_config = vpe10_cdc_program_crossbar_config,
.program_global_sync = vpe10_cdc_program_global_sync,
.program_p2b_config = vpe10_cdc_program_p2b_config,
.program_viewport = vpe10_cdc_program_viewport,
};
void vpe10_construct_cdc(struct vpe_priv *vpe_priv, struct cdc *cdc)
{
cdc->vpe_priv = vpe_priv;
cdc->funcs = &cdc_func;
}
bool vpe10_cdc_check_input_format(struct cdc *cdc, enum vpe_surface_pixel_format format)
{
if (vpe_is_32bit_packed_rgb(format))
return true;
if (format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb)
return true;
if (format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr ||
format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb)
return true;
return false;
}
bool vpe10_cdc_check_output_format(struct cdc *cdc, enum vpe_surface_pixel_format format)
{
if (vpe_is_32bit_packed_rgb(format))
return true;
if (vpe_is_fp16(format))
return true;
return false;
}
void vpe10_cdc_program_surface_config(struct cdc *cdc, enum vpe_surface_pixel_format format,
enum vpe_rotation_angle rotation, bool horizontal_mirror, enum vpe_swizzle_mode_values swizzle)
{
uint32_t rotation_angle = 0, surface_linear;
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;
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
surf_format = 1;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
surf_format = 3;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
surf_format = 8;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
surf_format = 9;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
surf_format = 10;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
surf_format = 11;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
surf_format = 22;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: /* use crossbar */
surf_format = 24;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
surf_format = 25;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
surf_format = 65;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
surf_format = 64;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
surf_format = 67;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
surf_format = 66;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888: // use crossbar
surf_format = 12;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
surf_format = 112;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
surf_format = 113;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
surf_format = 114;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
surf_format = 118;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
surf_format = 119;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
default:
vpe_log("cdc: invalid pixel format %d\n", (int)format);
break;
}
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 vpe10_cdc_program_crossbar_config(struct cdc *cdc, 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_AYCbCr8888) {
red_bar = MUX_SEL_CB_B;
blue_bar = MUX_SEL_CR_R;
}
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 vpe10_cdc_program_global_sync(
struct cdc *cdc, 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 vpe10_cdc_program_p2b_config(struct cdc *cdc, enum vpe_surface_pixel_format format)
{
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;
PROGRAM_ENTRY();
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:
p2b_format_sel = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
p2b_format_sel = 1;
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:
p2b_format_sel = 2;
break;
default:
VPE_ASSERT(0);
break;
}
switch (format) {
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_RGBA16161616F:
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:
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:
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;
default:
break;
}
REG_SET_5(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);
}
/** segment specific */
void vpe10_cdc_program_viewport(
struct cdc *cdc, 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);
}
@@ -0,0 +1,674 @@
/* 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 <stdint.h>
#include <string.h>
#include "vpe10_cm_common.h"
#include "custom_float.h"
#include "reg_helper.h"
#define CTX_BASE dpp
#define CTX vpe10_dpp
static bool cm_helper_convert_to_custom_float(struct pwl_result_data *rgb_resulted,
struct curve_points3 *corner_points, uint32_t hw_points_num, bool fixpoint)
{
struct custom_float_format fmt = {0};
struct pwl_result_data *rgb = rgb_resulted;
uint32_t i = 0;
fmt.exponenta_bits = 6;
fmt.mantissa_bits = 12;
fmt.sign = false;
/* corner_points[0] - beginning base, slope offset for R,G,B
* corner_points[1] - end base, slope offset for R,G,B
*/
if (!vpe_convert_to_custom_float_format(
corner_points[0].red.x, &fmt, &corner_points[0].red.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].green.x, &fmt, &corner_points[0].green.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].blue.x, &fmt, &corner_points[0].blue.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].red.offset, &fmt, &corner_points[0].red.custom_float_offset)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].green.offset, &fmt, &corner_points[0].green.custom_float_offset)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].blue.offset, &fmt, &corner_points[0].blue.custom_float_offset)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].red.slope, &fmt, &corner_points[0].red.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].green.slope, &fmt, &corner_points[0].green.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[0].blue.slope, &fmt, &corner_points[0].blue.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (fixpoint == true) {
corner_points[1].red.custom_float_y = vpe_fixpt_clamp_u0d14(corner_points[1].red.y);
corner_points[1].green.custom_float_y = vpe_fixpt_clamp_u0d14(corner_points[1].green.y);
corner_points[1].blue.custom_float_y = vpe_fixpt_clamp_u0d14(corner_points[1].blue.y);
} else {
if (!vpe_convert_to_custom_float_format(
corner_points[1].red.y, &fmt, &corner_points[1].red.custom_float_y)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].green.y, &fmt, &corner_points[1].green.custom_float_y)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].blue.y, &fmt, &corner_points[1].blue.custom_float_y)) {
VPE_ASSERT(0);
return false;
}
}
fmt.mantissa_bits = 10;
fmt.sign = false;
if (!vpe_convert_to_custom_float_format(
corner_points[1].red.x, &fmt, &corner_points[1].red.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].green.x, &fmt, &corner_points[1].green.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].blue.x, &fmt, &corner_points[1].blue.custom_float_x)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].red.slope, &fmt, &corner_points[1].red.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].green.slope, &fmt, &corner_points[1].green.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(
corner_points[1].blue.slope, &fmt, &corner_points[1].blue.custom_float_slope)) {
VPE_ASSERT(0);
return false;
}
if (hw_points_num == 0 || rgb_resulted == NULL || fixpoint == true)
return true;
fmt.mantissa_bits = 12;
while (i != hw_points_num) {
if (!vpe_convert_to_custom_float_format(rgb->red, &fmt, &rgb->red_reg)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(rgb->green, &fmt, &rgb->green_reg)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(rgb->blue, &fmt, &rgb->blue_reg)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(rgb->delta_red, &fmt, &rgb->delta_red_reg)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(rgb->delta_green, &fmt, &rgb->delta_green_reg)) {
VPE_ASSERT(0);
return false;
}
if (!vpe_convert_to_custom_float_format(rgb->delta_blue, &fmt, &rgb->delta_blue_reg)) {
VPE_ASSERT(0);
return false;
}
++rgb;
++i;
}
return true;
}
/* driver uses 32 regions or less, but DCN HW has 34, extra 2 are set to 0 */
#define MAX_REGIONS_NUMBER 34
#define MAX_LOW_POINT 25
#define NUMBER_REGIONS 32
#define NUMBER_SW_SEGMENTS 16
bool vpe10_cm_helper_translate_curve_to_hw_format(
const struct transfer_func *output_tf, struct pwl_params *lut_params, bool fixpoint)
{
struct curve_points3 *corner_points;
struct pwl_result_data *rgb_resulted;
struct pwl_result_data *rgb;
struct pwl_result_data *rgb_plus_1;
struct pwl_result_data *rgb_minus_1;
int32_t region_start, region_end;
int32_t i;
uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS)
return false;
corner_points = lut_params->corner_points;
rgb_resulted = lut_params->rgb_resulted;
hw_points = 0;
memset(lut_params, 0, sizeof(struct pwl_params));
memset(seg_distr, 0, sizeof(seg_distr));
if (output_tf->tf == TRANSFER_FUNC_PQ2084) {
for (i = 0; i < MAX_LOW_POINT; i++)
seg_distr[i] = 3;
// Extra magic point to account for incorrect programming of the lut
seg_distr[i] = 1;
region_start = -MAX_LOW_POINT;
region_end = 1;
} else if (output_tf->tf == TRANSFER_FUNC_LINEAR_0_125) {
int num_regions_linear = MAX_LOW_POINT + 3;
for (i = 0; i < num_regions_linear; i++)
seg_distr[i] = 3;
region_start = -MAX_LOW_POINT;
region_end = 3;
} else {
seg_distr[0] = 3;
seg_distr[1] = 4;
seg_distr[2] = 4;
seg_distr[3] = 4;
seg_distr[4] = 4;
seg_distr[5] = 4;
seg_distr[6] = 4;
seg_distr[7] = 4;
seg_distr[8] = 4;
seg_distr[9] = 4;
seg_distr[10] = 4;
seg_distr[11] = 4;
seg_distr[12] = 1;
region_start = -12;
region_end = 1;
}
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER; i++)
seg_distr[i] = (uint32_t)-1;
for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
if (seg_distr[k] != (uint32_t)-1)
hw_points += (1 << seg_distr[k]);
}
j = 0;
for (k = 0; k < (uint32_t)(region_end - region_start); k++) {
increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
start_index = ((uint32_t)region_start + k + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
for (i = (int32_t)start_index; i < (int32_t)start_index + NUMBER_SW_SEGMENTS;
i += increment) {
if (j == hw_points - 1)
break;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
j++;
}
}
/* last point */
start_index = (uint32_t)((region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS);
rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
// All 3 color channels have same x
corner_points[0].red.x = vpe_fixpt_pow(vpe_fixpt_from_int(2), vpe_fixpt_from_int(region_start));
corner_points[0].green.x = corner_points[0].red.x;
corner_points[0].blue.x = corner_points[0].red.x;
corner_points[1].red.x = vpe_fixpt_pow(vpe_fixpt_from_int(2), vpe_fixpt_from_int(region_end));
corner_points[1].green.x = corner_points[1].red.x;
corner_points[1].blue.x = corner_points[1].red.x;
corner_points[0].red.y = rgb_resulted[0].red;
corner_points[0].green.y = rgb_resulted[0].green;
corner_points[0].blue.y = rgb_resulted[0].blue;
corner_points[0].red.slope = vpe_fixpt_div(corner_points[0].red.y, corner_points[0].red.x);
corner_points[0].green.slope =
vpe_fixpt_div(corner_points[0].green.y, corner_points[0].green.x);
corner_points[0].blue.slope = vpe_fixpt_div(corner_points[0].blue.y, corner_points[0].blue.x);
/* see comment above, m_arrPoints[1].y should be the Y value for the
* region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
*/
corner_points[1].red.y = rgb_resulted[hw_points - 1].red;
corner_points[1].green.y = rgb_resulted[hw_points - 1].green;
corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue;
corner_points[1].red.slope = vpe_fixpt_zero;
corner_points[1].green.slope = vpe_fixpt_zero;
corner_points[1].blue.slope = vpe_fixpt_zero;
lut_params->hw_points_num = hw_points;
k = 0;
for (i = 1; i < MAX_REGIONS_NUMBER; i++) {
if (seg_distr[k] != (uint32_t)-1) {
lut_params->arr_curve_points[k].segments_num = seg_distr[k];
lut_params->arr_curve_points[i].offset =
lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
}
k++;
}
if (seg_distr[k] != (uint32_t)-1)
lut_params->arr_curve_points[k].segments_num = seg_distr[k];
rgb = rgb_resulted;
rgb_plus_1 = rgb_resulted + 1;
rgb_minus_1 = rgb;
i = 1;
while (i != (int32_t)(hw_points + 1)) {
if (i >= (int32_t)(hw_points - 1)) {
if (vpe_fixpt_lt(rgb_plus_1->red, rgb->red))
rgb_plus_1->red = vpe_fixpt_add(rgb->red, rgb_minus_1->delta_red);
if (vpe_fixpt_lt(rgb_plus_1->green, rgb->green))
rgb_plus_1->green = vpe_fixpt_add(rgb->green, rgb_minus_1->delta_green);
if (vpe_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = vpe_fixpt_add(rgb->blue, rgb_minus_1->delta_blue);
}
rgb->delta_red = vpe_fixpt_sub(rgb_plus_1->red, rgb->red);
rgb->delta_green = vpe_fixpt_sub(rgb_plus_1->green, rgb->green);
rgb->delta_blue = vpe_fixpt_sub(rgb_plus_1->blue, rgb->blue);
if (fixpoint == true) {
rgb->delta_red_reg = vpe_fixpt_clamp_u0d10(rgb->delta_red);
rgb->delta_green_reg = vpe_fixpt_clamp_u0d10(rgb->delta_green);
rgb->delta_blue_reg = vpe_fixpt_clamp_u0d10(rgb->delta_blue);
rgb->red_reg = vpe_fixpt_clamp_u0d14(rgb->red);
rgb->green_reg = vpe_fixpt_clamp_u0d14(rgb->green);
rgb->blue_reg = vpe_fixpt_clamp_u0d14(rgb->blue);
}
++rgb_plus_1;
rgb_minus_1 = rgb;
++rgb;
++i;
}
cm_helper_convert_to_custom_float(rgb_resulted, lut_params->corner_points, hw_points, fixpoint);
return true;
}
#define NUM_DEGAMMA_REGIONS 9
#define MAX_REGIONS_NUMBER_DEGAMMA 16
#define MAX_HW_POINTS_DEGAMMA 257
bool vpe10_cm_helper_translate_curve_to_degamma_hw_format(
const struct transfer_func *output_tf, struct pwl_params *lut_params)
{
struct curve_points3 *corner_points;
struct pwl_result_data *rgb_resulted;
struct pwl_result_data *rgb;
struct pwl_result_data *rgb_plus_1;
int32_t region_start, region_end;
int32_t i;
uint32_t k, seg_distr[MAX_REGIONS_NUMBER_DEGAMMA], num_segments, hw_points;
if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS)
return false;
corner_points = lut_params->corner_points;
rgb_resulted = lut_params->rgb_resulted;
num_segments = 0;
memset(lut_params, 0, sizeof(struct pwl_params));
memset(seg_distr, 0, sizeof(seg_distr));
region_start = -NUM_DEGAMMA_REGIONS;
region_end = 0;
for (i = 0; i < MAX_HW_POINTS_DEGAMMA; i++) {
rgb_resulted[i].red = output_tf->tf_pts.red[i];
rgb_resulted[i].green = output_tf->tf_pts.green[i];
rgb_resulted[i].blue = output_tf->tf_pts.blue[i];
}
for (k = (uint32_t)(region_end - region_start); k < MAX_REGIONS_NUMBER_DEGAMMA; k++)
seg_distr[k] = (uint32_t)-1;
/* 9 segments
* segments are from 2^-8 to 0
*/
seg_distr[0] = 0; /* Since we only have one point in last region */
num_segments += 1;
for (k = 1; k < NUM_DEGAMMA_REGIONS; k++) {
seg_distr[k] = k - 1; /* Depends upon the regions' points 2^n; seg_distr = n */
num_segments += (1 << seg_distr[k]);
}
hw_points = num_segments + 1;
corner_points[0].red.x = vpe_fixpt_pow(vpe_fixpt_from_int(2), vpe_fixpt_from_int(region_start));
corner_points[0].green.x = corner_points[0].red.x;
corner_points[0].blue.x = corner_points[0].red.x;
corner_points[0].red.y = rgb_resulted[0].red;
corner_points[0].green.y = rgb_resulted[0].green;
corner_points[0].blue.y = rgb_resulted[0].blue;
corner_points[0].red.slope = vpe_fixpt_div(corner_points[0].red.y, corner_points[0].red.x);
corner_points[0].green.slope = corner_points[0].red.slope;
corner_points[0].blue.slope = corner_points[0].red.slope;
corner_points[1].red.x = vpe_fixpt_pow(vpe_fixpt_from_int(2), vpe_fixpt_from_int(region_end));
corner_points[1].green.x = corner_points[1].red.x;
corner_points[1].blue.x = corner_points[1].red.x;
corner_points[1].red.y = rgb_resulted[num_segments].red;
corner_points[1].green.y = rgb_resulted[num_segments].green;
corner_points[1].blue.y = rgb_resulted[num_segments].blue;
corner_points[1].red.slope = vpe_fixpt_zero;
corner_points[1].green.slope = vpe_fixpt_zero;
corner_points[1].blue.slope = vpe_fixpt_zero;
// The number of HW points is equal to num_segments+1, however due to bug in lower layer, it
// must be set to num_segments
lut_params->hw_points_num = num_segments;
lut_params->arr_curve_points[0].segments_num = seg_distr[0];
for (i = 1; i < NUM_DEGAMMA_REGIONS; i++) {
lut_params->arr_curve_points[i].segments_num = seg_distr[i];
lut_params->arr_curve_points[i].offset =
lut_params->arr_curve_points[i - 1].offset + (1 << seg_distr[i - 1]);
}
if (seg_distr[i] != (uint32_t)-1)
lut_params->arr_curve_points[k].segments_num = seg_distr[k];
rgb = rgb_resulted;
rgb_plus_1 = rgb_resulted + 1;
i = 1;
while (i != (int32_t)(hw_points)) {
if (vpe_fixpt_lt(rgb_plus_1->red, rgb->red))
rgb_plus_1->red = rgb->red;
if (vpe_fixpt_lt(rgb_plus_1->green, rgb->green))
rgb_plus_1->green = rgb->green;
if (vpe_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = rgb->blue;
rgb->delta_red = vpe_fixpt_sub(rgb_plus_1->red, rgb->red);
rgb->delta_green = vpe_fixpt_sub(rgb_plus_1->green, rgb->green);
rgb->delta_blue = vpe_fixpt_sub(rgb_plus_1->blue, rgb->blue);
++rgb_plus_1;
++rgb;
++i;
}
cm_helper_convert_to_custom_float(rgb_resulted, lut_params->corner_points, hw_points, false);
return true;
}
void vpe10_cm_get_tf_pwl_params(
const struct transfer_func *output_tf, struct pwl_params **lut_params, enum cm_type vpe_cm_type)
{
int table_index = 0;
switch (output_tf->tf) {
case TRANSFER_FUNC_SRGB:
table_index = 0;
break;
case TRANSFER_FUNC_BT1886:
table_index = 1;
break;
case TRANSFER_FUNC_PQ2084:
table_index = 2;
break;
case TRANSFER_FUNC_BT709:
case TRANSFER_FUNC_LINEAR_0_125:
table_index = 3;
break;
default:
*lut_params = NULL;
return;
}
*lut_params = &tf_pwl_param_table[vpe_cm_type][table_index];
}
#define REG_FIELD_VALUE_CM(field, value) \
((uint32_t)((value) << reg->shifts.field) & reg->masks.field)
#define REG_FIELD_MASK_CM(field) reg->masks.field
#define REG_SET_CM(reg_offset, init_val, field, val) \
do { \
config_writer_fill( \
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, 0) | \
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, reg_offset)); \
config_writer_fill(config_writer, \
((init_val & ~(REG_FIELD_MASK_CM(field))) | REG_FIELD_VALUE_CM(field, val))); \
} while (0)
#define REG_SET_2_CM(reg_offset, init_val, f1, v1, f2, v2) \
do { \
config_writer_fill( \
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, 0) | \
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, reg_offset)); \
config_writer_fill( \
config_writer, ((init_val & ~(REG_FIELD_MASK_CM(f1)) & ~(REG_FIELD_MASK_CM(f2))) | \
REG_FIELD_VALUE_CM(f1, v1) | REG_FIELD_VALUE_CM(f2, v2))); \
} while (0)
#define REG_SET_4_CM(reg_offset, init_val, f1, v1, f2, v2, f3, v3, f4, v4) \
do { \
config_writer_fill( \
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, 0) | \
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, reg_offset)); \
config_writer_fill( \
config_writer, ((init_val & ~(REG_FIELD_MASK_CM(f1)) & ~(REG_FIELD_MASK_CM(f2)) & \
~(REG_FIELD_MASK_CM(f3)) & ~(REG_FIELD_MASK_CM(f4))) | \
REG_FIELD_VALUE_CM(f1, v1) | REG_FIELD_VALUE_CM(f2, v2) | \
REG_FIELD_VALUE_CM(f3, v3) | REG_FIELD_VALUE_CM(f4, v4))); \
} while (0)
void vpe10_cm_helper_program_gamcor_xfer_func(struct config_writer *config_writer,
const struct pwl_params *params, const struct vpe10_xfer_func_reg *reg)
{
// Total: 13 * 4 + (region_end - region_start + 4) = 13*4 + 68 = 120 bytes
uint32_t reg_region_cur;
unsigned int i = 0;
uint16_t packet_data_size = (uint16_t)((reg->region_end - reg->region_start + 1));
REG_SET_2_CM(reg->start_cntl_b, 0, exp_region_start,
params->corner_points[0].blue.custom_float_x, exp_region_start_segment, 0);
REG_SET_2_CM(reg->start_cntl_g, 0, exp_region_start,
params->corner_points[0].green.custom_float_x, exp_region_start_segment, 0);
REG_SET_2_CM(reg->start_cntl_r, 0, exp_region_start,
params->corner_points[0].red.custom_float_x, exp_region_start_segment, 0);
REG_SET_CM(reg->start_slope_cntl_b, 0, // linear slope at start of curve
field_region_linear_slope, params->corner_points[0].blue.custom_float_slope);
REG_SET_CM(reg->start_slope_cntl_g, 0, field_region_linear_slope,
params->corner_points[0].green.custom_float_slope);
REG_SET_CM(reg->start_slope_cntl_r, 0, field_region_linear_slope,
params->corner_points[0].red.custom_float_slope);
REG_SET_CM(reg->start_end_cntl1_b, 0, field_region_end_base,
params->corner_points[1].blue.custom_float_y);
REG_SET_CM(reg->start_end_cntl1_g, 0, field_region_end_base,
params->corner_points[1].green.custom_float_y);
REG_SET_CM(reg->start_end_cntl1_r, 0, field_region_end_base,
params->corner_points[1].red.custom_float_y);
REG_SET_2_CM(reg->start_end_cntl2_b, 0, field_region_end_slope,
params->corner_points[1].blue.custom_float_slope, field_region_end,
params->corner_points[1].blue.custom_float_x);
REG_SET_2_CM(reg->start_end_cntl2_g, 0, field_region_end_slope,
params->corner_points[1].green.custom_float_slope, field_region_end,
params->corner_points[1].green.custom_float_x);
REG_SET_2_CM(reg->start_end_cntl2_r, 0, field_region_end_slope,
params->corner_points[1].red.custom_float_slope, field_region_end,
params->corner_points[1].red.custom_float_x);
// program all the *GAM_RAM?_REGION_start ~ region_end regs in one VPEP_DIRECT_CONFIG packet
// with auto inc
config_writer_fill(
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, packet_data_size - 1) |
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, reg->region_start) |
0x01); // auto increase on
for (reg_region_cur = reg->region_start; reg_region_cur <= reg->region_end; reg_region_cur++) {
const struct gamma_curve *curve0 = &(params->arr_curve_points[2 * i]);
const struct gamma_curve *curve1 = &(params->arr_curve_points[(2 * i) + 1]);
config_writer_fill(
config_writer, (((curve0->offset << reg->shifts.exp_region0_lut_offset) &
reg->masks.exp_region0_lut_offset) |
((curve0->segments_num << reg->shifts.exp_region0_num_segments) &
reg->masks.exp_region0_num_segments) |
((curve1->offset << reg->shifts.exp_region1_lut_offset) &
reg->masks.exp_region1_lut_offset) |
((curve1->segments_num << reg->shifts.exp_region1_num_segments) &
reg->masks.exp_region1_num_segments)));
i++;
}
}
void vpe10_cm_helper_program_pwl(struct config_writer *config_writer,
const struct pwl_result_data *rgb, uint32_t last_base_value, uint32_t num,
uint32_t lut_data_reg_offset, uint8_t lut_data_reg_shift, uint32_t lut_data_reg_mask,
enum cm_rgb_channel channel)
{
uint32_t i;
uint32_t lut_data = 0;
// For LUT, we keep write the same address with entire LUT data, so don't set INC bit
config_writer_fill(
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, num) |
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, lut_data_reg_offset));
for (i = 0; i < num; i++) {
switch (channel) {
case CM_PWL_R:
lut_data = rgb[i].red_reg;
break;
case CM_PWL_G:
lut_data = rgb[i].green_reg;
break;
case CM_PWL_B:
lut_data = rgb[i].blue_reg;
break;
}
config_writer_fill(config_writer, ((lut_data << lut_data_reg_shift) & lut_data_reg_mask));
}
config_writer_fill(
config_writer, ((last_base_value << lut_data_reg_shift) & lut_data_reg_mask));
}
void vpe10_cm_helper_program_color_matrices(struct config_writer *config_writer,
const uint16_t *regval, const struct color_matrices_reg *reg)
{
uint32_t cur_csc_reg;
unsigned int i = 0;
uint16_t packet_data_size = (uint16_t)((reg->csc_c33_c34 - reg->csc_c11_c12 + 1));
config_writer_fill(
config_writer, VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_DATA_SIZE, packet_data_size - 1) |
VPEC_FIELD_VALUE(VPE_DIR_CFG_PKT_REGISTER_OFFSET, reg->csc_c11_c12) |
0x01); // auto increase on
for (cur_csc_reg = reg->csc_c11_c12; cur_csc_reg <= reg->csc_c33_c34; cur_csc_reg++) {
const uint16_t *regval0 = &(regval[2 * i]);
const uint16_t *regval1 = &(regval[(2 * i) + 1]);
// use C11/C12 mask value for all CSC regs to ease programing
config_writer_fill(
config_writer, ((uint32_t)(*regval0 << reg->shifts.csc_c11) & reg->masks.csc_c11) |
((uint32_t)(*regval1 << reg->shifts.csc_c12) & reg->masks.csc_c12));
// Due to the program nature of CSC regs are switchable to different sets
// Skip record REG_IS_WRITTEN and LAST_WRITTEN_VAL used in REG_SET* macros.
// and those CSC regs will always write at once for all fields
i++;
}
}
@@ -0,0 +1,334 @@
/* 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 "vpe_assert.h"
#include "common.h"
#include "vpe_priv.h"
#include "vpe_command.h"
#include "vpe10_cmd_builder.h"
#include "plane_desc_writer.h"
#include "reg_helper.h"
/***** Internal helpers *****/
static void get_np(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info, int32_t *nps0,
int32_t *nps1, int32_t *npd0, int32_t *npd1);
static enum VPE_PLANE_CFG_ELEMENT_SIZE vpe_get_element_size(
enum vpe_surface_pixel_format format, int plane_idx);
void vpe10_construct_cmd_builder(struct vpe_priv *vpe_priv, struct cmd_builder *builder)
{
builder->build_noops = vpe10_build_noops;
builder->build_vpe_cmd = vpe10_build_vpe_cmd;
builder->build_plane_descriptor = vpe10_build_plane_descriptor;
}
enum vpe_status vpe10_build_noops(struct vpe_priv *vpe_priv, uint32_t **ppbuf, uint32_t num_dwords)
{
uint32_t i;
uint32_t *buffer = *ppbuf;
uint32_t noop = VPE_CMD_HEADER(VPE_CMD_OPCODE_NOP, 0);
for (i = 0; i < num_dwords; i++)
*buffer++ = noop;
*ppbuf = buffer;
return VPE_STATUS_OK;
}
enum vpe_status vpe10_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_buf *emb_buf = &cur_bufs->emb_buf;
struct vpe_cmd_info *cmd_info = &vpe_priv->vpe_cmd_info[cmd_idx];
struct output_ctx *output_ctx;
struct pipe_ctx *pipe_ctx = NULL;
uint32_t i, j;
vpe_desc_writer_init(&vpe_priv->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_priv->vpe_desc_writer, vpe_priv->plane_desc_writer.base_gpu_va, 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);
// frontend programming
for (i = 0; i < cmd_info->num_inputs; i++) {
bool reuse;
struct stream_ctx *stream_ctx;
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
pipe_ctx = vpe_pipe_find_owner(vpe_priv, cmd_info->inputs[i].stream_idx, &reuse);
VPE_ASSERT(pipe_ctx);
if (!reuse) {
vpe_priv->resource.program_frontend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, i, false);
} else {
if (vpe_priv->init.debug.disable_reuse_bit)
reuse = false;
stream_ctx = &vpe_priv->stream_ctx[cmd_info->inputs[i].stream_idx];
// frame specific for same type of command
if (cmd_info->ops == VPE_CMD_OPS_BG)
cmd_type = VPE_CMD_TYPE_BG;
else if (cmd_info->ops == VPE_CMD_OPS_COMPOSITING)
cmd_type = VPE_CMD_TYPE_COMPOSITING;
else if (cmd_info->ops == VPE_CMD_OPS_BG_VSCF_INPUT)
cmd_type = VPE_CMD_TYPE_BG_VSCF_INPUT;
else if (cmd_info->ops == VPE_CMD_OPS_BG_VSCF_OUTPUT)
cmd_type = VPE_CMD_TYPE_BG_VSCF_OUTPUT;
else {
VPE_ASSERT(0);
return VPE_STATUS_ERROR;
}
// follow the same order of config generation in "non-reuse" case
// stream sharing
VPE_ASSERT(stream_ctx->num_configs);
for (j = 0; j < stream_ctx->num_configs; j++) {
vpe_desc_writer_add_config_desc(&vpe_priv->vpe_desc_writer,
stream_ctx->configs[j].config_base_addr, reuse, emb_buf->tmz);
}
// stream-op sharing
for (j = 0; j < stream_ctx->num_stream_op_configs[cmd_type]; j++) {
vpe_desc_writer_add_config_desc(&vpe_priv->vpe_desc_writer,
stream_ctx->stream_op_configs[cmd_type][j].config_base_addr, reuse,
emb_buf->tmz);
}
// command specific
vpe_priv->resource.program_frontend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, i, true);
}
}
VPE_ASSERT(pipe_ctx);
// If config writer has been crashed due to buffer overflow
if (vpe_priv->config_writer.status != VPE_STATUS_OK) {
return vpe_priv->config_writer.status;
}
// backend programming
output_ctx = &vpe_priv->output_ctx;
if (!output_ctx->num_configs) {
vpe_priv->resource.program_backend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, false);
} else {
bool reuse = !vpe_priv->init.debug.disable_reuse_bit;
// re-use output register configs
for (j = 0; j < output_ctx->num_configs; j++) {
vpe_desc_writer_add_config_desc(&vpe_priv->vpe_desc_writer,
output_ctx->configs[j].config_base_addr, reuse, emb_buf->tmz);
}
vpe_priv->resource.program_backend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, true);
}
/* If writer crashed due to buffer overflow */
if (vpe_priv->vpe_desc_writer.status != VPE_STATUS_OK) {
return vpe_priv->vpe_desc_writer.status;
}
vpe_desc_writer_complete(&vpe_priv->vpe_desc_writer);
return VPE_STATUS_OK;
}
enum vpe_status vpe10_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 nps0, nps1, npd0, npd1;
int32_t stream_idx;
struct vpe_cmd_info *cmd_info;
PHYSICAL_ADDRESS_LOC *addrloc;
struct plane_desc_src src;
struct plane_desc_dst dst;
cmd_info = &vpe_priv->vpe_cmd_info[cmd_idx];
VPE_ASSERT(cmd_info->num_inputs == 1);
// obtains number of planes for each source/destination stream
get_np(vpe_priv, cmd_info, &nps0, &nps1, &npd0, &npd1);
plane_desc_writer_init(
&vpe_priv->plane_desc_writer, buf, nps0, npd0, nps1, npd1, VPE_PLANE_CFG_SUBOP_1_TO_1);
stream_idx = cmd_info->inputs[0].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.rotation = stream_ctx->stream.rotation;
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;
src.viewport_x = (uint16_t)cmd_info->inputs[0].scaler_data.viewport.x;
src.viewport_y = (uint16_t)cmd_info->inputs[0].scaler_data.viewport.y;
src.viewport_w = (uint16_t)cmd_info->inputs[0].scaler_data.viewport.width;
src.viewport_h = (uint16_t)cmd_info->inputs[0].scaler_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);
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)cmd_info->inputs[0].scaler_data.viewport_c.x;
src.viewport_y = (uint16_t)cmd_info->inputs[0].scaler_data.viewport_c.y;
src.viewport_w = (uint16_t)cmd_info->inputs[0].scaler_data.viewport_c.width;
src.viewport_h = (uint16_t)cmd_info->inputs[0].scaler_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);
}
} 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)cmd_info->inputs[0].scaler_data.viewport.x;
src.viewport_y = (uint16_t)cmd_info->inputs[0].scaler_data.viewport.y;
src.viewport_w = (uint16_t)cmd_info->inputs[0].scaler_data.viewport.width;
src.viewport_h = (uint16_t)cmd_info->inputs[0].scaler_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);
}
surface_info = &vpe_priv->output_ctx.surface;
VPE_ASSERT(surface_info->address.type == VPE_PLN_ADDR_TYPE_GRAPHICS);
addrloc = &surface_info->address.grph.addr;
dst.tmz = surface_info->address.tmz_surface;
dst.swizzle = surface_info->swizzle;
if (stream_ctx->flip_horizonal_output)
dst.mirror = VPE_MIRROR_HORIZONTAL;
else
dst.mirror = VPE_MIRROR_NONE;
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->dst_viewport.x;
dst.viewport_y = (uint16_t)cmd_info->dst_viewport.y;
dst.viewport_w = (uint16_t)cmd_info->dst_viewport.width;
dst.viewport_h = (uint16_t)cmd_info->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);
return vpe_priv->plane_desc_writer.status;
}
static void get_np(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info, int32_t *nps0,
int32_t *nps1, int32_t *npd0, int32_t *npd1)
{
*npd1 = 0;
if (cmd_info->num_inputs == 1) {
*nps1 = 0;
if (vpe_is_dual_plane_format(
vpe_priv->stream_ctx[cmd_info->inputs[0].stream_idx].stream.surface_info.format))
*nps0 = VPE_PLANE_CFG_TWO_PLANES;
else
*nps0 = VPE_PLANE_CFG_ONE_PLANE;
} else if (cmd_info->num_inputs == 2) {
if (vpe_is_dual_plane_format(
vpe_priv->stream_ctx[cmd_info->inputs[0].stream_idx].stream.surface_info.format))
*nps0 = VPE_PLANE_CFG_TWO_PLANES;
else
*nps0 = VPE_PLANE_CFG_ONE_PLANE;
if (vpe_is_dual_plane_format(
vpe_priv->stream_ctx[cmd_info->inputs[1].stream_idx].stream.surface_info.format))
*nps1 = VPE_PLANE_CFG_TWO_PLANES;
else
*nps1 = VPE_PLANE_CFG_ONE_PLANE;
} else {
*nps0 = 0;
*nps1 = 0;
*npd0 = 0;
return;
}
if (vpe_is_dual_plane_format(vpe_priv->output_ctx.surface.format))
*npd0 = 1;
else
*npd0 = 0;
}
static enum VPE_PLANE_CFG_ELEMENT_SIZE vpe_get_element_size(
enum vpe_surface_pixel_format format, int plane_idx)
{
switch (format) {
// nv12/21
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
if (plane_idx == 0)
return VPE_PLANE_CFG_ELEMENT_SIZE_8BPE;
else
return VPE_PLANE_CFG_ELEMENT_SIZE_16BPE;
// P010
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
if (plane_idx == 0)
return VPE_PLANE_CFG_ELEMENT_SIZE_16BPE;
else
return VPE_PLANE_CFG_ELEMENT_SIZE_32BPE;
// 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:
return VPE_PLANE_CFG_ELEMENT_SIZE_64BPE;
default:
break;
}
return VPE_PLANE_CFG_ELEMENT_SIZE_32BPE;
}
+434
View File
@@ -0,0 +1,434 @@
/* 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 "color.h"
#include "vpe10/inc/vpe10_cm_common.h"
#include "hw_shared.h"
#include "reg_helper.h"
#define CTX_BASE dpp
#define CTX vpe10_dpp
static struct dpp_funcs vpe10_dpp_funcs = {
// cnv
.program_cnv = vpe10_dpp_program_cnv,
.program_pre_dgam = vpe10_dpp_cnv_program_pre_dgam,
.program_cnv_bias_scale = vpe10_dpp_program_cnv_bias_scale,
.program_alpha_keyer = vpe10_dpp_cnv_program_alpha_keyer,
.program_crc = vpe10_dpp_program_crc,
// cm
.program_input_transfer_func = vpe10_dpp_program_input_transfer_func,
.program_gamut_remap = vpe10_dpp_program_gamut_remap,
.program_post_csc = vpe10_dpp_program_post_csc,
.set_hdr_multiplier = vpe10_dpp_set_hdr_multiplier,
// 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 = vpe10_dpp_set_segment_scaler,
.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,
};
void vpe10_construct_dpp(struct vpe_priv *vpe_priv, struct dpp *dpp)
{
dpp->vpe_priv = vpe_priv;
dpp->funcs = &vpe10_dpp_funcs;
}
bool vpe10_dpp_get_optimal_number_of_taps(
struct dpp *dpp, struct scaler_data *scl_data, const struct vpe_scaling_taps *in_taps)
{
struct vpe_priv *vpe_priv = dpp->vpe_priv;
uint32_t h_taps_min = 0, v_taps_min = 0;
/*
* Set default taps if none are provided
* From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling
* taps = 4 for upscaling
*/
if (in_taps->h_taps > 8 || in_taps->v_taps > 8 || in_taps->h_taps_c > 8 ||
in_taps->v_taps_c > 8)
return false;
if (vpe_fixpt_ceil(scl_data->ratios.horz) > 1)
h_taps_min = (uint32_t)max(4, min(2 * vpe_fixpt_ceil(scl_data->ratios.horz), 8));
else
h_taps_min = (uint32_t)4;
if (in_taps->h_taps == 0) {
scl_data->taps.h_taps = h_taps_min;
} else {
if (in_taps->h_taps < h_taps_min)
return false;
scl_data->taps.h_taps = in_taps->h_taps;
}
if (vpe_fixpt_ceil(scl_data->ratios.vert) > 1)
v_taps_min =
(uint32_t)max(4, min(vpe_fixpt_ceil(vpe_fixpt_mul_int(scl_data->ratios.vert, 2)), 8));
else
v_taps_min = (uint32_t)4;
if (in_taps->v_taps == 0) {
scl_data->taps.v_taps = v_taps_min;
} else {
if (in_taps->v_taps < v_taps_min)
return false;
scl_data->taps.v_taps = in_taps->v_taps;
}
if (in_taps->h_taps_c == 0) {
// default to 2 as mmd only uses bilinear for chroma
scl_data->taps.h_taps_c = (uint32_t)2;
} else
scl_data->taps.h_taps_c = in_taps->h_taps_c;
if (in_taps->v_taps_c == 0) {
// default to 2 as mmd only uses bilinear for chroma
scl_data->taps.v_taps_c = (uint32_t)2;
} else
scl_data->taps.v_taps_c = in_taps->v_taps_c;
/* taps can be either 1 or an even number */
if (scl_data->taps.h_taps % 2 && scl_data->taps.h_taps != 1)
scl_data->taps.h_taps++;
if (scl_data->taps.v_taps % 2 && scl_data->taps.v_taps != 1)
scl_data->taps.v_taps++;
if (scl_data->taps.h_taps_c % 2 && scl_data->taps.h_taps_c != 1)
scl_data->taps.h_taps_c++;
if (scl_data->taps.v_taps_c % 2 && scl_data->taps.v_taps_c != 1)
scl_data->taps.v_taps_c++;
// bypass scaler if all ratios are 1
if (IDENTITY_RATIO(scl_data->ratios.horz))
scl_data->taps.h_taps = 1;
if (IDENTITY_RATIO(scl_data->ratios.vert))
scl_data->taps.v_taps = 1;
return true;
}
void vpe10_dscl_calc_lb_num_partitions(const struct scaler_data *scl_data,
enum lb_memory_config lb_config, uint32_t *num_part_y, uint32_t *num_part_c)
{
uint32_t memory_line_size_y, memory_line_size_c, memory_line_size_a, lb_memory_size,
lb_memory_size_c, lb_memory_size_a, num_partitions_a;
uint32_t line_size = scl_data->viewport.width < scl_data->recout.width
? scl_data->viewport.width
: scl_data->recout.width;
uint32_t line_size_c = scl_data->viewport_c.width < scl_data->recout.width
? scl_data->viewport_c.width
: scl_data->recout.width;
if (line_size == 0)
line_size = 1;
if (line_size_c == 0)
line_size_c = 1;
memory_line_size_y = (line_size + 5) / 6; /* +5 to ceil */
memory_line_size_c = (line_size_c + 5) / 6; /* +5 to ceil */
memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
// only has 1-piece lb config in vpe1
lb_memory_size = 696;
lb_memory_size_c = 696;
lb_memory_size_a = 696;
*num_part_y = lb_memory_size / memory_line_size_y;
*num_part_c = lb_memory_size_c / memory_line_size_c;
num_partitions_a = lb_memory_size_a / memory_line_size_a;
if (scl_data->lb_params.alpha_en && (num_partitions_a < *num_part_y))
*num_part_y = num_partitions_a;
if (*num_part_y > 12)
*num_part_y = 12;
if (*num_part_c > 12)
*num_part_c = 12;
}
/* Not used as we don't enable prealpha dealpha currently
* Can skip for optimize performance and use default val
*/
static void vpe10_dpp_program_prealpha_dealpha(struct dpp *dpp)
{
uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
uint32_t realpha_en = 0, realpha_ablnd_en = 0;
uint32_t program_prealpha_dealpha = 0;
PROGRAM_ENTRY();
if (program_prealpha_dealpha) {
dealpha_en = 1;
realpha_en = 1;
}
REG_SET_2(
VPCNVC_PRE_DEALPHA, 0, PRE_DEALPHA_EN, dealpha_en, PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
REG_SET_2(
VPCNVC_PRE_REALPHA, 0, PRE_REALPHA_EN, realpha_en, PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
}
/* Not used as we don't have special 2bit LUt currently
* Can skip for optimize performance and use default val
*/
static void vpe10_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_4(VPCNVC_ALPHA_2BIT_LUT, 0, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0, ALPHA_2BIT_LUT1,
alpha_2bit_lut->lut1, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2, ALPHA_2BIT_LUT3,
alpha_2bit_lut->lut3);
} else { // restore to default
REG_SET_DEFAULT(VPCNVC_ALPHA_2BIT_LUT);
}
}
void vpe10_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:
alpha_en = 0;
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:
alpha_en = 0;
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_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
pixel_format = 12;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
pixel_format = 64;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
pixel_format = 65;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
pixel_format = 66;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
pixel_format = 67;
alpha_en = 0;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
pixel_format = 22;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
pixel_format = 24;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
pixel_format = 25;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
pixel_format = 114;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
pixel_format = 115;
break;
default:
break;
}
REG_SET(VPCNVC_SURFACE_PIXEL_FORMAT, 0, VPCNVC_SURFACE_PIXEL_FORMAT, pixel_format);
REG_SET_7(VPCNVC_FORMAT_CONTROL, 0, 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);
}
void vpe10_dpp_program_cnv_bias_scale(struct dpp *dpp, struct bias_and_scale *bias_and_scale)
{
PROGRAM_ENTRY();
REG_SET(VPCNVC_FCNV_FP_BIAS_R, 0, FCNV_FP_BIAS_R, bias_and_scale->bias_red);
REG_SET(VPCNVC_FCNV_FP_BIAS_G, 0, FCNV_FP_BIAS_G, bias_and_scale->bias_green);
REG_SET(VPCNVC_FCNV_FP_BIAS_B, 0, FCNV_FP_BIAS_B, bias_and_scale->bias_blue);
REG_SET(VPCNVC_FCNV_FP_SCALE_R, 0, FCNV_FP_SCALE_R, bias_and_scale->scale_red);
REG_SET(VPCNVC_FCNV_FP_SCALE_G, 0, FCNV_FP_SCALE_G, bias_and_scale->scale_green);
REG_SET(VPCNVC_FCNV_FP_SCALE_B, 0, FCNV_FP_SCALE_B, bias_and_scale->scale_blue);
}
void vpe10_dpp_cnv_program_pre_dgam(struct dpp *dpp, enum color_transfer_func tr)
{
int pre_degam_en = 1;
int degamma_lut_selection = 0;
PROGRAM_ENTRY();
switch (tr) {
case TRANSFER_FUNC_LINEAR_0_125:
pre_degam_en = 0; // bypass
break;
case TRANSFER_FUNC_SRGB:
degamma_lut_selection = 0;
break;
case TRANSFER_FUNC_BT709:
degamma_lut_selection = 4;
break;
case TRANSFER_FUNC_PQ2084:
degamma_lut_selection = 5;
break;
default:
pre_degam_en = 0;
break;
}
REG_SET_2(
VPCNVC_PRE_DEGAM, 0, PRE_DEGAM_MODE, pre_degam_en, PRE_DEGAM_SELECT, degamma_lut_selection);
}
void vpe10_dpp_cnv_program_alpha_keyer(struct dpp *dpp, struct cnv_color_keyer_params *color_keyer)
{
PROGRAM_ENTRY();
REG_SET_2(VPCNVC_COLOR_KEYER_CONTROL, 0, COLOR_KEYER_EN, color_keyer->color_keyer_en,
COLOR_KEYER_MODE, color_keyer->color_keyer_mode);
REG_SET_2(VPCNVC_COLOR_KEYER_ALPHA, 0, COLOR_KEYER_ALPHA_LOW,
color_keyer->color_keyer_alpha_low, COLOR_KEYER_ALPHA_HIGH,
color_keyer->color_keyer_alpha_high);
REG_SET_2(VPCNVC_COLOR_KEYER_RED, 0, COLOR_KEYER_RED_LOW, color_keyer->color_keyer_red_low,
COLOR_KEYER_RED_HIGH, color_keyer->color_keyer_red_high);
REG_SET_2(VPCNVC_COLOR_KEYER_GREEN, 0, COLOR_KEYER_GREEN_LOW,
color_keyer->color_keyer_green_low, COLOR_KEYER_GREEN_HIGH,
color_keyer->color_keyer_green_high);
REG_SET_2(VPCNVC_COLOR_KEYER_BLUE, 0, COLOR_KEYER_BLUE_LOW, color_keyer->color_keyer_blue_low,
COLOR_KEYER_BLUE_HIGH, color_keyer->color_keyer_blue_high);
}
uint32_t vpe10_get_line_buffer_size()
{
return MAX_LINE_SIZE * MAX_LINE_CNT;
}
bool vpe10_dpp_validate_number_of_taps(struct dpp *dpp, struct scaler_data *scl_data)
{
uint32_t num_part_y, num_part_c;
uint32_t max_taps_y, max_taps_c;
uint32_t min_taps_y, min_taps_c;
/*Ensure we can support the requested number of vtaps*/
min_taps_y = (uint32_t)vpe_fixpt_ceil(scl_data->ratios.vert);
min_taps_c = (uint32_t)vpe_fixpt_ceil(scl_data->ratios.vert_c);
dpp->funcs->dscl_calc_lb_num_partitions(scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
/* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */
if (vpe_fixpt_ceil(scl_data->ratios.vert) > 2)
max_taps_y = num_part_y - ((uint32_t)vpe_fixpt_ceil(scl_data->ratios.vert) - 2);
else
max_taps_y = num_part_y;
if (vpe_fixpt_ceil(scl_data->ratios.vert_c) > 2)
max_taps_c = num_part_c - ((uint32_t)vpe_fixpt_ceil(scl_data->ratios.vert_c) - 2);
else
max_taps_c = num_part_c;
if (max_taps_y < min_taps_y)
return false;
else if (max_taps_c < min_taps_c)
return false;
if (scl_data->taps.v_taps > max_taps_y)
scl_data->taps.v_taps = max_taps_y;
if (scl_data->taps.v_taps_c > max_taps_c)
scl_data->taps.v_taps_c = max_taps_c;
if (IDENTITY_RATIO(scl_data->ratios.vert))
scl_data->taps.v_taps = 1;
if (scl_data->taps.v_taps % 2 && scl_data->taps.v_taps != 1)
scl_data->taps.v_taps++;
if (scl_data->taps.v_taps_c % 2 && scl_data->taps.v_taps_c != 1)
scl_data->taps.v_taps_c++;
return true;
}
void vpe10_dpp_program_crc(struct dpp *dpp, bool enable)
{
PROGRAM_ENTRY();
REG_UPDATE(VPDPP_CRC_CTRL, VPDPP_CRC_EN, enable);
}
@@ -0,0 +1,289 @@
#include "vpe_priv.h"
#include "reg_helper.h"
#include "vpe10/inc/vpe10_cm_common.h"
#include "vpe10_dpp.h"
#include "conversion.h"
#include "color_pwl.h"
#define CTX vpe10_dpp
#define CTX_BASE dpp
static void vpe10_enable_cm_block(struct dpp *dpp)
{
unsigned int cm_bypass_mode = 0;
PROGRAM_ENTRY();
// debug option: put CM in bypass mode
if (vpe_priv->init.debug.cm_in_bypass)
cm_bypass_mode = 1;
REG_SET(VPCM_CONTROL, 0, VPCM_BYPASS, cm_bypass_mode);
}
static void vpe10_power_on_gamcor_lut(struct dpp *dpp, bool power_on)
{
PROGRAM_ENTRY();
if (vpe_priv->init.debug.enable_mem_low_power.bits.cm) {
if (power_on) {
REG_SET_2(VPCM_MEM_PWR_CTRL, REG_DEFAULT(VPCM_MEM_PWR_CTRL), GAMCOR_MEM_PWR_DIS, 0,
GAMCOR_MEM_PWR_FORCE, 0);
// two dummy updates (10-15clks each) for wake up delay
REG_SET_2(VPCM_MEM_PWR_CTRL, REG_DEFAULT(VPCM_MEM_PWR_CTRL), GAMCOR_MEM_PWR_DIS, 0,
GAMCOR_MEM_PWR_FORCE, 0);
REG_SET_2(VPCM_MEM_PWR_CTRL, REG_DEFAULT(VPCM_MEM_PWR_CTRL), GAMCOR_MEM_PWR_DIS, 0,
GAMCOR_MEM_PWR_FORCE, 0);
} else {
REG_SET_2(VPCM_MEM_PWR_CTRL, REG_DEFAULT(VPCM_MEM_PWR_CTRL), GAMCOR_MEM_PWR_DIS, 0,
GAMCOR_MEM_PWR_FORCE, 3);
}
} else {
REG_SET_2(VPCM_MEM_PWR_CTRL, REG_DEFAULT(VPCM_MEM_PWR_CTRL), GAMCOR_MEM_PWR_DIS,
power_on == true ? 1 : 0, GAMCOR_MEM_PWR_FORCE, 0);
}
}
static void vpe10_configure_gamcor_lut(struct dpp *dpp)
{
PROGRAM_ENTRY();
REG_SET(VPCM_GAMCOR_LUT_CONTROL, 0, VPCM_GAMCOR_LUT_WRITE_COLOR_MASK, 7);
REG_SET(VPCM_GAMCOR_LUT_INDEX, 0, VPCM_GAMCOR_LUT_INDEX, 0);
}
static void vpe10_dpp_gamcor_reg_field(struct dpp *dpp, struct vpe10_xfer_func_reg *reg)
{
struct vpe10_dpp *vpe10_dpp = (struct vpe10_dpp *)dpp;
reg->shifts.field_region_start_base =
vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_B;
reg->masks.field_region_start_base = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_START_BASE_B;
reg->shifts.field_offset = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_OFFSET_B;
reg->masks.field_offset = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_OFFSET_B;
reg->shifts.exp_region0_lut_offset = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET;
reg->masks.exp_region0_lut_offset = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET;
reg->shifts.exp_region0_num_segments =
vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->masks.exp_region0_num_segments =
vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->shifts.exp_region1_lut_offset = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET;
reg->masks.exp_region1_lut_offset = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET;
reg->shifts.exp_region1_num_segments =
vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->masks.exp_region1_num_segments =
vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->shifts.field_region_end = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_END_B;
reg->masks.field_region_end = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_END_B;
reg->shifts.field_region_end_slope = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B;
reg->masks.field_region_end_slope = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B;
reg->shifts.field_region_end_base = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_B;
reg->masks.field_region_end_base = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_END_BASE_B;
reg->shifts.field_region_linear_slope =
vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B;
reg->masks.field_region_linear_slope =
vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B;
reg->shifts.exp_region_start = vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_START_B;
reg->masks.exp_region_start = vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_START_B;
reg->shifts.exp_region_start_segment =
vpe10_dpp->shift->VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B;
reg->masks.exp_region_start_segment =
vpe10_dpp->mask->VPCM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B;
}
static void vpe10_dpp_program_gammcor_lut(
struct dpp *dpp, const struct pwl_result_data *rgb, uint32_t num)
{
uint32_t last_base_value_red = rgb[num].red_reg;
uint32_t last_base_value_green = rgb[num].blue_reg;
uint32_t last_base_value_blue = rgb[num].green_reg;
PROGRAM_ENTRY();
/*fill in the LUT with all base values to be used by pwl module
* HW auto increments the LUT index: back-to-back write
*/
if (vpe_is_rgb_equal(rgb, num)) {
vpe10_cm_helper_program_pwl(config_writer, rgb, last_base_value_red, num,
REG_OFFSET(VPCM_GAMCOR_LUT_DATA), REG_FIELD_SHIFT(VPCM_GAMCOR_LUT_DATA),
REG_FIELD_MASK(VPCM_GAMCOR_LUT_DATA), CM_PWL_R);
} else {
REG_UPDATE(VPCM_GAMCOR_LUT_CONTROL, VPCM_GAMCOR_LUT_WRITE_COLOR_MASK, 4);
vpe10_cm_helper_program_pwl(config_writer, rgb, last_base_value_red, num,
REG_OFFSET(VPCM_GAMCOR_LUT_DATA), REG_FIELD_SHIFT(VPCM_GAMCOR_LUT_DATA),
REG_FIELD_MASK(VPCM_GAMCOR_LUT_DATA), CM_PWL_R);
REG_SET(VPCM_GAMCOR_LUT_INDEX, 0, VPCM_GAMCOR_LUT_INDEX, 0);
REG_UPDATE(VPCM_GAMCOR_LUT_CONTROL, VPCM_GAMCOR_LUT_WRITE_COLOR_MASK, 2);
vpe10_cm_helper_program_pwl(config_writer, rgb, last_base_value_green, num,
REG_OFFSET(VPCM_GAMCOR_LUT_DATA), REG_FIELD_SHIFT(VPCM_GAMCOR_LUT_DATA),
REG_FIELD_MASK(VPCM_GAMCOR_LUT_DATA), CM_PWL_G);
REG_SET(VPCM_GAMCOR_LUT_INDEX, 0, VPCM_GAMCOR_LUT_INDEX, 0);
REG_UPDATE(VPCM_GAMCOR_LUT_CONTROL, VPCM_GAMCOR_LUT_WRITE_COLOR_MASK, 1);
vpe10_cm_helper_program_pwl(config_writer, rgb, last_base_value_blue, num,
REG_OFFSET(VPCM_GAMCOR_LUT_DATA), REG_FIELD_SHIFT(VPCM_GAMCOR_LUT_DATA),
REG_FIELD_MASK(VPCM_GAMCOR_LUT_DATA), CM_PWL_B);
}
}
static void vpe10_dpp_program_gamcor_lut(struct dpp *dpp, const struct pwl_params *params)
{
struct vpe10_xfer_func_reg gam_regs = {0};
PROGRAM_ENTRY();
vpe10_enable_cm_block(dpp);
if (dpp->vpe_priv->init.debug.bypass_gamcor || params == NULL) {
// bypass
REG_SET(VPCM_GAMCOR_CONTROL, 0, VPCM_GAMCOR_MODE, 0);
vpe10_power_on_gamcor_lut(dpp, false);
return;
}
vpe10_power_on_gamcor_lut(dpp, true);
vpe10_configure_gamcor_lut(dpp);
REG_SET(VPCM_GAMCOR_CONTROL, 0, VPCM_GAMCOR_MODE, 2); // programmable RAM
gam_regs.start_cntl_b = REG_OFFSET(VPCM_GAMCOR_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG_OFFSET(VPCM_GAMCOR_RAMA_START_CNTL_G);
gam_regs.start_cntl_r = REG_OFFSET(VPCM_GAMCOR_RAMA_START_CNTL_R);
gam_regs.start_slope_cntl_b = REG_OFFSET(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_B);
gam_regs.start_slope_cntl_g = REG_OFFSET(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_G);
gam_regs.start_slope_cntl_r = REG_OFFSET(VPCM_GAMCOR_RAMA_START_SLOPE_CNTL_R);
gam_regs.start_end_cntl1_b = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL1_B);
gam_regs.start_end_cntl2_b = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL2_B);
gam_regs.start_end_cntl1_g = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL1_G);
gam_regs.start_end_cntl2_g = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL2_G);
gam_regs.start_end_cntl1_r = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL1_R);
gam_regs.start_end_cntl2_r = REG_OFFSET(VPCM_GAMCOR_RAMA_END_CNTL2_R);
gam_regs.region_start = REG_OFFSET(VPCM_GAMCOR_RAMA_REGION_0_1);
gam_regs.region_end = REG_OFFSET(VPCM_GAMCOR_RAMA_REGION_32_33);
gam_regs.offset_b = REG_OFFSET(VPCM_GAMCOR_RAMA_OFFSET_B);
gam_regs.offset_g = REG_OFFSET(VPCM_GAMCOR_RAMA_OFFSET_G);
gam_regs.offset_r = REG_OFFSET(VPCM_GAMCOR_RAMA_OFFSET_R);
gam_regs.start_base_cntl_b = REG_OFFSET(VPCM_GAMCOR_RAMA_START_BASE_CNTL_B);
gam_regs.start_base_cntl_g = REG_OFFSET(VPCM_GAMCOR_RAMA_START_BASE_CNTL_G);
gam_regs.start_base_cntl_r = REG_OFFSET(VPCM_GAMCOR_RAMA_START_BASE_CNTL_R);
vpe10_dpp_gamcor_reg_field(dpp, &gam_regs);
vpe10_cm_helper_program_gamcor_xfer_func(config_writer, params, &gam_regs);
vpe10_dpp_program_gammcor_lut(dpp, params->rgb_resulted, params->hw_points_num);
}
void vpe10_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf)
{
struct pwl_params *params = NULL;
PROGRAM_ENTRY();
// There should always have input_tf
VPE_ASSERT(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) {
if (!input_tf->use_pre_calculated_table || dpp->vpe_priv->init.debug.force_tf_calculation) {
vpe10_cm_helper_translate_curve_to_degamma_hw_format(input_tf, &dpp->degamma_params);
params = &dpp->degamma_params;
} else {
vpe10_cm_get_tf_pwl_params(input_tf, &params, CM_DEGAM);
VPE_ASSERT(params != NULL);
if (params == NULL)
return;
}
}
vpe10_dpp_program_gamcor_lut(dpp, params);
}
void vpe10_dpp_program_gamut_remap(struct dpp *dpp, struct colorspace_transform *gamut_remap)
{
struct color_matrices_reg gam_regs;
uint16_t arr_reg_val[12];
PROGRAM_ENTRY();
if (!gamut_remap || !gamut_remap->enable_remap ||
dpp->vpe_priv->init.debug.bypass_dpp_gamut_remap) {
REG_SET(VPCM_GAMUT_REMAP_CONTROL, 0, VPCM_GAMUT_REMAP_MODE, 0);
return;
}
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPCM_GAMUT_REMAP_C11);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPCM_GAMUT_REMAP_C11);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPCM_GAMUT_REMAP_C12);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPCM_GAMUT_REMAP_C12);
gam_regs.csc_c11_c12 = REG_OFFSET(VPCM_GAMUT_REMAP_C11_C12);
gam_regs.csc_c33_c34 = REG_OFFSET(VPCM_GAMUT_REMAP_C33_C34);
conv_convert_float_matrix(arr_reg_val, gamut_remap->matrix, 12);
vpe10_cm_helper_program_color_matrices(config_writer, arr_reg_val, &gam_regs);
REG_SET(VPCM_GAMUT_REMAP_CONTROL, 0, VPCM_GAMUT_REMAP_MODE, 1);
}
/*program post scaler scs block in dpp CM*/
void vpe10_dpp_program_post_csc(struct dpp *dpp, enum color_space color_space,
enum input_csc_select input_select, struct vpe_csc_matrix *input_cs)
{
PROGRAM_ENTRY();
int i;
int arr_size = sizeof(vpe_input_csc_matrix_fixed) / sizeof(struct vpe_csc_matrix);
const uint16_t *regval = NULL;
struct color_matrices_reg gam_regs;
if (input_select == INPUT_CSC_SELECT_BYPASS || dpp->vpe_priv->init.debug.bypass_post_csc) {
REG_SET(VPCM_POST_CSC_CONTROL, 0, VPCM_POST_CSC_MODE, 0);
return;
}
if (input_cs == NULL) {
for (i = 0; i < arr_size; i++)
if (vpe_input_csc_matrix_fixed[i].cs == color_space) {
regval = vpe_input_csc_matrix_fixed[i].regval;
break;
}
if (regval == NULL) {
VPE_ASSERT(0);
return;
}
} else {
regval = input_cs->regval;
}
/* Always use the only one set of CSC matrix
*/
gam_regs.shifts.csc_c11 = REG_FIELD_SHIFT(VPCM_POST_CSC_C11);
gam_regs.masks.csc_c11 = REG_FIELD_MASK(VPCM_POST_CSC_C11);
gam_regs.shifts.csc_c12 = REG_FIELD_SHIFT(VPCM_POST_CSC_C12);
gam_regs.masks.csc_c12 = REG_FIELD_MASK(VPCM_POST_CSC_C12);
gam_regs.csc_c11_c12 = REG_OFFSET(VPCM_POST_CSC_C11_C12);
gam_regs.csc_c33_c34 = REG_OFFSET(VPCM_POST_CSC_C33_C34);
vpe10_cm_helper_program_color_matrices(config_writer, regval, &gam_regs);
REG_SET(VPCM_POST_CSC_CONTROL, 0, VPCM_POST_CSC_MODE, input_select);
}
void vpe10_dpp_set_hdr_multiplier(struct dpp *dpp, uint32_t multiplier)
{
PROGRAM_ENTRY();
REG_SET(VPCM_HDR_MULT_COEF, REG_DEFAULT(VPCM_HDR_MULT_COEF), VPCM_HDR_MULT_COEF, multiplier);
}
@@ -0,0 +1,383 @@
/* 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 "vpe_priv.h"
#include "vpe10_dpp.h"
#define CTX vpe10_dpp
#define CTX_BASE dpp
#define NUM_PHASES 64
#define HORZ_MAX_TAPS 8
#define VERT_MAX_TAPS 8
#define LB_MAX_PARTITION 12
enum vpe10_coef_filter_type_sel {
SCL_COEF_LUMA_VERT_FILTER = 0,
SCL_COEF_LUMA_HORZ_FILTER = 1,
SCL_COEF_CHROMA_VERT_FILTER = 2,
SCL_COEF_CHROMA_HORZ_FILTER = 3,
SCL_COEF_ALPHA_VERT_FILTER = 4,
SCL_COEF_ALPHA_HORZ_FILTER = 5
};
enum dscl_autocal_mode {
AUTOCAL_MODE_OFF = 0,
/* Autocal calculate the scaling ratio and initial phase and the
* DSCL_MODE_SEL must be set to 1
*/
AUTOCAL_MODE_AUTOSCALE = 1,
/* Autocal perform auto centering without replication and the
* DSCL_MODE_SEL must be set to 0
*/
AUTOCAL_MODE_AUTOCENTER = 2,
/* Autocal perform auto centering and auto replication and the
* DSCL_MODE_SEL must be set to 0
*/
AUTOCAL_MODE_AUTOREPLICATE = 3
};
enum dscl_mode_sel {
DSCL_MODE_SCALING_444_BYPASS = 0,
DSCL_MODE_SCALING_444_RGB_ENABLE = 1,
DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2,
DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3,
DSCL_MODE_SCALING_420_LUMA_BYPASS = 4,
DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5,
DSCL_MODE_DSCL_BYPASS = 6
};
static bool dpp1_dscl_is_ycbcr(const enum vpe_surface_pixel_format format)
{
return format >= VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN &&
format <= VPE_SURFACE_PIXEL_FORMAT_VIDEO_END;
}
static bool dpp1_dscl_is_video_subsampled(const enum vpe_surface_pixel_format format)
{
return (format >= VPE_SURFACE_PIXEL_FORMAT_VIDEO_BEGIN &&
format <= VPE_SURFACE_PIXEL_FORMAT_SUBSAMPLE_END);
}
static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(const struct scaler_data *data)
{
// TODO Check if bypass bit enabled
const long long one = vpe_fixpt_one.value;
if (data->ratios.horz.value == one && data->ratios.vert.value == one &&
data->ratios.horz_c.value == one && data->ratios.vert_c.value == one)
return DSCL_MODE_DSCL_BYPASS;
if (!dpp1_dscl_is_ycbcr(data->format))
return DSCL_MODE_SCALING_444_RGB_ENABLE;
if (!dpp1_dscl_is_video_subsampled(data->format))
return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
if (data->ratios.horz.value == one && data->ratios.vert.value == one)
return DSCL_MODE_SCALING_420_LUMA_BYPASS;
return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
}
static void dpp1_dscl_set_dscl_mode(struct dpp *dpp, enum dscl_mode_sel dscl_mode)
{
PROGRAM_ENTRY();
REG_SET(VPDSCL_MODE, 0, VPDSCL_MODE, dscl_mode);
}
static void dpp1_dscl_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 dpp1_dscl_set_mpc_size(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
REG_SET_2(VPMPC_SIZE, 0, VPMPC_WIDTH, scl_data->h_active, VPMPC_HEIGHT, scl_data->v_active);
}
static void dpp1_dscl_set_h_blank(struct dpp *dpp, uint16_t start, uint16_t end)
{
PROGRAM_ENTRY();
REG_SET_2(VPOTG_H_BLANK, 0, OTG_H_BLANK_END, end, OTG_H_BLANK_START, start);
}
static void dpp1_dscl_set_v_blank(struct dpp *dpp, uint16_t start, uint16_t end)
{
PROGRAM_ENTRY();
REG_SET_2(VPOTG_V_BLANK, 0, OTG_V_BLANK_END, end, OTG_V_BLANK_START, start);
}
static void dpp1_dscl_set_taps(struct dpp *dpp, const struct scaler_data *scl_data)
{
PROGRAM_ENTRY();
REG_SET_4(VPDSCL_TAP_CONTROL, 0, 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);
}
static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
{
if (taps == 8)
return vpe_get_filter_8tap_64p(ratio);
else if (taps == 6)
return vpe_get_filter_6tap_64p(ratio);
else if (taps == 4)
return vpe_get_filter_4tap_64p(ratio);
else if (taps == 2)
return vpe_get_2tap_bilinear_64p();
else if (taps == 1)
return NULL;
else {
/* should never happen, bug */
return NULL;
}
}
static void dpp1_dscl_set_scaler_filter(struct dpp *dpp, uint32_t taps,
enum vpe10_coef_filter_type_sel filter_type, const uint16_t *filter)
{
const int tap_pairs = (taps + 1) / 2;
int phase;
int pair;
uint16_t odd_coef, even_coef;
PROGRAM_ENTRY();
REG_SET_3(VPDSCL_COEF_RAM_TAP_SELECT, 0, SCL_COEF_RAM_TAP_PAIR_IDX, 0, SCL_COEF_RAM_PHASE, 0,
SCL_COEF_RAM_FILTER_TYPE, filter_type);
for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) {
for (pair = 0; pair < tap_pairs; pair++) {
even_coef = filter[phase * (int)taps + 2 * pair];
if ((pair * 2 + 1) < (int)taps)
odd_coef = filter[phase * (int)taps + 2 * pair + 1];
else
odd_coef = 0;
REG_SET_4(VPDSCL_COEF_RAM_TAP_DATA, 0,
/* Even tap coefficient (bits 1:0 fixed to 0) */
SCL_COEF_RAM_EVEN_TAP_COEF, even_coef,
/* Write/read control for even coefficient */
SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1,
/* Odd tap coefficient (bits 1:0 fixed to 0) */
SCL_COEF_RAM_ODD_TAP_COEF, odd_coef,
/* Write/read control for odd coefficient */
SCL_COEF_RAM_ODD_TAP_COEF_EN, 1);
}
}
}
static void dpp1_dscl_set_scl_filter(struct dpp *dpp, const struct scaler_data *scl_data,
enum dscl_mode_sel scl_mode, bool chroma_coef_mode)
{
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;
PROGRAM_ENTRY();
if (scl_data->polyphase_filter_coeffs == 0) /*no externally provided set of coeffs and taps*/
{
filter_h = (uint16_t *)dpp1_dscl_get_filter_coeffs_64p(
(int)scl_data->taps.h_taps, scl_data->ratios.horz);
filter_v =
dpp1_dscl_get_filter_coeffs_64p((int)scl_data->taps.v_taps, scl_data->ratios.vert);
} else {
filter_h = (const uint16_t *)&scl_data->polyphase_filter_coeffs->horiz_polyphase_coeffs;
filter_v = (const uint16_t *)&scl_data->polyphase_filter_coeffs->vert_polyphase_coeffs;
}
if (filter_h != NULL)
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps, SCL_COEF_LUMA_HORZ_FILTER, filter_h);
if (filter_v != NULL)
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps, SCL_COEF_LUMA_VERT_FILTER, filter_v);
if (chroma_coef_mode) {
filter_h_c =
dpp1_dscl_get_filter_coeffs_64p((int)scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
filter_v_c =
dpp1_dscl_get_filter_coeffs_64p((int)scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
if (filter_h_c != NULL)
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps_c, SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
if (filter_v_c != NULL)
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps_c, SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
}
REG_UPDATE(VPDSCL_MODE, SCL_CHROMA_COEF_MODE, chroma_coef_mode);
}
static void dpp1_dscl_set_lb(struct dpp *dpp, const struct line_buffer_params *lb_params,
enum lb_memory_config mem_size_config)
{
PROGRAM_ENTRY();
REG_SET(VPLB_DATA_FORMAT, 0, ALPHA_EN, lb_params->alpha_en); /* Alpha enable */
REG_SET_2(
VPLB_MEMORY_CTRL, 0, MEMORY_CONFIG, mem_size_config, LB_MAX_PARTITIONS, LB_MAX_PARTITION);
}
static void dpp1_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,
vpe_fixpt_u3d19(data->ratios.horz) << 5);
REG_SET(VPDSCL_VERT_FILTER_SCALE_RATIO, 0, SCL_V_SCALE_RATIO,
vpe_fixpt_u3d19(data->ratios.vert) << 5);
REG_SET(VPDSCL_HORZ_FILTER_SCALE_RATIO_C, 0, SCL_H_SCALE_RATIO_C,
vpe_fixpt_u3d19(data->ratios.horz_c) << 5);
REG_SET(VPDSCL_VERT_FILTER_SCALE_RATIO_C, 0, SCL_V_SCALE_RATIO_C,
vpe_fixpt_u3d19(data->ratios.vert_c) << 5);
}
static void dpp1_dscl_set_scaler_position(struct dpp *dpp, const struct scaler_data *data)
{
uint32_t init_frac = 0;
uint32_t init_int = 0;
PROGRAM_ENTRY();
/*
* 0.24 format for fraction, first five bits zeroed
*/
init_frac = vpe_fixpt_u0d19(data->inits.h) << 5;
init_int = (uint32_t)vpe_fixpt_floor(data->inits.h);
REG_SET_2(VPDSCL_HORZ_FILTER_INIT, 0, SCL_H_INIT_FRAC, init_frac, SCL_H_INIT_INT, init_int);
init_frac = vpe_fixpt_u0d19(data->inits.h_c) << 5;
init_int = (uint32_t)vpe_fixpt_floor(data->inits.h_c);
REG_SET_2(
VPDSCL_HORZ_FILTER_INIT_C, 0, SCL_H_INIT_FRAC_C, init_frac, SCL_H_INIT_INT_C, init_int);
init_frac = vpe_fixpt_u0d19(data->inits.v) << 5;
init_int = (uint32_t)vpe_fixpt_floor(data->inits.v);
REG_SET_2(VPDSCL_VERT_FILTER_INIT, 0, SCL_V_INIT_FRAC, init_frac, SCL_V_INIT_INT, init_int);
init_frac = vpe_fixpt_u0d19(data->inits.v_c) << 5;
init_int = (uint32_t)vpe_fixpt_floor(data->inits.v_c);
REG_SET_2(
VPDSCL_VERT_FILTER_INIT_C, 0, SCL_V_INIT_FRAC_C, init_frac, SCL_V_INIT_INT_C, init_int);
}
static void dpp1_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);
}
}
}
void vpe10_dpp_set_segment_scaler(struct dpp *dpp, const struct scaler_data *scl_data)
{
enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(scl_data);
dpp1_dscl_set_recout(dpp, &scl_data->recout);
dpp1_dscl_set_mpc_size(dpp, scl_data);
if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
return;
dpp1_dscl_set_scaler_position(dpp, scl_data);
}
void vpe10_dpp_set_frame_scaler(struct dpp *dpp, const struct scaler_data *scl_data)
{
enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(scl_data);
bool ycbcr = dpp1_dscl_is_ycbcr(scl_data->format);
dpp1_dscl_set_h_blank(dpp, 1, 0);
dpp1_dscl_set_v_blank(dpp, 1, 0);
if (dscl_mode != DSCL_MODE_DSCL_BYPASS)
dpp1_power_on_dscl(dpp, true);
dpp1_dscl_set_dscl_mode(dpp, dscl_mode);
if (dscl_mode == DSCL_MODE_DSCL_BYPASS) {
dpp1_power_on_dscl(dpp, false);
return;
}
dpp1_dscl_set_lb(dpp, &scl_data->lb_params, LB_MEMORY_CONFIG_0);
dpp1_dscl_set_scale_ratio(dpp, scl_data);
dpp1_dscl_set_taps(dpp, scl_data);
dpp1_dscl_set_scl_filter(dpp, scl_data, dscl_mode, ycbcr);
}
File diff suppressed because it is too large Load Diff
+220
View File
@@ -0,0 +1,220 @@
/* 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_opp.h"
#include "vpe_command.h"
#include "hw_shared.h"
#include "reg_helper.h"
#define CTX_BASE opp
#define CTX vpe10_opp
static struct opp_funcs opp_funcs = {
.program_pipe_alpha = vpe10_opp_program_pipe_alpha,
.program_pipe_bypass = vpe10_opp_program_pipe_bypass,
.program_pipe_crc = vpe10_opp_program_pipe_crc,
.set_clamping = vpe10_opp_set_clamping,
.set_truncation = vpe10_opp_set_truncation,
.set_spatial_dither = vpe10_opp_set_spatial_dither,
.program_bit_depth_reduction = vpe10_opp_program_bit_depth_reduction,
.set_dyn_expansion = vpe10_opp_set_dyn_expansion,
.program_fmt = vpe10_opp_program_fmt,
};
void vpe10_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp)
{
opp->vpe_priv = vpe_priv;
opp->funcs = &opp_funcs;
}
void vpe10_opp_set_clamping(
struct opp *opp, const struct clamping_and_pixel_encoding_params *params)
{
PROGRAM_ENTRY();
switch (params->clamping_level) {
case CLAMPING_LIMITED_RANGE_8BPC:
case CLAMPING_LIMITED_RANGE_10BPC:
case CLAMPING_LIMITED_RANGE_12BPC:
REG_SET_2(VPFMT_CLAMP_CNTL, 0, VPFMT_CLAMP_DATA_EN, 1, VPFMT_CLAMP_COLOR_FORMAT,
params->clamping_level);
break;
case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
REG_SET_2(VPFMT_CLAMP_CNTL, 0, VPFMT_CLAMP_DATA_EN, 1, VPFMT_CLAMP_COLOR_FORMAT, 7);
REG_SET_2(VPFMT_CLAMP_COMPONENT_R, 0, VPFMT_CLAMP_LOWER_R, params->r_clamp_component_lower,
VPFMT_CLAMP_UPPER_R, params->r_clamp_component_upper);
REG_SET_2(VPFMT_CLAMP_COMPONENT_G, 0, VPFMT_CLAMP_LOWER_G, params->g_clamp_component_lower,
VPFMT_CLAMP_UPPER_G, params->g_clamp_component_upper);
REG_SET_2(VPFMT_CLAMP_COMPONENT_B, 0, VPFMT_CLAMP_LOWER_B, params->b_clamp_component_lower,
VPFMT_CLAMP_UPPER_B, params->b_clamp_component_upper);
break;
case CLAMPING_FULL_RANGE:
default:
REG_SET_2(VPFMT_CLAMP_CNTL, 0, VPFMT_CLAMP_DATA_EN, 0, VPFMT_CLAMP_COLOR_FORMAT, 0);
break;
}
}
void vpe10_opp_set_dyn_expansion(struct opp *opp, bool enable, enum color_depth color_dpth)
{
PROGRAM_ENTRY();
if (!enable) {
REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
return;
}
/*00 - 10-bit -> 12-bit dynamic expansion*/
/*01 - 8-bit -> 12-bit dynamic expansion*/
switch (color_dpth) {
case COLOR_DEPTH_888:
REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 1);
break;
case COLOR_DEPTH_101010:
REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 0);
break;
case COLOR_DEPTH_121212:
REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN,
1, /*otherwise last two bits are zero*/
VPFMT_DYNAMIC_EXP_MODE, 0);
break;
default:
REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
break;
}
}
void vpe10_opp_set_truncation(struct opp *opp, const struct bit_depth_reduction_params *params)
{
PROGRAM_ENTRY();
REG_UPDATE_3(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);
}
void vpe10_opp_set_spatial_dither(struct opp *opp, const struct bit_depth_reduction_params *params)
{
PROGRAM_ENTRY();
/*Disable spatial (random) dithering*/
REG_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL, 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);
if (params->flags.SPATIAL_DITHER_ENABLED == 0)
return;
/* only use FRAME_COUNTER_MAX if frameRandom == 1*/
if (params->flags.FRAME_RANDOM == 1) {
if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) {
REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
} else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
} else
return;
} else {
REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
}
/* 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_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL,
/*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);
}
void vpe10_opp_program_bit_depth_reduction(
struct opp *opp, const struct bit_depth_reduction_params *fmt_bit_depth)
{
opp->funcs->set_truncation(opp, fmt_bit_depth);
opp->funcs->set_spatial_dither(opp, fmt_bit_depth);
}
void vpe10_opp_program_fmt(struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth,
struct clamping_and_pixel_encoding_params *clamping)
{
opp->funcs->program_bit_depth_reduction(opp, fmt_bit_depth);
opp->funcs->set_clamping(opp, clamping);
}
void vpe10_opp_program_pipe_alpha(struct opp *opp, uint16_t alpha)
{
PROGRAM_ENTRY();
REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_ALPHA, alpha);
}
void vpe10_opp_program_pipe_bypass(struct opp *opp, bool enable)
{
PROGRAM_ENTRY();
REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_DIGITAL_BYPASS_EN, enable);
}
void vpe10_opp_program_pipe_crc(struct opp *opp, bool enable)
{
PROGRAM_ENTRY();
REG_UPDATE(VPOPP_PIPE_CRC_CONTROL, VPOPP_PIPE_CRC_EN, enable);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
/* 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 "vpe10_vpec.h"
static struct vpec_funcs vpec_funcs = {
.check_swmode_support = vpe10_vpec_check_swmode_support,
.get_dcc_compression_cap = vpe10_vpec_get_dcc_compression_cap,
};
void vpe10_construct_vpec(struct vpe_priv *vpe_priv, struct vpec *vpec)
{
vpec->vpe_priv = vpe_priv;
vpec->funcs = &vpec_funcs;
}
/** functions for capability check */
bool vpe10_vpec_check_swmode_support(struct vpec *vpec, enum vpe_swizzle_mode_values sw_mode)
{
switch (sw_mode) {
case VPE_SW_LINEAR:
case VPE_SW_256B_D:
case VPE_SW_4KB_D:
case VPE_SW_64KB_D:
case VPE_SW_64KB_D_T:
case VPE_SW_4KB_D_X:
case VPE_SW_64KB_D_X:
case VPE_SW_64KB_R_X:
case VPE_SW_VAR_D_X:
case VPE_SW_VAR_R_X:
return true;
default:
return false;
}
}
bool vpe10_vpec_get_dcc_compression_cap(struct vpec *vpec,
const struct vpe_dcc_surface_param *input, struct vpe_surface_dcc_cap *output)
{
output->capable = false;
return output->capable;
}
+117
View File
@@ -0,0 +1,117 @@
/* 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 "3dlut_builder.h"
static void convert_3dlut_to_tetrahedral_params(
struct vpe_rgb *rgb, bool is_17x17x17, bool is_12_bits, struct tetrahedral_params *params)
{
struct vpe_rgb *lut0;
struct vpe_rgb *lut1;
struct vpe_rgb *lut2;
struct vpe_rgb *lut3;
int i, lut_i;
int num_values;
if (is_17x17x17 == false) {
lut0 = params->tetrahedral_9.lut0;
lut1 = params->tetrahedral_9.lut1;
lut2 = params->tetrahedral_9.lut2;
lut3 = params->tetrahedral_9.lut3;
num_values = LUT3D_SIZE_9x9x9;
} else {
lut0 = params->tetrahedral_17.lut0;
lut1 = params->tetrahedral_17.lut1;
lut2 = params->tetrahedral_17.lut2;
lut3 = params->tetrahedral_17.lut3;
num_values = LUT3D_SIZE_17x17x17;
}
for (lut_i = 0, i = 0; i < num_values - 4; lut_i++, i += 4) {
lut0[lut_i].red = rgb[i].red;
lut0[lut_i].green = rgb[i].green;
lut0[lut_i].blue = rgb[i].blue;
lut1[lut_i].red = rgb[i + 1].red;
lut1[lut_i].green = rgb[i + 1].green;
lut1[lut_i].blue = rgb[i + 1].blue;
lut2[lut_i].red = rgb[i + 2].red;
lut2[lut_i].green = rgb[i + 2].green;
lut2[lut_i].blue = rgb[i + 2].blue;
lut3[lut_i].red = rgb[i + 3].red;
lut3[lut_i].green = rgb[i + 3].green;
lut3[lut_i].blue = rgb[i + 3].blue;
}
lut0[lut_i].red = rgb[i].red;
lut0[lut_i].green = rgb[i].green;
lut0[lut_i].blue = rgb[i].blue;
params->use_12bits = is_12_bits;
params->use_tetrahedral_9 = !is_17x17x17;
}
bool convert_to_tetrahedral(struct vpe_priv *vpe_priv, uint16_t rgb_lib[17 * 17 * 17 * 3],
struct vpe_3dlut *params, bool enable_3dlut)
{
if (!enable_3dlut) {
params->state.bits.initialized = 0;
return true;
}
bool ret = false;
struct vpe_rgb *rgb_area = NULL;
int ind = 0;
int ind_lut = 0;
int nir, nig, nib;
rgb_area = (struct vpe_rgb *)vpe_zalloc(sizeof(struct vpe_rgb) * 17 * 17 * 17);
if (rgb_area == NULL)
goto release;
memset(rgb_area, 0, 17 * 17 * 17 * sizeof(struct vpe_rgb));
for (nib = 0; nib < 17; nib++) {
for (nig = 0; nig < 17; nig++) {
for (nir = 0; nir < 17; nir++) {
ind_lut = 3 * (nib + 17 * nig + 289 * nir);
rgb_area[ind].red = rgb_lib[ind_lut + 0];
rgb_area[ind].green = rgb_lib[ind_lut + 1];
rgb_area[ind].blue = rgb_lib[ind_lut + 2];
ind++;
}
}
}
convert_3dlut_to_tetrahedral_params(rgb_area, true, true, &params->lut_3d);
params->state.bits.initialized = 1;
vpe_free(rgb_area);
ret = true;
release:
return ret;
}
+214
View File
@@ -0,0 +1,214 @@
/* 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 "background.h"
#include "common.h"
#include "vpe_priv.h"
#include "color_bg.h"
void vpe_create_bg_segments(
struct vpe_priv *vpe_priv, struct vpe_rect *gaps, uint16_t gaps_cnt, enum vpe_cmd_ops ops)
{
uint16_t gap_index;
struct scaler_data *scaler_data;
struct stream_ctx *stream_ctx = &(vpe_priv->stream_ctx[0]);
int32_t vp_x = stream_ctx->stream.scaling_info.src_rect.x;
int32_t vp_y = stream_ctx->stream.scaling_info.src_rect.y;
uint16_t src_div = vpe_is_yuv420(stream_ctx->stream.surface_info.format) ? 2 : 1;
uint16_t dst_div = vpe_is_yuv420(vpe_priv->output_ctx.surface.format) ? 2 : 1;
for (gap_index = 0; gap_index < gaps_cnt; gap_index++) {
scaler_data = &(vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].inputs[0].scaler_data);
/* format */
scaler_data->format = stream_ctx->stream.surface_info.format;
scaler_data->lb_params.alpha_en = stream_ctx->per_pixel_alpha;
/* recout */
scaler_data->recout.x = 0;
scaler_data->recout.y = 0;
scaler_data->recout.height = VPE_MIN_VIEWPORT_SIZE;
scaler_data->recout.width = VPE_MIN_VIEWPORT_SIZE;
/* ratios */
scaler_data->ratios.horz = vpe_fixpt_one;
scaler_data->ratios.vert = vpe_fixpt_one;
if (vpe_is_yuv420(scaler_data->format)) {
scaler_data->ratios.horz_c = vpe_fixpt_from_fraction(1, 2);
scaler_data->ratios.vert_c = vpe_fixpt_from_fraction(1, 2);
} else {
scaler_data->ratios.horz_c = vpe_fixpt_one;
scaler_data->ratios.vert_c = vpe_fixpt_one;
}
/* Active region */
scaler_data->h_active = gaps[gap_index].width;
scaler_data->v_active = gaps[gap_index].height;
/* viewport */
scaler_data->viewport.x = vp_x;
scaler_data->viewport.y = vp_y;
scaler_data->viewport.width = VPE_MIN_VIEWPORT_SIZE;
scaler_data->viewport.height = VPE_MIN_VIEWPORT_SIZE;
scaler_data->viewport_c.x = scaler_data->viewport.x / src_div;
scaler_data->viewport_c.y = scaler_data->viewport.y / src_div;
scaler_data->viewport_c.width = scaler_data->viewport.width / src_div;
scaler_data->viewport_c.height = scaler_data->viewport.height / src_div;
/* destination viewport */
scaler_data->dst_viewport = gaps[gap_index];
scaler_data->dst_viewport_c.x = scaler_data->dst_viewport.x / dst_div;
scaler_data->dst_viewport_c.y = scaler_data->dst_viewport.y / dst_div;
scaler_data->dst_viewport_c.width = scaler_data->dst_viewport.width / dst_div;
scaler_data->dst_viewport_c.height = scaler_data->dst_viewport.height / dst_div;
/* taps and inits */
scaler_data->taps.h_taps = scaler_data->taps.v_taps = 4;
scaler_data->taps.h_taps_c = scaler_data->taps.v_taps_c = 2;
scaler_data->inits.h = vpe_fixpt_div_int(
vpe_fixpt_add_int(scaler_data->ratios.horz, (int)(scaler_data->taps.h_taps + 1)), 2);
scaler_data->inits.v = vpe_fixpt_div_int(
vpe_fixpt_add_int(scaler_data->ratios.vert, (int)(scaler_data->taps.v_taps + 1)), 2);
scaler_data->inits.h_c = vpe_fixpt_div_int(
vpe_fixpt_add_int(scaler_data->ratios.horz_c, (int)(scaler_data->taps.h_taps_c + 1)),
2);
scaler_data->inits.v_c = vpe_fixpt_div_int(
vpe_fixpt_add_int(scaler_data->ratios.vert_c, (int)(scaler_data->taps.v_taps_c + 1)),
2);
VPE_ASSERT(gaps_cnt - gap_index - 1 <= (uint16_t)0xF);
// background takes stream_idx 0 as its input
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].inputs[0].stream_idx = 0;
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].dst_viewport = scaler_data->dst_viewport;
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].dst_viewport_c = scaler_data->dst_viewport_c;
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].num_inputs = 1;
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].ops = ops;
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].cd = (uint8_t)(gaps_cnt - gap_index - 1);
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].tm_enabled =
false; // currently only support frontend tm
if (vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].cd == (gaps_cnt - 1)) {
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].is_begin = true;
}
if (vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].cd == 0) {
vpe_priv->vpe_cmd_info[vpe_priv->num_vpe_cmds].is_end = true;
}
vpe_priv->num_vpe_cmds++;
}
}
void vpe_full_bg_gaps(struct vpe_rect *gaps, const struct vpe_rect *target_rect, uint16_t max_gaps)
{
uint16_t gap_index;
int32_t last_covered;
uint32_t gap_width, gap_remainder;
last_covered = target_rect->x;
gap_width = target_rect->width / max_gaps;
gap_remainder = target_rect->width % max_gaps;
for (gap_index = 0; gap_index < max_gaps; gap_index++) {
gaps[gap_index].x = last_covered;
gaps[gap_index].y = target_rect->y;
gaps[gap_index].width = gap_width;
if (gap_index >= max_gaps - gap_remainder) {
gaps[gap_index].width += 1;
}
gaps[gap_index].height = target_rect->height;
last_covered = last_covered + (int32_t)gaps[gap_index].width;
}
}
/* calculates the gaps in target_rect which are not covered by the first stream
and returns the number of gaps */
uint16_t vpe_find_bg_gaps(struct vpe_priv *vpe_priv, const struct vpe_rect *target_rect,
struct vpe_rect *gaps, uint16_t max_gaps)
{
uint16_t num_gaps = 0;
uint16_t num_segs;
struct vpe_rect *dst_viewport_rect;
bool full_bg = false;
const uint32_t max_seg_width = vpe_priv->pub.caps->plane_caps.max_viewport_width;
const uint16_t num_multiple = 1;
num_segs = vpe_priv->stream_ctx[0].num_segments;
dst_viewport_rect = &(vpe_priv->stream_ctx[0].segment_ctx[0].scaler_data.dst_viewport);
if (target_rect->x < dst_viewport_rect->x) {
if (target_rect->width <= max_seg_width) {
goto full_bg;
}
gaps[0].x = target_rect->x;
gaps[0].y = target_rect->y;
gaps[0].width = (uint32_t)(dst_viewport_rect->x - target_rect->x);
gaps[0].height = target_rect->height;
num_gaps++;
if (gaps[0].width > max_seg_width) {
if (!vpe_priv->resource.split_bg_gap(
gaps, target_rect, max_seg_width, max_gaps, &num_gaps, num_multiple)) {
goto full_bg;
}
}
}
dst_viewport_rect =
&(vpe_priv->stream_ctx[0].segment_ctx[num_segs - 1].scaler_data.dst_viewport);
if (target_rect->x + (int32_t)target_rect->width >
dst_viewport_rect->x + (int32_t)dst_viewport_rect->width) {
if (num_gaps == max_gaps) {
goto full_bg;
}
gaps[num_gaps].x = dst_viewport_rect->x + (int32_t)dst_viewport_rect->width;
gaps[num_gaps].y = target_rect->y;
gaps[num_gaps].width =
(uint32_t)(target_rect->x + (int32_t)target_rect->width -
(dst_viewport_rect->x + (int32_t)dst_viewport_rect->width));
gaps[num_gaps].height = target_rect->height;
num_gaps++;
if (gaps[num_gaps - 1].width > max_seg_width) {
if (!vpe_priv->resource.split_bg_gap(
gaps, target_rect, max_seg_width, max_gaps, &num_gaps, num_multiple)) {
goto full_bg;
}
}
}
return num_gaps;
full_bg:
vpe_full_bg_gaps(gaps, target_rect, max_gaps);
return max_gaps;
}
+887
View File
@@ -0,0 +1,887 @@
/* 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 "vpe_assert.h"
#include <string.h>
#include "color.h"
#include "color_gamma.h"
#include "color_cs.h"
#include "vpe_priv.h"
#include "color_gamut.h"
#include "common.h"
#include "custom_float.h"
#include "color_test_values.h"
#include "color_pwl.h"
#include "3dlut_builder.h"
#include "shaper_builder.h"
static void color_check_input_cm_update(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx,
const struct vpe_color_space *vcs, const struct vpe_color_adjust *adjustments,
bool enable_3dlut);
static void color_check_output_cm_update(
struct vpe_priv *vpe_priv, const struct vpe_color_space *vcs);
static bool color_check_bypass_cm(struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
static bool color_update_output_tf(struct vpe_priv *vpe_priv,
enum color_transfer_func output_transfer_function, struct transfer_func *output_tf,
bool can_bypass);
static bool color_update_input_tf(struct vpe_priv *vpe_priv,
enum color_transfer_func input_transfer_function, struct transfer_func *input_tf,
bool can_bypass, bool force_tf_calculation);
static bool color_update_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
const struct vpe_color_adjust *adjustments, struct vpe_csc_matrix *input_cs,
struct vpe_color_adjust *stream_clr_adjustments, struct fixed31_32 *matrix_scaling_factor);
static bool is_ycbcr(enum color_space in_cs);
static bool is_ycbcr(enum color_space in_cs)
{
if ((in_cs == COLOR_SPACE_YCBCR601) || (in_cs == COLOR_SPACE_YCBCR601_LIMITED) ||
(in_cs == COLOR_SPACE_YCBCR709) || (in_cs == COLOR_SPACE_YCBCR709_LIMITED) ||
(in_cs == COLOR_SPACE_2020_YCBCR) || (in_cs == COLOR_SPACE_2020_YCBCR_LIMITED)) {
return true;
}
return false;
}
static void color_check_output_cm_update(
struct vpe_priv *vpe_priv, const struct vpe_color_space *vcs)
{
enum color_space cs;
enum color_transfer_func tf;
vpe_color_get_color_space_and_tf(vcs, &cs, &tf);
if (cs == COLOR_SPACE_UNKNOWN || tf == TRANSFER_FUNC_UNKNOWN)
VPE_ASSERT(0);
if (cs != vpe_priv->output_ctx.cs) {
vpe_priv->output_ctx.dirty_bits.color_space = 1;
vpe_priv->output_ctx.cs = cs;
} else {
vpe_priv->output_ctx.dirty_bits.color_space = 0;
}
if (tf != vpe_priv->output_ctx.tf) {
vpe_priv->output_ctx.dirty_bits.transfer_function = 1;
vpe_priv->output_ctx.tf = tf;
} else {
vpe_priv->output_ctx.dirty_bits.transfer_function = 0;
}
}
static void color_check_input_cm_update(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx,
const struct vpe_color_space *vcs, const struct vpe_color_adjust *adjustments,
bool enable_3dlut)
{
enum color_space cs;
enum color_transfer_func tf;
vpe_color_get_color_space_and_tf(vcs, &cs, &tf);
/*
* Bias and Scale already does full->limited range conversion.
* Hence, the ICSC matrix should always be full range
*/
vpe_convert_full_range_color_enum(&cs);
if (cs == COLOR_SPACE_UNKNOWN && tf == TRANSFER_FUNC_UNKNOWN)
VPE_ASSERT(0);
if (cs != stream_ctx->cs || enable_3dlut != stream_ctx->enable_3dlut) {
stream_ctx->dirty_bits.color_space = 1;
stream_ctx->cs = cs;
} else {
stream_ctx->dirty_bits.color_space = 0;
if (adjustments) {
if (vpe_color_different_color_adjusts(
adjustments, &stream_ctx->color_adjustments)) // the new stream has different
// color adjustments params
stream_ctx->dirty_bits.color_space = 1;
}
}
// if the new transfer function is different than the old one or the scaling factor is not one
// any new stream will start with a transfer function which is not scaled
if (tf != stream_ctx->tf || enable_3dlut != stream_ctx->enable_3dlut) {
stream_ctx->dirty_bits.transfer_function = 1;
stream_ctx->tf = tf;
} else {
stream_ctx->dirty_bits.transfer_function = 0;
}
stream_ctx->enable_3dlut = enable_3dlut;
}
static bool color_update_output_tf(struct vpe_priv *vpe_priv,
enum color_transfer_func output_transfer_function, struct transfer_func *output_tf,
bool can_bypass)
{
struct pwl_params *params = NULL;
output_tf->sdr_ref_white_level = 80;
if (can_bypass) {
output_tf->type = TF_TYPE_BYPASS;
return true;
}
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
switch (output_transfer_function) {
case TRANSFER_FUNC_SRGB:
case TRANSFER_FUNC_BT709:
case TRANSFER_FUNC_BT1886:
case TRANSFER_FUNC_PQ2084:
case TRANSFER_FUNC_LINEAR_0_125:
output_tf->tf = output_transfer_function;
break;
default:
VPE_ASSERT(0);
break;
}
if (!vpe_priv->init.debug.force_tf_calculation)
vpe_priv->resource.get_tf_pwl_params(output_tf, &params, CM_REGAM);
if (params)
output_tf->use_pre_calculated_table = true;
else
output_tf->use_pre_calculated_table = false;
if (!output_tf->use_pre_calculated_table)
vpe_color_calculate_regamma_params(vpe_priv, output_tf, &vpe_priv->cal_buffer);
return true;
}
static bool color_update_input_tf(struct vpe_priv *vpe_priv,
const enum color_transfer_func color_input_tf, struct transfer_func *input_tf, bool can_bypass,
bool force_tf_calculation)
{
bool ret = true;
struct pwl_params *params = NULL;
if (can_bypass) {
input_tf->type = TF_TYPE_BYPASS;
return true;
}
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
switch (color_input_tf) {
case TRANSFER_FUNC_SRGB:
case TRANSFER_FUNC_BT709:
case TRANSFER_FUNC_BT1886:
case TRANSFER_FUNC_PQ2084:
case TRANSFER_FUNC_LINEAR_0_125:
case TRANSFER_FUNC_NORMALIZED_PQ:
input_tf->tf = color_input_tf;
break;
default:
VPE_ASSERT(0);
break;
}
if (!vpe_priv->init.debug.force_tf_calculation)
vpe_priv->resource.get_tf_pwl_params(input_tf, &params, CM_DEGAM);
if (params)
input_tf->use_pre_calculated_table = true;
else
input_tf->use_pre_calculated_table = false;
if ((!input_tf->use_pre_calculated_table) || (force_tf_calculation)) {
input_tf->use_pre_calculated_table = false;
vpe_color_calculate_degamma_params(vpe_priv, vpe_priv->stream_ctx->tf_scaling_factor,
vpe_fixpt_from_int(1),
input_tf);
}
return ret;
}
// return true if bypass can be done
static bool color_check_bypass_cm(struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
uint32_t i;
struct stream_ctx *stream_ctx;
// TODO: revisit the TM case
for (i = 0; i < param->num_streams; i++) {
stream_ctx = &vpe_priv->stream_ctx[i];
if (stream_ctx->cs != vpe_priv->output_ctx.cs ||
stream_ctx->tf != vpe_priv->output_ctx.tf) {
return false;
}
}
return true;
}
static enum color_space color_get_icsc_cs(enum color_space ics)
{
switch (ics) {
case COLOR_SPACE_SRGB:
case COLOR_SPACE_SRGB_LIMITED:
case COLOR_SPACE_MSREF_SCRGB:
case COLOR_SPACE_2020_RGB_FULLRANGE:
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
return COLOR_SPACE_SRGB;
case COLOR_SPACE_JFIF:
case COLOR_SPACE_YCBCR601:
case COLOR_SPACE_YCBCR601_LIMITED:
return COLOR_SPACE_YCBCR601;
case COLOR_SPACE_YCBCR709:
case COLOR_SPACE_YCBCR709_LIMITED:
return COLOR_SPACE_YCBCR709;
case COLOR_SPACE_2020_YCBCR:
case COLOR_SPACE_2020_YCBCR_LIMITED:
return COLOR_SPACE_2020_YCBCR;
default:
return COLOR_SPACE_UNKNOWN;
}
}
// return true is bypass can be done
static bool color_update_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
const struct vpe_color_adjust *adjustments, struct vpe_csc_matrix *input_cs,
struct vpe_color_adjust *stream_clr_adjustments, struct fixed31_32 *matrix_scaling_factor)
{
int i, j;
bool use_adjustments = false;
int arr_size = sizeof(vpe_input_csc_matrix_fixed) / sizeof(struct vpe_csc_matrix);
input_cs->cs = COLOR_SPACE_UNKNOWN;
use_adjustments = vpe_use_csc_adjust(adjustments);
in_cs = color_get_icsc_cs(in_cs);
for (i = 0; i < arr_size; i++)
if (vpe_input_csc_matrix_fixed[i].cs == in_cs) {
input_cs->cs = vpe_input_csc_matrix_fixed[i].cs;
for (j = 0; j < 12; j++)
input_cs->regval[j] = vpe_input_csc_matrix_fixed[i].regval[j];
break;
}
if (i == arr_size) {
vpe_log("err: unknown cs not handled!");
return false;
}
if (use_adjustments && is_ycbcr(in_cs)) { // shader supports only yuv input for color
// adjustments
vpe_log("Apply color adjustments (contrast, saturation, hue, brightness)");
if (!vpe_color_calculate_input_cs(
vpe_priv, in_cs, adjustments, input_cs, matrix_scaling_factor))
return false;
*stream_clr_adjustments = *adjustments;
}
return true;
}
bool vpe_use_csc_adjust(const struct vpe_color_adjust *adjustments)
{
float epsilon = 0.001f; // steps are 1.0f or 0.01f, so should be plenty
// see vpe_types.h and vpe_color_adjust definition for VpBlt ranges
// default brightness = 0
if (adjustments->brightness > epsilon || adjustments->brightness < -epsilon)
return true;
// default contrast = 1
if (adjustments->contrast > 1 + epsilon || adjustments->contrast < 1 - epsilon)
return true;
// default saturation = 1
if (adjustments->saturation > 1 + epsilon || adjustments->saturation < 1 - epsilon)
return true;
// default hue = 0
if (adjustments->hue > epsilon || adjustments->hue < -epsilon)
return true;
return false;
}
/* Bias and Scale reference table
Encoding Bpp Format Data Range Expansion Bias Scale
aRGB 32bpp 8888 Full Zero 0 256/255
8888 Limited Zero -16/256 256/(235-16)
2101010 Full Zero 0 1024/1023
2101010 Limited Zero -64/1024 1024/(940-64)
2101010 XR bias Zero -384/1024 1024/510 // not used
64bpp fixed 10bpc Full Zero 0 1024/1023 // do we have these?
10 bpc limited zero -64/1024 1024/(940-64)
12 bpc Full Zero 0 4096/4095
12 bpc Limited Zero -256/4096 4096/(3760-256)
aCrYCb 32bpp 8888 Full Zero 0 256/255
8888 Limited Zero Y:-16/256 Y:256/(235-16)
C:-128/256 C:256/(240-16) // See notes
below 2101010 Full Zero 0 1024/1023 2101010 Limited Zero
Y:-64/1024 Y:1024/(940-64) C:-512/1024 C:1024(960-64) 64bpp fixed 10bpc Full Zero 0
1024/1023 10 bpc Limited Zero Y:-64/1024 Y:1024/(940-64) C:-512/1024
C:1024(960-64) // See notes below 12 bpc Full Zero 0 4096/4095 12
bpc Limited Zero Y:-256/4096 Y:4096/(3760-256) C:-2048/4096 C:4096/(3840-256) //
See notes below
The bias_c we use here in the function are diff with the above table from hw team
because the table is to run with CSC matrix which expect chroma
from -0.5~+0.5.
However the csc matrix we use in ICSC is expecting chroma value
from 0.0~1.0.
Hence we need a bias for chroma to output a range from 0.0~1.0 instead.
So we use the same value as luma (Y) which expects range from 0~1.0 already.
*/
static bool build_scale_and_bias(struct bias_and_scale *bias_and_scale,
const struct vpe_color_space *vcs, enum vpe_surface_pixel_format format)
{
struct fixed31_32 scale = vpe_fixpt_one; // RGB or Y
struct fixed31_32 scale_c = vpe_fixpt_one; // Cb/Cr
struct fixed31_32 bias = vpe_fixpt_zero; // RGB or Y
struct fixed31_32 bias_c = vpe_fixpt_from_fraction(-1, 2); // Cb/Cr
bool is_chroma_different = false;
struct custom_float_format fmt;
fmt.exponenta_bits = 6;
fmt.mantissa_bits = 12;
fmt.sign = true;
if (vpe_is_rgb8(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(256, 255);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(256, 235 - 16);
bias = vpe_fixpt_from_fraction(-16, 256);
} // else report error? here just go with default (1.0, 0.0)
} else if (vpe_is_rgb10(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(1024, 1023);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(1024, 940 - 64);
bias = vpe_fixpt_from_fraction(-64, 1024);
} // else report error? here just go with default (1.0, 0.0)
} else if (vpe_is_yuv420_8(format) || vpe_is_yuv444_8(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(256, 255);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(256, 235 - 16);
bias = vpe_fixpt_from_fraction(-16, 256);
scale_c = vpe_fixpt_from_fraction(256, 240 - 16);
bias_c = vpe_fixpt_from_fraction(-16, 256); // See notes in function comment
is_chroma_different = true;
} // else report error? not sure if default is right
} else if (vpe_is_yuv420_10(format) || vpe_is_yuv444_10(format)) {
if (vcs->range == VPE_COLOR_RANGE_FULL) {
scale = vpe_fixpt_from_fraction(1024, 1023);
} else if (vcs->range == VPE_COLOR_RANGE_STUDIO) {
scale = vpe_fixpt_from_fraction(1024, 940 - 64);
bias = vpe_fixpt_from_fraction(-64, 1024);
scale_c = vpe_fixpt_from_fraction(1024, 960 - 64);
bias_c = vpe_fixpt_from_fraction(-64, 1024); // See notes in function comment
is_chroma_different = true;
} // else report error? not sure if default is right
}
vpe_convert_to_custom_float_format(scale, &fmt, &bias_and_scale->scale_green);
vpe_convert_to_custom_float_format(bias, &fmt, &bias_and_scale->bias_green);
// see definition of scale/bias and scale_c/bias_c
// RGB formats only have scale/bias since all color channels are the same
// YCbCr have scale/bias for Y (in HW maps to G) and scale_c/bias_c for CrCb (mapping to R,B)
if (!is_chroma_different) {
bias_and_scale->scale_red = bias_and_scale->scale_green;
bias_and_scale->scale_blue = bias_and_scale->scale_green;
bias_and_scale->bias_red = bias_and_scale->bias_green;
bias_and_scale->bias_blue = bias_and_scale->bias_green;
} else {
vpe_convert_to_custom_float_format(scale_c, &fmt, &bias_and_scale->scale_red);
vpe_convert_to_custom_float_format(bias_c, &fmt, &bias_and_scale->bias_red);
bias_and_scale->scale_blue = bias_and_scale->scale_red;
bias_and_scale->bias_blue = bias_and_scale->bias_red;
}
return true;
}
enum vpe_status vpe_color_build_tm_cs(const struct vpe_tonemap_params *tm_params,
struct vpe_surface_info surface_info, struct vpe_color_space *tm_out_cs)
{
tm_out_cs->tf = tm_params->lut_out_tf;
tm_out_cs->primaries = tm_params->lut_out_gamut;
tm_out_cs->encoding = surface_info.cs.encoding;
tm_out_cs->range = VPE_COLOR_RANGE_FULL; // surface_info.cs.range;
tm_out_cs->cositing = VPE_CHROMA_COSITING_NONE; // surface_info.cs.cositing;
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)
{
uint32_t stream_idx;
struct stream_ctx *stream_ctx;
struct output_ctx *output_ctx;
enum vpe_status status = VPE_STATUS_OK;
color_check_output_cm_update(vpe_priv, &param->dst_surface.cs);
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
color_check_input_cm_update(vpe_priv, stream_ctx,
&param->streams[stream_idx].surface_info.cs, &param->streams[stream_idx].color_adj,
param->streams[stream_idx].tm_params.enable_3dlut);
}
output_ctx = &vpe_priv->output_ctx;
if (output_ctx->dirty_bits.transfer_function) {
if (!output_ctx->output_tf) {
output_ctx->output_tf =
(struct transfer_func *)vpe_zalloc(sizeof(struct transfer_func));
if (!output_ctx->output_tf) {
vpe_log("err: out of memory for output tf!");
return VPE_STATUS_NO_MEMORY;
}
}
color_update_output_tf(vpe_priv, output_ctx->tf, output_ctx->output_tf,
false); // No bypass, always do regam/degam
}
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
struct fixed31_32 new_matrix_scaling_factor = vpe_fixpt_one;
if (stream_ctx->dirty_bits.color_space) {
if (!stream_ctx->input_cs) {
stream_ctx->input_cs =
(struct vpe_csc_matrix *)vpe_zalloc(sizeof(struct vpe_csc_matrix));
if (!stream_ctx->input_cs) {
vpe_log("err: out of memory for input cs!");
return VPE_STATUS_NO_MEMORY;
}
}
if (!color_update_input_cs(vpe_priv, stream_ctx->cs,
&param->streams[stream_idx].color_adj, stream_ctx->input_cs,
&stream_ctx->color_adjustments, &new_matrix_scaling_factor)) {
vpe_log("err: input cs not being programmed!");
} else {
if ((vpe_priv->scale_yuv_matrix) && // the option to scale the matrix yuv to rgb is
// on
(new_matrix_scaling_factor.value !=
vpe_priv->stream_ctx->tf_scaling_factor.value)) {
vpe_priv->stream_ctx->tf_scaling_factor = new_matrix_scaling_factor;
stream_ctx->dirty_bits.transfer_function = 1; // force tf recalculation
}
}
}
if (stream_ctx->dirty_bits.transfer_function) {
if (!stream_ctx->input_tf) {
stream_ctx->input_tf =
(struct transfer_func *)vpe_zalloc(sizeof(struct transfer_func));
if (!stream_ctx->input_tf) {
vpe_log("err: out of memory for input tf!");
return VPE_STATUS_NO_MEMORY;
}
}
color_update_input_tf(vpe_priv, stream_ctx->tf, stream_ctx->input_tf,
stream_ctx->stream.tm_params.enable_3dlut, // By Pass regamma if 3DLUT is enabled
false);
}
if (!stream_ctx->bias_scale) {
stream_ctx->bias_scale =
(struct bias_and_scale *)vpe_zalloc(sizeof(struct bias_and_scale));
if (!stream_ctx->bias_scale) {
vpe_log("err: out of memory for bias and scale!");
return VPE_STATUS_NO_MEMORY;
}
build_scale_and_bias(stream_ctx->bias_scale,
&param->streams[stream_idx].surface_info.cs,
param->streams[stream_idx].surface_info.format);
}
if (stream_ctx->dirty_bits.color_space || output_ctx->dirty_bits.color_space) {
if (!stream_ctx->gamut_remap) {
stream_ctx->gamut_remap = vpe_zalloc(sizeof(struct colorspace_transform));
if (!stream_ctx->gamut_remap) {
vpe_log("err: out of memory for gamut_remap!");
return VPE_STATUS_NO_MEMORY;
}
}
status = vpe_color_update_gamut(vpe_priv, stream_ctx->cs, output_ctx->cs,
stream_ctx->gamut_remap, stream_ctx->stream.tm_params.enable_3dlut);
}
}
if (status != VPE_STATUS_OK) {
vpe_log("failed in updating gamut %d\n", (int)status);
return status;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_color_tm_update_hdr_mult(uint16_t shaper_in_exp_max, uint32_t peak_white,
struct fixed31_32 *hdr_multiplier, bool enable3dlut)
{
if (enable3dlut) {
struct fixed31_32 shaper_in_gain;
struct fixed31_32 pq_norm_gain;
// HDRMULT = 2^shaper_in_exp_max*(1/PQ(x))
shaper_in_gain = vpe_fixpt_from_int((long long)1 << shaper_in_exp_max);
vpe_compute_pq(vpe_fixpt_from_fraction((long long)peak_white, 10000), &pq_norm_gain);
*hdr_multiplier = vpe_fixpt_div(shaper_in_gain, pq_norm_gain);
} else {
*hdr_multiplier = vpe_fixpt_one;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_color_update_shaper(
uint16_t shaper_in_exp_max, struct transfer_func *shaper_func, bool enable_3dlut)
{
if (!enable_3dlut) {
shaper_func->type = TF_TYPE_BYPASS;
return VPE_STATUS_OK;
}
struct vpe_shaper_setup_in shaper_in;
shaper_in.shaper_in_max = 1 << 16;
shaper_in.use_const_hdr_mult = false; // can't be true. Fix is required.
shaper_func->type = TF_TYPE_HWPWL;
shaper_func->tf = TRANSFER_FUNC_LINEAR_0_125;
return vpe_build_shaper(&shaper_in, &shaper_func->pwl);
}
enum vpe_status vpe_color_update_blnd_gam(struct vpe_priv *vpe_priv,
const struct vpe_build_param *param, const struct vpe_tonemap_params *tm_params,
struct transfer_func *blnd_tf_func, bool enable_3dlut)
{
if (!enable_3dlut) {
blnd_tf_func->type = TF_TYPE_BYPASS;
return VPE_STATUS_OK;
}
enum vpe_status ret = VPE_STATUS_OK;
struct vpe_color_space tm_out_cs;
enum color_space cs;
enum color_transfer_func tf;
struct fixed31_32 tf_norm_gain;
vpe_color_build_tm_cs(tm_params, param->dst_surface, &tm_out_cs);
vpe_color_get_color_space_and_tf(&tm_out_cs, &cs, &tf);
if (tf == TRANSFER_FUNC_NORMALIZED_PQ) {
uint32_t outLuminance = vpe_priv->output_ctx.hdr_metadata.max_mastering;
vpe_compute_pq(vpe_fixpt_from_fraction((long long)outLuminance, 10000), &tf_norm_gain);
} else {
tf_norm_gain = vpe_fixpt_from_int(1);
}
blnd_tf_func->type = TF_TYPE_DISTRIBUTED_POINTS;
blnd_tf_func->tf = tf;
blnd_tf_func->use_pre_calculated_table = false;
vpe_color_calculate_degamma_params(vpe_priv, tf_norm_gain, vpe_fixpt_from_int(1), blnd_tf_func);
return VPE_STATUS_OK;
}
enum vpe_status vpe_color_update_movable_cm(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
enum vpe_status ret = VPE_STATUS_OK;
uint32_t stream_idx;
struct stream_ctx *stream_ctx;
struct output_ctx *output_ctx = &vpe_priv->output_ctx;
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
bool enable_3dlut = stream_ctx->stream.tm_params.enable_3dlut;
bool update_3dlut = stream_ctx->stream.tm_params.update_3dlut;
if (stream_ctx->update_3dlut) {
uint32_t pqNormFactor;
struct vpe_color_space tm_out_cs;
enum color_space out_lut_cs;
enum color_transfer_func tf;
if (!stream_ctx->in_shaper_func) {
stream_ctx->in_shaper_func = vpe_zalloc(sizeof(struct transfer_func));
if (!stream_ctx->in_shaper_func) {
vpe_log("err: out of memory for shaper tf!");
ret = VPE_STATUS_NO_MEMORY;
goto exit;
}
}
if (!stream_ctx->blend_tf) {
stream_ctx->blend_tf = vpe_zalloc(sizeof(struct transfer_func));
if (!stream_ctx->blend_tf) {
vpe_log("err: out of memory for blend/post1d tf!");
ret = VPE_STATUS_NO_MEMORY;
goto exit;
}
}
if (!stream_ctx->lut3d_func) {
stream_ctx->lut3d_func = vpe_zalloc(sizeof(struct vpe_3dlut));
if (!stream_ctx->lut3d_func) {
vpe_log("err: out of memory for 3d lut!");
ret = VPE_STATUS_NO_MEMORY;
goto exit;
}
}
if (!output_ctx->gamut_remap) {
output_ctx->gamut_remap = vpe_zalloc(sizeof(struct colorspace_transform));
if (!output_ctx->gamut_remap) {
vpe_log("err: out of memory for post blend gamut remap!");
ret = VPE_STATUS_NO_MEMORY;
goto exit;
}
}
if (param->streams[stream_idx].tm_params.shaper_tf == VPE_TF_PQ_NORMALIZED)
pqNormFactor = stream_ctx->stream.hdr_metadata.max_mastering;
else
pqNormFactor = HDR_PEAK_WHITE;
vpe_color_tm_update_hdr_mult(SHAPER_EXP_MAX_IN, pqNormFactor,
&stream_ctx->lut3d_func->hdr_multiplier, enable_3dlut);
vpe_color_update_shaper(SHAPER_EXP_MAX_IN, stream_ctx->in_shaper_func, enable_3dlut);
vpe_color_update_blnd_gam(
vpe_priv, param, &stream_ctx->stream.tm_params, stream_ctx->blend_tf, enable_3dlut);
vpe_color_build_tm_cs(&stream_ctx->stream.tm_params, param->dst_surface, &tm_out_cs);
vpe_color_get_color_space_and_tf(&tm_out_cs, &out_lut_cs, &tf);
vpe_color_update_gamut(vpe_priv, out_lut_cs, vpe_priv->output_ctx.cs,
output_ctx->gamut_remap, !enable_3dlut);
convert_to_tetrahedral(vpe_priv, param->streams[stream_idx].tm_params.lut_data,
stream_ctx->lut3d_func, enable_3dlut);
stream_ctx->update_3dlut = false;
}
}
exit:
return ret;
}
void vpe_color_get_color_space_and_tf(
const struct vpe_color_space *vcs, enum color_space *cs, enum color_transfer_func *tf)
{
enum vpe_color_range colorRange = vcs->range;
*cs = COLOR_SPACE_UNKNOWN;
*tf = TRANSFER_FUNC_UNKNOWN;
if (vcs->encoding == VPE_PIXEL_ENCODING_YCbCr) {
switch (vcs->tf) {
case VPE_TF_G22:
*tf = TRANSFER_FUNC_SRGB;
break;
case VPE_TF_G24:
*tf = TRANSFER_FUNC_BT1886;
break;
case VPE_TF_PQ:
*tf = TRANSFER_FUNC_PQ2084;
break;
case VPE_TF_PQ_NORMALIZED:
*tf = TRANSFER_FUNC_NORMALIZED_PQ;
default:
break;
}
switch (vcs->primaries) {
case VPE_PRIMARIES_BT601:
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_YCBCR601
: COLOR_SPACE_YCBCR601_LIMITED;
break;
case VPE_PRIMARIES_BT709:
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_YCBCR709
: COLOR_SPACE_YCBCR709_LIMITED;
break;
case VPE_PRIMARIES_BT2020:
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_2020_YCBCR
: COLOR_SPACE_2020_YCBCR_LIMITED;
break;
case VPE_PRIMARIES_JFIF:
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_JFIF : COLOR_SPACE_UNKNOWN;
break;
default:
break;
}
} else {
switch (vcs->tf) {
case VPE_TF_G22:
*tf = TRANSFER_FUNC_SRGB;
break;
case VPE_TF_G24:
*tf = TRANSFER_FUNC_BT1886;
break;
case VPE_TF_PQ:
*tf = TRANSFER_FUNC_PQ2084;
break;
case VPE_TF_PQ_NORMALIZED:
*tf = TRANSFER_FUNC_NORMALIZED_PQ;
break;
case VPE_TF_G10:
*tf = TRANSFER_FUNC_LINEAR_0_125;
break;
default:
break;
}
switch (vcs->primaries) {
case VPE_PRIMARIES_BT709:
if (vcs->tf == VPE_TF_G10) {
*cs = COLOR_SPACE_MSREF_SCRGB;
} else {
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_SRGB
: COLOR_SPACE_SRGB_LIMITED;
}
break;
case VPE_PRIMARIES_BT2020:
*cs = colorRange == VPE_COLOR_RANGE_FULL ? COLOR_SPACE_2020_RGB_FULLRANGE
: COLOR_SPACE_2020_RGB_LIMITEDRANGE;
break;
default:
break;
}
}
}
bool vpe_is_rgb_equal(const struct pwl_result_data *rgb, uint32_t num)
{
uint32_t i;
bool ret = true;
for (i = 0; i < num; i++) {
if (rgb[i].red_reg != rgb[i].green_reg || rgb[i].blue_reg != rgb[i].red_reg ||
rgb[i].blue_reg != rgb[i].green_reg) {
ret = false;
break;
}
}
return ret;
}
void vpe_convert_full_range_color_enum(enum color_space *cs)
{
switch (*cs) {
case COLOR_SPACE_YCBCR601_LIMITED:
*cs = COLOR_SPACE_YCBCR601;
break;
case COLOR_SPACE_YCBCR709_LIMITED:
*cs = COLOR_SPACE_YCBCR709;
break;
case COLOR_SPACE_2020_YCBCR_LIMITED:
*cs = COLOR_SPACE_2020_YCBCR;
break;
case COLOR_SPACE_SRGB_LIMITED:
*cs = COLOR_SPACE_SRGB;
break;
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
*cs = COLOR_SPACE_2020_RGB_FULLRANGE;
break;
default:
break;
}
}
bool vpe_is_HDR(enum color_transfer_func tf)
{
return (tf == TRANSFER_FUNC_PQ2084 || tf == TRANSFER_FUNC_LINEAR_0_125);
}
/*
*
* Pixel processing in VPE can be divided int two main paths. Tone maping cases and non tone mapping
* cases. The gain factor supplied by the below function is only applied in the non-tone mapping
* path.
*
* The gain is used to scale the white point in SDR<->HDR conversions.
*
* The policy is as follows:
* HDR -> SDR (None tone mapping case): Map max input pixel value indicated by HDR meta data to
* value of 1. SDR-> HDR : Map nominal value of 1 to display brightness indicated by metadata.
*
* Table outlining handling for full combination can be found in VPE Wolfpack
*/
enum vpe_status vpe_color_update_whitepoint(
const struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
struct stream_ctx *stream = vpe_priv->stream_ctx;
const struct output_ctx *output_ctx = &vpe_priv->output_ctx;
const struct vpe_color_space *vpe_cs = &stream->stream.surface_info.cs;
bool output_isHDR = vpe_is_HDR(vpe_priv->output_ctx.tf);
bool input_isHDR = false;
bool isYCbCr = false;
bool isG24 = false;
for (unsigned int stream_index = 0; stream_index < vpe_priv->num_streams; stream_index++) {
input_isHDR = vpe_is_HDR(stream->tf);
isYCbCr = (vpe_cs->encoding == VPE_PIXEL_ENCODING_YCbCr);
isG24 = (vpe_cs->tf == VPE_TF_G24);
if (!input_isHDR && output_isHDR) {
int sdrWhiteLevel = (isYCbCr || isG24) ? SDR_VIDEO_WHITE_POINT : SDR_WHITE_POINT;
stream->white_point_gain = vpe_fixpt_from_fraction(sdrWhiteLevel, 10000);
} else if (input_isHDR && !output_isHDR) {
stream->white_point_gain = stream->stream.hdr_metadata.max_mastering != 0
? vpe_fixpt_from_fraction(HDR_PEAK_WHITE,
stream->stream.hdr_metadata.max_mastering)
: vpe_fixpt_one;
} else {
stream->white_point_gain = vpe_fixpt_one;
}
stream++;
}
return VPE_STATUS_OK;
}
+363
View File
@@ -0,0 +1,363 @@
#include <string.h>
#include <math.h>
#include "color_bg.h"
struct csc_vector {
float x;
float y;
float z;
};
struct csc_table {
struct csc_vector rgb_offset; // RGB offset
struct csc_vector red_coef; // RED coefficient
struct csc_vector green_coef; // GREEN coefficient
struct csc_vector blue_coef; // BLUE coefficient
};
static struct csc_table bgcolor_to_rgbfull_table[COLOR_SPACE_MAX] = {
[COLOR_SPACE_YCBCR601] =
{
{0.0f, -0.5f, -0.5f},
{1.0f, 0.0f, 1.402f},
{1.0f, -0.344136286f, -0.714136286f},
{1.0f, 1.772f, 0.0f},
},
[COLOR_SPACE_YCBCR709] =
{
{0.0f, -0.5f, -0.5f},
{1.0f, 0.0f, 1.5748f},
{1.0f, -0.187324273f, -0.468124273f},
{1.0f, 1.8556f, 0.0f},
},
[COLOR_SPACE_YCBCR601_LIMITED] =
{
{-0.0625f, -0.5f, -0.5f},
{1.164383562f, 0.0f, 1.596026786f},
{1.164383562f, -0.39176229f, -0.812967647f},
{1.164383562f, 2.017232143f, 0.0f},
},
[COLOR_SPACE_YCBCR709_LIMITED] =
{
{-0.0625f, -0.5f, -0.5f},
{1.164383562f, 0.0f, 1.792741071f},
{1.164383562f, -0.213248614f, -0.532909329f},
{1.164383562f, 2.112401786f, 0.0f},
},
[COLOR_SPACE_2020_YCBCR] =
{
{0.0f, -512.f / 1023.f, -512.f / 1023.f},
{1.0f, 0.0f, 1.4746f},
{1.0f, -0.164553127f, -0.571353127f},
{1.0f, 1.8814f, 0.0f},
},
[COLOR_SPACE_2020_YCBCR_LIMITED] =
{
{-0.0625f, -0.5f, -0.5f},
{1.167808219f, 0.0f, 1.683611384f},
{1.167808219f, -0.187877063f, -0.652337331f},
{1.167808219f, 2.148071652f, 0.0f},
},
[COLOR_SPACE_SRGB_LIMITED] =
{
{-0.0626221f, -0.0626221f, -0.0626221f},
{1.167783652f, 0.0f, 0.0f},
{0.0f, 1.167783652f, 0.0f},
{0.0f, 0.0, 1.167783652f},
},
[COLOR_SPACE_2020_RGB_LIMITEDRANGE] = {
{-0.0626221f, -0.0626221f, -0.0626221f},
{1.167783652f, 0.0f, 0.0f},
{0.0f, 1.167783652f, 0.0f},
{0.0f, 0.0, 1.167783652f},
}};
static double clip_double(double x)
{
if (x < 0.0)
return 0.0;
else if (x > 1.0)
return 1.0;
else
return x;
}
static float clip_float(float x)
{
if (x < 0.0f)
return 0.0f;
else if (x > 1.0f)
return 1.0f;
else
return x;
}
static bool bg_csc(struct vpe_color *bg_color, enum color_space cs)
{
struct csc_table *entry = &bgcolor_to_rgbfull_table[cs];
float csc_final[3] = {0};
float csc_mm[3][4] = {0};
bool output_is_clipped = false;
memcpy(&csc_mm[0][0], &entry->red_coef, sizeof(struct csc_vector));
memcpy(&csc_mm[1][0], &entry->green_coef, sizeof(struct csc_vector));
memcpy(&csc_mm[2][0], &entry->blue_coef, sizeof(struct csc_vector));
csc_mm[0][3] = entry->rgb_offset.x * csc_mm[0][0] + entry->rgb_offset.y * csc_mm[0][1] +
entry->rgb_offset.z * csc_mm[0][2];
csc_mm[1][3] = entry->rgb_offset.x * csc_mm[1][0] + entry->rgb_offset.y * csc_mm[1][1] +
entry->rgb_offset.z * csc_mm[1][2];
csc_mm[2][3] = entry->rgb_offset.x * csc_mm[2][0] + entry->rgb_offset.y * csc_mm[2][1] +
entry->rgb_offset.z * csc_mm[2][2];
csc_final[0] = csc_mm[0][0] * bg_color->ycbcra.y + csc_mm[0][1] * bg_color->ycbcra.cb +
csc_mm[0][2] * bg_color->ycbcra.cr + csc_mm[0][3];
csc_final[1] = csc_mm[1][0] * bg_color->ycbcra.y + csc_mm[1][1] * bg_color->ycbcra.cb +
csc_mm[1][2] * bg_color->ycbcra.cr + csc_mm[1][3];
csc_final[2] = csc_mm[2][0] * bg_color->ycbcra.y + csc_mm[2][1] * bg_color->ycbcra.cb +
csc_mm[2][2] * bg_color->ycbcra.cr + csc_mm[2][3];
// switch to RGB components
bg_color->rgba.a = bg_color->ycbcra.a;
bg_color->rgba.r = clip_float(csc_final[0]);
bg_color->rgba.g = clip_float(csc_final[1]);
bg_color->rgba.b = clip_float(csc_final[2]);
if ((bg_color->rgba.r != csc_final[0]) || (bg_color->rgba.g != csc_final[1]) ||
(bg_color->rgba.b != csc_final[2])) {
output_is_clipped = true;
}
bg_color->is_ycbcr = false;
return output_is_clipped;
}
struct gamma_coefs {
float a0;
float a1;
float a2;
float a3;
float user_gamma;
float user_contrast;
float user_brightness;
};
// srgb, 709, G24
static const int32_t numerator01[] = {31308, 180000, 0};
static const int32_t numerator02[] = {12920, 4500, 0};
static const int32_t numerator03[] = {55, 99, 0};
static const int32_t numerator04[] = {55, 99, 0};
static const int32_t numerator05[] = {2400, 2222, 2400};
static bool build_coefficients(struct gamma_coefs *coefficients, enum color_transfer_func type)
{
uint32_t index = 0;
bool ret = true;
if (type == TRANSFER_FUNC_SRGB)
index = 0;
else if (type == TRANSFER_FUNC_BT709)
index = 1;
else if (type == TRANSFER_FUNC_BT1886)
index = 2;
else {
ret = false;
goto release;
}
coefficients->a0 = (float)numerator01[index] / 10000000.0f;
coefficients->a1 = (float)numerator02[index] / 1000.0f;
coefficients->a2 = (float)numerator03[index] / 1000.0f;
coefficients->a3 = (float)numerator04[index] / 1000.0f;
coefficients->user_gamma = (float)numerator05[index] / 1000.0f;
release:
return ret;
}
static double translate_to_linear_space(
double arg, double a0, double a1, double a2, double a3, double gamma)
{
double linear;
double base;
a0 *= a1;
if (arg <= -a0) {
base = (a2 - arg) / (1.0 + a3);
linear = -pow(base, gamma);
} else if ((-a0 <= arg) && (arg <= a0))
linear = arg / a1;
else {
base = (a2 + arg) / (1.0 + a3);
linear = pow(base, gamma);
}
return linear;
}
// for 709 & sRGB
static void compute_degam(enum color_transfer_func tf, double inY, double *outX, bool clip)
{
double ret;
struct gamma_coefs coefs = {0};
build_coefficients(&coefs, tf);
ret = translate_to_linear_space(inY, (double)coefs.a0, (double)coefs.a1, (double)coefs.a2,
(double)coefs.a3, (double)coefs.user_gamma);
if (clip) {
ret = clip_double(ret);
}
*outX = ret;
}
static double get_maximum_fp(double a, double b)
{
if (a > b)
return a;
return b;
}
static void compute_depq(double inY, double *outX, bool clip)
{
double M1 = 0.159301758;
double M2 = 78.84375;
double C1 = 0.8359375;
double C2 = 18.8515625;
double C3 = 18.6875;
double nPowM2;
double base;
double one = 1.0;
double zero = 0.0;
bool negative = false;
double ret;
if (inY < zero) {
inY = -inY;
negative = true;
}
nPowM2 = pow(inY, one / M2);
base = get_maximum_fp(nPowM2 - C1, zero) / (C2 - C3 * nPowM2);
ret = pow(base, one / M1);
if (clip) {
ret = clip_double(ret);
}
if (negative)
ret = -ret;
*outX = ret;
}
static bool is_rgb_limited(enum color_space cs)
{
return (cs == COLOR_SPACE_SRGB_LIMITED || cs == COLOR_SPACE_2020_RGB_LIMITEDRANGE);
}
void vpe_bg_color_convert(
enum color_space output_cs, struct transfer_func *output_tf, struct vpe_color *bg_color)
{
enum color_space bgcolor_cs;
if (bg_color->is_ycbcr) {
// Need YUV to RGB csc as internal pipe is using RGB full range
// For range conversion, if output is limited, we assume bg color
// is limited range too
switch (output_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:
bgcolor_cs = output_cs;
break;
// output is RGB cs, follow output's range
// but need yuv to rgb csc
case COLOR_SPACE_SRGB_LIMITED:
bgcolor_cs = COLOR_SPACE_YCBCR709_LIMITED;
break;
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
bgcolor_cs = COLOR_SPACE_2020_YCBCR_LIMITED;
break;
case COLOR_SPACE_SRGB:
case COLOR_SPACE_MSREF_SCRGB:
bgcolor_cs = COLOR_SPACE_YCBCR709;
break;
case COLOR_SPACE_2020_RGB_FULLRANGE:
bgcolor_cs = COLOR_SPACE_2020_YCBCR;
break;
default:
// should revise the newly added CS
// and set corresponding bgcolor_cs accordingly
VPE_ASSERT(0);
bgcolor_cs = COLOR_SPACE_YCBCR709;
break;
}
} else {
// RGB BG color, use output's cs for range check
bgcolor_cs = output_cs;
}
// input is [0-0xffff]
// convert bg color to RGB full range for use inside pipe
if (bg_color->is_ycbcr || is_rgb_limited(bgcolor_cs))
bg_csc(bg_color, bgcolor_cs);
if (output_tf->type == TF_TYPE_DISTRIBUTED_POINTS) {
double degam_r = 0;
double degam_g = 0;
double degam_b = 0;
// de-gam
switch (output_tf->tf) {
case TRANSFER_FUNC_SRGB:
case TRANSFER_FUNC_BT709:
case TRANSFER_FUNC_BT1886:
compute_degam(output_tf->tf, (double)bg_color->rgba.r, &degam_r, true);
compute_degam(output_tf->tf, (double)bg_color->rgba.g, &degam_g, true);
compute_degam(output_tf->tf, (double)bg_color->rgba.b, &degam_b, true);
bg_color->rgba.r = (float)degam_r;
bg_color->rgba.g = (float)degam_g;
bg_color->rgba.b = (float)degam_b;
break;
case TRANSFER_FUNC_PQ2084:
compute_depq((double)bg_color->rgba.r, &degam_r, true);
compute_depq((double)bg_color->rgba.g, &degam_g, true);
compute_depq((double)bg_color->rgba.b, &degam_b, true);
bg_color->rgba.r = (float)degam_r;
bg_color->rgba.g = (float)degam_g;
bg_color->rgba.b = (float)degam_b;
break;
case TRANSFER_FUNC_LINEAR_0_125:
break;
default:
VPE_ASSERT(0);
break;
}
}
// for TF_TYPE_BYPASS, bg color should be programmed to mpc as linear
}
enum vpe_status vpe_bg_color_outside_cs_gamut(
const struct vpe_color_space *vcs, struct vpe_color *bg_color)
{
enum color_space cs;
enum color_transfer_func tf;
struct vpe_color bg_color_copy = *bg_color;
vpe_color_get_color_space_and_tf(vcs, &cs, &tf);
if (is_rgb_limited(cs) || (bg_color->is_ycbcr)) {
// using the bg_color_copy instead as bg_csc will modify it
// we should not do modification in checking stage
// otherwise validate_cached_param() will fail
if (bg_csc(&bg_color_copy, cs)) {
return VPE_STATUS_BG_COLOR_OUT_OF_RANGE;
}
}
return VPE_STATUS_OK;
}
+744
View File
@@ -0,0 +1,744 @@
/* 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 "color.h"
#include "color_cs.h"
#include "hw_shared.h"
#include "conversion.h"
#define DIVIDER 10000
/* S2D13 value in [-3.999...3.999] */
#define S2D13_MIN (-39990)
#define S2D13_MAX (39990)
static void translate_blt_to_internal_adjustments(
const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust);
/* these values are defaults: 0 brightness, 1 contrast, 0 hue, 1 saturation*/
static struct vpe_color_adjust defaultClrAdjust = {0.0f, 1.0f, 0.0f, 1.0f};
void vpe_color_set_adjustments_to_default(struct vpe_color_adjust *crt_vpe_adjusts)
{
*crt_vpe_adjusts = defaultClrAdjust;
}
bool vpe_color_different_color_adjusts(
const struct vpe_color_adjust *new_vpe_adjusts, struct vpe_color_adjust *crt_vpe_adjsuts)
{
if ((crt_vpe_adjsuts->brightness != new_vpe_adjusts->brightness) ||
(crt_vpe_adjsuts->saturation != new_vpe_adjusts->saturation) ||
(crt_vpe_adjsuts->hue != new_vpe_adjusts->hue) ||
(crt_vpe_adjsuts->contrast != new_vpe_adjusts->contrast)) {
return true;
}
return false;
}
/**
* Adjustment Min Max default step
*
* Input range
* Brightness -100.0f, 100.0f, 0.0f, 0.1f
* Contrast 0.0f, 2.0f, 1.0f, 0.01f
* Hue -180.0f, 180.0f, 0.0f, 1.0f
* Saturation 0.0f, 3.0f, 1.0f, 0.01f
*
* DAL range
* Brightness -100, 100, 0, 1
* Contrast 0, 200, 100, 1
* Hue -30, 30, 0, 1
* Saturation 0, 200, 100, 1
*/
static void translate_blt_to_internal_adjustments(
const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust)
{
dal_adjust->brightness.current = (int)(10 * blt_adjust->brightness);
dal_adjust->brightness.min = -1000;
dal_adjust->brightness.max = 1000;
dal_adjust->contrast.current = (int)(100 * blt_adjust->contrast);
dal_adjust->contrast.min = 0;
dal_adjust->contrast.max = 200;
dal_adjust->saturation.current = (int)(100 * blt_adjust->saturation);
dal_adjust->saturation.min = 0;
dal_adjust->saturation.max = 300; // assuming input bigger range
dal_adjust->hue.current = (int)(blt_adjust->hue);
dal_adjust->hue.min = -180;
dal_adjust->hue.max = 180; // assuming input bigger range
}
static int get_hw_value_from_sw_value(int swVal, int swMin, int swMax, int hwMin, int hwMax)
{
int dSW = swMax - swMin; /*software adjustment range size*/
int dHW = hwMax - hwMin; /*hardware adjustment range size*/
int hwVal; /*HW adjustment value*/
/* error case, I preserve the behavior from the predecessor
*getHwStepFromSwHwMinMaxValue (removed in Feb 2013)
*which was the FP version that only computed SCLF (i.e. dHW/dSW).
*it would return 0 in this case so
*hwVal = hwMin from the formula given in @brief
*/
if (dSW == 0)
return hwMin;
/*it's quite often that ranges match,
*e.g. for overlay colors currently (Feb 2013)
*only brightness has a different
*HW range, and in this case no multiplication or division is needed,
*and if minimums match, no calculation at all
*/
if (dSW != dHW) {
hwVal = (swVal - swMin) * dHW / dSW + hwMin;
} else {
hwVal = swVal;
if (swMin != hwMin)
hwVal += (hwMin - swMin);
}
return hwVal;
}
static void color_adjustments_to_fixed_point(const struct vpe_color_adjustments *vpe_adjust,
bool icsc, // input csc or output csc
struct fixed31_32 *grph_cont, struct fixed31_32 *grph_sat, struct fixed31_32 *grph_bright,
struct fixed31_32 *sin_grph_hue, struct fixed31_32 *cos_grph_hue)
{
/* Hue adjustment could be negative. -45 ~ +45 */
struct fixed31_32 hue;
const int hw_hue_min = -30;
const int hw_hue_max = 30;
const int hw_sat_min = 0;
const int hw_sat_max = 200;
const int hw_contrast_min = 0;
const int hw_contrast_max = 200;
const int hw_bright_min = -1000;
const int hw_bright_max = 1000;
if (icsc) {
hue = vpe_fixpt_mul(
vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
180),
vpe_fixpt_pi);
// In MMD is -100 to +100 in 16-235 range; which when scaled to full
// range is ~-116 to +116. When normalized this is about 0.4566.
*grph_bright = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
1000);
*grph_cont = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
100);
*grph_sat = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
100);
} else {
hue = vpe_fixpt_mul(
vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
180),
vpe_fixpt_pi);
*grph_bright = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
100);
*grph_cont = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
100);
*grph_sat = vpe_fixpt_from_fraction(
get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
100);
}
*sin_grph_hue = vpe_fixpt_sin(hue);
*cos_grph_hue = vpe_fixpt_cos(hue);
}
static void calculate_rgb_matrix_legacy(
struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
{
const struct fixed31_32 k1 = vpe_fixpt_from_fraction(787400, 1000000);
const struct fixed31_32 k2 = vpe_fixpt_from_fraction(180428, 1000000);
const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-715200, 1000000);
const struct fixed31_32 k4 = vpe_fixpt_from_fraction(606972, 1000000);
const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-72200, 1000000);
const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-787400, 1000000);
const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-212600, 1000000);
const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-147296, 1000000);
const struct fixed31_32 k9 = vpe_fixpt_from_fraction(284800, 1000000);
const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-95354, 1000000);
const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-72200, 1000000);
const struct fixed31_32 k12 = vpe_fixpt_from_fraction(242650, 1000000);
const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-212600, 1000000);
const struct fixed31_32 k14 = vpe_fixpt_from_fraction(927800, 1000000);
const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-715200, 1000000);
const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-842726, 1000000);
const struct fixed31_32 k17 = vpe_fixpt_from_fraction(927800, 1000000);
const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-85074, 1000000);
const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(2126, 10000);
const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(7152, 10000);
const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(722, 10000);
struct fixed31_32 grph_cont;
struct fixed31_32 grph_sat;
struct fixed31_32 grph_bright;
struct fixed31_32 sin_grph_hue;
struct fixed31_32 cos_grph_hue;
color_adjustments_to_fixed_point(
vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
/* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
/* Sin(GrphHue) * K2))*/
/* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
/* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
/* K2))*/
rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
/* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
/* Sin(GrphHue) * K4))*/
/* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
/* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
/* K4))*/
rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
/* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
/* Sin(GrphHue) * K6))*/
/* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
/* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
/* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
/* K6))*/
rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
/* COEF_1_4 = GrphBright*/
rgb_matrix[3] = grph_bright;
/* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
/* Sin(GrphHue) * K8))*/
/* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
/* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
/* K8))*/
rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
/* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
/* Sin(GrphHue) * K10))*/
/* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
/* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
/* K10))*/
rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
/* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
/* Sin(GrphHue) * K12))*/
/* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
/* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
/* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
/* K12))*/
rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
/* COEF_2_4 = GrphBright*/
rgb_matrix[7] = grph_bright;
/* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
/* Sin(GrphHue) * K14))*/
/* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
/* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
/* K14)) */
rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
/* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
/* Sin(GrphHue) * K16)) */
/* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
rgb_matrix[9] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
/* K16)) */
rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
/* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
/* Sin(GrphHue) * K18)) */
/* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
/* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
/* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
/* K18)) */
rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
/* COEF_3_4 = GrphBright */
rgb_matrix[11] = grph_bright;
}
static void calculate_rgb_limited_range_matrix_legacy(
struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
{
const struct fixed31_32 k1 = vpe_fixpt_from_fraction(701000, 1000000);
const struct fixed31_32 k2 = vpe_fixpt_from_fraction(236568, 1000000);
const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-587000, 1000000);
const struct fixed31_32 k4 = vpe_fixpt_from_fraction(464432, 1000000);
const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-114000, 1000000);
const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-701000, 1000000);
const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-299000, 1000000);
const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-292569, 1000000);
const struct fixed31_32 k9 = vpe_fixpt_from_fraction(413000, 1000000);
const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-92482, 1000000);
const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-114000, 1000000);
const struct fixed31_32 k12 = vpe_fixpt_from_fraction(385051, 1000000);
const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-299000, 1000000);
const struct fixed31_32 k14 = vpe_fixpt_from_fraction(886000, 1000000);
const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-587000, 1000000);
const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-741914, 1000000);
const struct fixed31_32 k17 = vpe_fixpt_from_fraction(886000, 1000000);
const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-144086, 1000000);
const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(299, 1000);
const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(587, 1000);
const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(114, 1000);
/*onst struct fixed31_32 luma_scale =
vpe_fixpt_from_fraction(875855, 1000000);*/
const struct fixed31_32 rgb_scale = vpe_fixpt_from_fraction(85546875, 100000000);
const struct fixed31_32 rgb_bias = vpe_fixpt_from_fraction(625, 10000);
struct fixed31_32 grph_cont;
struct fixed31_32 grph_sat;
struct fixed31_32 grph_bright;
struct fixed31_32 sin_grph_hue;
struct fixed31_32 cos_grph_hue;
color_adjustments_to_fixed_point(
vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
/* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
/* Sin(GrphHue) * K2))*/
/* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
/* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
/* K2))*/
rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
/* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + */
/* Sin(GrphHue) * K2))*/
rgb_matrix[0] = vpe_fixpt_mul(rgb_scale, rgb_matrix[0]);
/* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
/* Sin(GrphHue) * K4))*/
/* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
/* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
/* K4))*/
rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
/* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K3 + */
/* Sin(GrphHue) * K4))*/
rgb_matrix[1] = vpe_fixpt_mul(rgb_scale, rgb_matrix[1]);
/* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
/* Sin(GrphHue) * K6))*/
/* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
/* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
/* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
/* K6))*/
rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
/* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K5 + */
/* Sin(GrphHue) * K6))*/
rgb_matrix[2] = vpe_fixpt_mul(rgb_scale, rgb_matrix[2]);
/* COEF_1_4 = RGBBias + RGBScale * GrphBright*/
rgb_matrix[3] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
/* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
/* Sin(GrphHue) * K8))*/
/* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
/* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
/* K8))*/
rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
/* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + */
/* Sin(GrphHue) * K8))*/
rgb_matrix[4] = vpe_fixpt_mul(rgb_scale, rgb_matrix[4]);
/* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
/* Sin(GrphHue) * K10))*/
/* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
/* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
/* K10))*/
rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
/* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K9 + */
/* Sin(GrphHue) * K10))*/
rgb_matrix[5] = vpe_fixpt_mul(rgb_scale, rgb_matrix[5]);
/* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
/* Sin(GrphHue) * K12))*/
/* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
/* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
/* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
/* K12))*/
rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
/* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K11 +*/
/* Sin(GrphHue) * K12)) */
rgb_matrix[6] = vpe_fixpt_mul(rgb_scale, rgb_matrix[6]);
/* COEF_2_4 = RGBBias + RGBScale * GrphBright*/
rgb_matrix[7] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
/* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
/* Sin(GrphHue) * K14))*/
/* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
/* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
/* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
/* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
/* K14)) */
rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
/* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
/* Sin(GrphHue) * K14))*/
rgb_matrix[8] = vpe_fixpt_mul(rgb_scale, rgb_matrix[8]);
/* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
/* Sin(GrphHue) * K16)) */
/* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
rgb_matrix[9] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
/* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
/* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
/* K16)) */
rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
/* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K15 + */
/* Sin(GrphHue) * K16))*/
rgb_matrix[9] = vpe_fixpt_mul(rgb_scale, rgb_matrix[9]);
/* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
/* Sin(GrphHue) * K18)) */
/* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] =
vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
/* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
/* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
/* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
/* K18)) */
rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
/* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * */
/* K17 + Sin(GrphHue) * K18))*/
rgb_matrix[10] = vpe_fixpt_mul(rgb_scale, rgb_matrix[10]);
/* COEF_3_4 = RGBBias + RGBScale * GrphBright */
rgb_matrix[11] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
}
/* this function scales the matrix coefficients to fit a maximum integer bit range*/
static bool vpe_scale_csc_matrix(struct fixed31_32 *matrix, unsigned int matrixLength,
unsigned int maxIntegerBits, struct fixed31_32 *scalingFactor)
{
bool ret = false;
unsigned int index = 0;
long long maxIntegerVal = ((long long)1 << maxIntegerBits);
long long maxMatrixVal = 0;
unsigned int crtIntPart = 0;
struct fixed31_32 divisionFactor = vpe_fixpt_one;
long long crtValue = 0;
unsigned int posLargestBit = 0;
(*scalingFactor) = vpe_fixpt_one; // by default this is initialized to one
for (index = 0; index < matrixLength; index++) {
crtValue = matrix[index].value;
if (crtValue < 0) {
crtValue = -crtValue;
}
crtIntPart = (crtValue >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
if (maxMatrixVal < crtIntPart) {
maxMatrixVal = crtIntPart;
}
}
if ((maxMatrixVal >= maxIntegerVal) && (maxIntegerVal > 0)) {
for (index = 0; index < (FIXED31_32_BITS_PER_FRACTIONAL_PART - 1); index++) {
if (maxMatrixVal & ((long long)1 << index)) { // scan all the bits
posLargestBit = index;
}
}
divisionFactor.value = (long long)1 << (posLargestBit - maxIntegerBits + 1);
divisionFactor.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
(*scalingFactor) = divisionFactor;
for (index = 0; index < matrixLength; index++) {
matrix[index] = vpe_fixpt_div(matrix[index], divisionFactor);
}
ret = true;
}
return ret;
}
static void calculate_yuv_matrix(struct vpe_color_adjustments *vpe_adjust,
enum color_space color_space, struct vpe_csc_matrix *input_cs, struct fixed31_32 *yuv_matrix)
{
struct fixed31_32 initialMatrix[12];
uint32_t i = 0;
bool ovl = true; // if we ever have Output CSC case, we can reuse this function with ovl passed
// in as param
struct fixed31_32 grph_cont;
struct fixed31_32 grph_sat;
struct fixed31_32 grph_bright;
struct fixed31_32 sin_grph_hue;
struct fixed31_32 cos_grph_hue;
struct fixed31_32 multiplier;
struct fixed31_32 chromaOffset = vpe_fixpt_sub(vpe_fixpt_half, vpe_fixpt_one); // = -0.5
struct fixed31_32 lumaOffset = {
0x10101010LL}; //=16/255.0 This is an offset applied in the shader, not clear why
// to maintain compatibility this offset is still applied in VPE
/* The input YCbCr to RGB matrix is modified to embed the color adjustments as follows:
A = initial YCbCr to RGB conversion matrix
s = saturation , h = hue, c = contrast, b = brightness
| c*s*(a11*cos(h)+a13*sin(h)) a12*c c*s(a13*cos(h)-a11*sin(h)) |
|R| | | |Y+b |
|G|= | c*s*(a21*cos(h)+a23*sin(h)) a22*c c*s(a23*cos(h)-a21*sin(h)) | * |Cb-0.5|
|B| | | |Cr-0.5|
| c*s*(a31*cos(h)+a33*sin(h)) a32*c c*s(a33*cos(h)-a31*sin(h)) |
*/
for (i = 0; i < 12; i++) {
initialMatrix[i] = vpe_convfix31_32(input_cs->regval[i]); // convert from s.2.13 to s.31.32
}
color_adjustments_to_fixed_point(
vpe_adjust, ovl, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
grph_bright = vpe_fixpt_sub(grph_bright, lumaOffset);
multiplier = vpe_fixpt_mul(grph_cont, grph_sat); // contSat
yuv_matrix[0] =
vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[0], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[2], sin_grph_hue)));
yuv_matrix[1] = vpe_fixpt_mul(initialMatrix[1], grph_cont);
yuv_matrix[2] =
vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[2], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[0], sin_grph_hue)));
yuv_matrix[3] = initialMatrix[3];
yuv_matrix[4] =
vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[4], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[6], sin_grph_hue)));
yuv_matrix[5] = vpe_fixpt_mul(initialMatrix[5], grph_cont);
yuv_matrix[6] =
vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[6], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[4], sin_grph_hue)));
yuv_matrix[7] = initialMatrix[7];
yuv_matrix[8] =
vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[8], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[10], sin_grph_hue)));
yuv_matrix[9] = vpe_fixpt_mul(initialMatrix[9], grph_cont);
yuv_matrix[10] =
vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[10], cos_grph_hue),
vpe_fixpt_mul(initialMatrix[8], sin_grph_hue)));
yuv_matrix[3] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[1]),
vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[0]),
vpe_fixpt_mul(chromaOffset, yuv_matrix[2])));
yuv_matrix[7] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[5]),
vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[4]),
vpe_fixpt_mul(chromaOffset, yuv_matrix[6])));
yuv_matrix[11] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[9]),
vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[8]),
vpe_fixpt_mul(chromaOffset, yuv_matrix[10])));
}
static void convert_float_matrix(uint16_t *matrix, struct fixed31_32 *flt, uint32_t buffer_size)
{
const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
uint32_t i;
uint16_t temp_matrix[12];
for (i = 0; i < 12; i++)
temp_matrix[i] = 0;
for (i = 0; i < buffer_size; ++i) {
uint32_t reg_value =
conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
temp_matrix[i] = (uint16_t)reg_value;
}
matrix[4] = temp_matrix[0];
matrix[5] = temp_matrix[1];
matrix[6] = temp_matrix[2];
matrix[7] = temp_matrix[3];
matrix[8] = temp_matrix[4];
matrix[9] = temp_matrix[5];
matrix[10] = temp_matrix[6];
matrix[11] = temp_matrix[7];
matrix[0] = temp_matrix[8];
matrix[1] = temp_matrix[9];
matrix[2] = temp_matrix[10];
matrix[3] = temp_matrix[11];
}
bool vpe_color_calculate_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
const struct vpe_color_adjust *vpe_blt_adjust, struct vpe_csc_matrix *input_cs,
struct fixed31_32 *matrix_scaling_factor)
{
struct fixed31_32 fixed_csc_matrix[12];
struct vpe_color_adjustments vpe_adjust = {0};
if (vpe_blt_adjust) {
translate_blt_to_internal_adjustments(vpe_blt_adjust, &vpe_adjust);
}
switch (in_cs) {
case COLOR_SPACE_SRGB:
case COLOR_SPACE_2020_RGB_FULLRANGE:
case COLOR_SPACE_MSREF_SCRGB:
case COLOR_SPACE_SRGB_LIMITED:
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
break;
case COLOR_SPACE_YCBCR601:
case COLOR_SPACE_YCBCR709:
case COLOR_SPACE_YCBCR601_LIMITED:
case COLOR_SPACE_YCBCR709_LIMITED:
case COLOR_SPACE_2020_YCBCR:
calculate_yuv_matrix(&vpe_adjust, in_cs, input_cs, fixed_csc_matrix);
if (vpe_priv->scale_yuv_matrix) { // in case the coefficitents are too large
// they are scaled down to fit the n integer bits, m
// fractional bits (for now 2.19)
vpe_log("Scale down YUV -> RGB matrix");
vpe_scale_csc_matrix(fixed_csc_matrix, 12, 2, matrix_scaling_factor);
} else {
vpe_log("No scaling on the yuv -> rgb matrix");
}
break;
default:
calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
break;
}
conv_convert_float_matrix(&input_cs->regval[0], fixed_csc_matrix, 12);
return true;
}
+623
View File
@@ -0,0 +1,623 @@
/* 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 "color.h"
#include "color_gamma.h"
#include "hw_shared.h"
#define PRECISE_LUT_REGION_START 224
#define PRECISE_LUT_REGION_END 239
static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
static struct hw_x_point coordinates_x_degamma[MAX_HW_POINTS_DEGAMMA];
// these are helpers for calculations to reduce stack usage
// do not depend on these being preserved across calls
/* Helper to optimize gamma calculation, only use in translate_from_linear, in
* particular the vpe_fixpt_pow function which is very expensive
* The idea is that our regions for X points are exponential and currently they all use
* the same number of points (NUM_PTS_IN_REGION) and in each region every point
* is exactly 2x the one at the same index in the previous region. In other words
* X[i] = 2 * X[i-NUM_PTS_IN_REGION] for i>=16
* The other fact is that (2x)^gamma = 2^gamma * x^gamma
* So we compute and save x^gamma for the first 16 regions, and for every next region
* just multiply with 2^gamma which can be computed once, and save the result so we
* recursively compute all the values.
*/
/*
* Regamma coefficients are used for both regamma and degamma. Degamma
* coefficients are calculated in our formula using the regamma coefficients.
*/
/*sRGB 709 2.2 2.4 P3*/
static const int32_t numerator01[] = {31308, 180000, 0, 0, 0};
static const int32_t numerator02[] = {12920, 4500, 0, 0, 0};
static const int32_t numerator03[] = {55, 99, 0, 0, 0};
static const int32_t numerator04[] = {55, 99, 0, 0, 0};
static const int32_t numerator05[] = {
2400, 2222, 2200, 2400, 2600}; // the standard REC 709 states 0.45. Inverse of that is 2.22
/* one-time setup of X points */
void vpe_color_setup_x_points_distribution(void)
{
struct fixed31_32 region_size = vpe_fixpt_from_int(128);
int32_t segment;
uint32_t seg_offset;
uint32_t index;
struct fixed31_32 increment;
coordinates_x[MAX_HW_POINTS].x = region_size;
coordinates_x[MAX_HW_POINTS + 1].x = region_size;
for (segment = 6; segment > (6 - NUM_REGIONS); segment--) {
region_size = vpe_fixpt_div_int(region_size, 2);
increment = vpe_fixpt_div_int(region_size, NUM_PTS_IN_REGION);
seg_offset = (uint32_t)((segment + (NUM_REGIONS - 7)) * NUM_PTS_IN_REGION);
coordinates_x[seg_offset].x = region_size;
for (index = seg_offset + 1; index < seg_offset + NUM_PTS_IN_REGION; index++) {
coordinates_x[index].x = vpe_fixpt_add(coordinates_x[index - 1].x, increment);
}
}
}
/* Setting up x points for DEGAMMA once */
void vpe_color_setup_x_points_distribution_degamma(void)
{
struct fixed31_32 region_size = vpe_fixpt_from_int(1);
int32_t segment;
uint32_t index = 0;
uint32_t numptsdegamma = 1;
uint32_t segment_offset;
/* Since region = -8 only has 1 point setting it up before the loop */
coordinates_x_degamma[0].x = vpe_fixpt_div(vpe_fixpt_from_int(1), vpe_fixpt_from_int(512));
for (segment = -7; segment <= 0; segment++) {
segment_offset = numptsdegamma;
numptsdegamma *= 2;
for (index = segment_offset; index < numptsdegamma; index++) {
coordinates_x_degamma[index].x =
vpe_fixpt_div(vpe_fixpt_from_int(index), vpe_fixpt_from_int(256));
}
}
coordinates_x_degamma[MAX_HW_POINTS_DEGAMMA - 1].x = region_size;
}
void vpe_compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
{
/* consts for PQ gamma formula. */
const struct fixed31_32 m1 = vpe_fixpt_from_fraction(159301758, 1000000000);
const struct fixed31_32 m2 = vpe_fixpt_from_fraction(7884375, 100000);
const struct fixed31_32 c1 = vpe_fixpt_from_fraction(8359375, 10000000);
const struct fixed31_32 c2 = vpe_fixpt_from_fraction(188515625, 10000000);
const struct fixed31_32 c3 = vpe_fixpt_from_fraction(186875, 10000);
struct fixed31_32 l_pow_m1;
struct fixed31_32 base;
if (vpe_fixpt_le(vpe_fixpt_one, in_x)) {
*out_y = vpe_fixpt_one;
return;
}
if (vpe_fixpt_lt(in_x, vpe_fixpt_zero))
in_x = vpe_fixpt_zero;
l_pow_m1 = vpe_fixpt_pow(in_x, m1);
base = vpe_fixpt_div(vpe_fixpt_add(c1, (vpe_fixpt_mul(c2, l_pow_m1))),
vpe_fixpt_add(vpe_fixpt_one, (vpe_fixpt_mul(c3, l_pow_m1))));
*out_y = vpe_fixpt_pow(base, m2);
}
static void compute_de_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
{
/* consts for dePQ gamma formula. */
const struct fixed31_32 m1 = vpe_fixpt_from_fraction(159301758, 1000000000);
const struct fixed31_32 m2 = vpe_fixpt_from_fraction(7884375, 100000);
const struct fixed31_32 c1 = vpe_fixpt_from_fraction(8359375, 10000000);
const struct fixed31_32 c2 = vpe_fixpt_from_fraction(188515625, 10000000);
const struct fixed31_32 c3 = vpe_fixpt_from_fraction(186875, 10000);
struct fixed31_32 l_pow_m1;
struct fixed31_32 base, div;
struct fixed31_32 base2;
if (vpe_fixpt_lt(in_x, vpe_fixpt_zero))
in_x = vpe_fixpt_zero;
if (vpe_fixpt_le(vpe_fixpt_one, in_x)) {
*out_y = vpe_fixpt_one;
return;
}
l_pow_m1 = vpe_fixpt_pow(in_x, vpe_fixpt_div(vpe_fixpt_one, m2));
base = vpe_fixpt_sub(l_pow_m1, c1);
div = vpe_fixpt_sub(c2, vpe_fixpt_mul(c3, l_pow_m1));
base2 = vpe_fixpt_div(base, div);
// avoid complex numbers
if (vpe_fixpt_lt(base2, vpe_fixpt_zero))
base2 = vpe_fixpt_sub(vpe_fixpt_zero, base2);
*out_y = vpe_fixpt_pow(base2, vpe_fixpt_div(vpe_fixpt_one, m1));
}
/* one-time pre-compute PQ values - only for sdr_white_level 80 */
static void precompute_pq(void)
{
int i;
struct fixed31_32 x;
const struct hw_x_point *coord_x = coordinates_x + 32;
struct fixed31_32 scaling_factor = vpe_fixpt_from_fraction(80, 10000);
struct fixed31_32 *pq_table = vpe_color_get_table(type_pq_table);
/* pow function has problems with arguments too small */
for (i = 0; i < 32; i++)
pq_table[i] = vpe_fixpt_zero;
for (i = 32; i <= MAX_HW_POINTS; i++) {
x = vpe_fixpt_mul(coord_x->x, scaling_factor);
vpe_compute_pq(x, &pq_table[i]);
++coord_x;
}
}
/* one-time pre-compute dePQ values - only for max pixel value 125 FP16.
yuv2rgbScaling is used when the output yuv->rgb is scaled down
due to limited range of the yuv2rgb matrix
*/
static void precompute_de_pq(struct fixed31_32 x_scale, struct fixed31_32 y_scale)
{
uint32_t i;
struct fixed31_32 y;
struct fixed31_32 *de_pq_table = vpe_color_get_table(type_de_pq_table);
for (i = 0; i < MAX_HW_POINTS_DEGAMMA; i++) {
compute_de_pq(vpe_fixpt_mul(coordinates_x_degamma[i].x, x_scale), &y);
de_pq_table[i] = vpe_fixpt_mul(y, y_scale);
}
}
static bool build_coefficients(
struct gamma_coefficients *coefficients, enum color_transfer_func type)
{
uint32_t i = 0;
uint32_t index = 0;
bool ret = true;
if (type == TRANSFER_FUNC_SRGB)
index = 0;
else if (type == TRANSFER_FUNC_BT709)
index = 1;
else if (type == TRANSFER_FUNC_BT1886)
index = 3;
else {
VPE_ASSERT(0);
ret = false;
goto release;
}
do {
coefficients->a0[i] = vpe_fixpt_from_fraction(numerator01[index], 10000000);
coefficients->a1[i] = vpe_fixpt_from_fraction(numerator02[index], 1000);
coefficients->a2[i] = vpe_fixpt_from_fraction(numerator03[index], 1000);
coefficients->a3[i] = vpe_fixpt_from_fraction(numerator04[index], 1000);
coefficients->user_gamma[i] = vpe_fixpt_from_fraction(numerator05[index], 1000);
++i;
} while (i != ARRAY_SIZE(coefficients->a0));
release:
return ret;
}
// bt.1886
static struct fixed31_32 translate_to_linear_space(struct fixed31_32 arg, struct fixed31_32 a0,
struct fixed31_32 a1, struct fixed31_32 a2, struct fixed31_32 a3, struct fixed31_32 gamma)
{
struct fixed31_32 linear;
a0 = vpe_fixpt_mul(a0, a1);
if (vpe_fixpt_le(arg, vpe_fixpt_neg(a0)))
linear = vpe_fixpt_neg(vpe_fixpt_pow(
vpe_fixpt_div(vpe_fixpt_sub(a2, arg), vpe_fixpt_add(vpe_fixpt_one, a3)), gamma));
else if (vpe_fixpt_le(vpe_fixpt_neg(a0), arg) && vpe_fixpt_le(arg, a0))
linear = vpe_fixpt_div(arg, a1);
else
linear = vpe_fixpt_pow(
vpe_fixpt_div(vpe_fixpt_add(a2, arg), vpe_fixpt_add(vpe_fixpt_one, a3)), gamma);
return linear;
}
static inline struct fixed31_32 translate_to_linear_space_ex(
struct fixed31_32 arg, struct gamma_coefficients *coeff, uint32_t color_index)
{
if (vpe_fixpt_le(vpe_fixpt_one, arg))
return vpe_fixpt_one;
return translate_to_linear_space(arg, coeff->a0[color_index], coeff->a1[color_index],
coeff->a2[color_index], coeff->a3[color_index], coeff->user_gamma[color_index]);
}
static struct fixed31_32 translate_from_linear_space(struct translate_from_linear_space_args *args)
{
const struct fixed31_32 one = vpe_fixpt_from_int(1);
struct fixed31_32 scratch_1, scratch_2;
struct calculate_buffer *cal_buffer = args->cal_buffer;
if (vpe_fixpt_le(one, args->arg))
return one;
if (vpe_fixpt_le(args->arg, vpe_fixpt_neg(args->a0))) {
scratch_1 = vpe_fixpt_add(one, args->a3);
scratch_2 = vpe_fixpt_pow(vpe_fixpt_neg(args->arg), vpe_fixpt_recip(args->gamma));
scratch_1 = vpe_fixpt_mul(scratch_1, scratch_2);
scratch_1 = vpe_fixpt_sub(args->a2, scratch_1);
return scratch_1;
} else if (vpe_fixpt_le(args->a0, args->arg)) {
if (cal_buffer->buffer_index == 0) {
cal_buffer->gamma_of_2 =
vpe_fixpt_pow(vpe_fixpt_from_int(2), vpe_fixpt_recip(args->gamma));
}
scratch_1 = vpe_fixpt_add(one, args->a3);
// In the first region (first 16 points) and in the
// region delimited by START/END we calculate with
// full precision to avoid error accumulation.
if ((cal_buffer->buffer_index >= PRECISE_LUT_REGION_START &&
cal_buffer->buffer_index <= PRECISE_LUT_REGION_END) ||
(cal_buffer->buffer_index < 16))
scratch_2 = vpe_fixpt_pow(args->arg, vpe_fixpt_recip(args->gamma));
else
scratch_2 = vpe_fixpt_mul(
cal_buffer->gamma_of_2, cal_buffer->buffer[cal_buffer->buffer_index % 16]);
if (cal_buffer->buffer_index != -1) {
cal_buffer->buffer[cal_buffer->buffer_index % 16] = scratch_2;
cal_buffer->buffer_index++;
}
scratch_1 = vpe_fixpt_mul(scratch_1, scratch_2);
scratch_1 = vpe_fixpt_sub(scratch_1, args->a2);
return scratch_1;
} else
return vpe_fixpt_mul(args->arg, args->a1);
}
static struct fixed31_32 translate_from_linear_space_ex(struct fixed31_32 arg,
struct gamma_coefficients *coeff, uint32_t color_index, struct calculate_buffer *cal_buffer)
{
struct translate_from_linear_space_args scratch_gamma_args = {0};
scratch_gamma_args.arg = arg;
scratch_gamma_args.a0 = coeff->a0[color_index];
scratch_gamma_args.a1 = coeff->a1[color_index];
scratch_gamma_args.a2 = coeff->a2[color_index];
scratch_gamma_args.a3 = coeff->a3[color_index];
scratch_gamma_args.gamma = coeff->user_gamma[color_index];
scratch_gamma_args.cal_buffer = cal_buffer;
return translate_from_linear_space(&scratch_gamma_args);
}
static void build_pq(struct pwl_float_data_ex *rgb_regamma, uint32_t hw_points_num,
const struct hw_x_point *coordinate_x, uint32_t hdr_normalization)
{
uint32_t i, start_index;
struct pwl_float_data_ex *rgb = rgb_regamma;
const struct hw_x_point *coord_x = coordinate_x;
struct fixed31_32 output;
struct fixed31_32 scaling_factor = vpe_fixpt_from_fraction(1, hdr_normalization);
/* TODO: start index is from segment 2^-24, skipping first segment
* due to x values too small for power calculations
*/
start_index = 32;
rgb += start_index;
coord_x += start_index;
for (i = start_index; i <= hw_points_num; i++) {
vpe_compute_pq(vpe_fixpt_mul(coord_x->x, scaling_factor), &output);
/* should really not happen? */
if (vpe_fixpt_lt(output, vpe_fixpt_zero))
output = vpe_fixpt_zero;
else if (vpe_fixpt_lt(vpe_fixpt_one, output))
output = vpe_fixpt_one;
rgb->r = output;
rgb->g = output;
rgb->b = output;
++coord_x;
++rgb;
}
coord_x = coordinates_x;
rgb = rgb_regamma;
struct fixed31_32 slope = vpe_fixpt_div(rgb[start_index].r, coord_x[start_index].x);
for (i = 0; i < start_index; i++) {
output = vpe_fixpt_mul(coord_x->x, slope);
rgb->r = output;
rgb->g = output;
rgb->b = output;
++coord_x;
++rgb;
}
}
static void build_de_pq(struct transfer_func_distributed_points *de_pq, uint32_t hw_points_num,
const struct hw_x_point *coordinate_x_degamma, struct fixed31_32 x_scale,
struct fixed31_32 y_scale)
{
uint32_t i;
struct fixed31_32 output;
struct fixed31_32 *de_pq_table = vpe_color_get_table(type_de_pq_table);
precompute_de_pq(x_scale, y_scale);
for (i = 0; i < hw_points_num; i++) {
output = de_pq_table[i];
/* should really not happen? */
if (vpe_fixpt_lt(output, vpe_fixpt_zero))
output = vpe_fixpt_zero;
de_pq->red[i] = output;
de_pq->green[i] = output;
de_pq->blue[i] = output;
}
}
static bool build_degamma(struct transfer_func_distributed_points *curve, uint32_t hw_points_num,
const struct hw_x_point *coordinate_x_degamma, enum color_transfer_func type,
struct fixed31_32 yuv2rgbScaling)
{
uint32_t i;
struct gamma_coefficients coeff;
struct fixed31_32 scaledX;
struct fixed31_32 scaledY;
bool ret = false;
if (!build_coefficients(&coeff, type))
goto release;
/* De-gamma X is 2^-8 to 2^0 i.e. 9 regions
*/
i = 0;
while (i != MAX_HW_POINTS_DEGAMMA) {
scaledX = vpe_fixpt_mul(coordinate_x_degamma[i].x, yuv2rgbScaling);
scaledY = translate_to_linear_space_ex(scaledX, &coeff, 0);
curve->red[i] = scaledY;
curve->green[i] = scaledY;
curve->blue[i] = scaledY;
i++;
}
ret = true;
release:
return ret;
}
static bool build_regamma(struct vpe_priv *vpe_priv, struct pwl_float_data_ex *rgb_regamma,
uint32_t hw_points_num, const struct hw_x_point *coordinate_x, enum color_transfer_func type,
struct calculate_buffer *cal_buffer)
{
uint32_t i;
bool ret = false;
struct gamma_coefficients *coeff;
struct pwl_float_data_ex *rgb = rgb_regamma;
const struct hw_x_point *coord_x = coordinate_x;
coeff = (struct gamma_coefficients *)vpe_zalloc(sizeof(*coeff));
if (!coeff)
goto release;
if (!build_coefficients(coeff, type))
goto release;
memset(cal_buffer->buffer, 0, NUM_PTS_IN_REGION * sizeof(struct fixed31_32));
cal_buffer->buffer_index = 0; // see variable definition for more info
i = 0;
while (i <= hw_points_num) {
/* TODO use y vs r,g,b */
rgb->r = translate_from_linear_space_ex(coord_x->x, coeff, 0, cal_buffer);
rgb->g = rgb->r;
rgb->b = rgb->r;
++coord_x;
++rgb;
++i;
}
cal_buffer->buffer_index = -1;
ret = true;
release:
vpe_free(coeff);
return ret;
}
static void build_new_custom_resulted_curve(
uint32_t hw_points_num, struct transfer_func_distributed_points *tf_pts)
{
uint32_t i = 0;
while (i != hw_points_num + 1) {
tf_pts->red[i] = vpe_fixpt_clamp(tf_pts->red[i], vpe_fixpt_zero, vpe_fixpt_one);
tf_pts->green[i] = vpe_fixpt_clamp(tf_pts->green[i], vpe_fixpt_zero, vpe_fixpt_one);
tf_pts->blue[i] = vpe_fixpt_clamp(tf_pts->blue[i], vpe_fixpt_zero, vpe_fixpt_one);
++i;
}
}
static bool map_regamma_hw_to_x_user(struct pixel_gamma_point *coeff128,
struct hw_x_point *coords_x, const struct pwl_float_data_ex *rgb_regamma,
uint32_t hw_points_num, struct transfer_func_distributed_points *tf_pts, bool doClamping)
{
/* setup to spare calculated ideal regamma values */
uint32_t i = 0;
struct hw_x_point *coords = coords_x;
const struct pwl_float_data_ex *regamma = rgb_regamma;
/* just copy current rgb_regamma into tf_pts */
while (i <= hw_points_num) {
tf_pts->red[i] = regamma->r;
tf_pts->green[i] = regamma->g;
tf_pts->blue[i] = regamma->b;
++regamma;
++i;
}
if (doClamping) {
/* this should be named differently, all it does is clamp to 0-1 */
build_new_custom_resulted_curve(hw_points_num, tf_pts);
}
return true;
}
static bool calculate_curve(struct vpe_priv *vpe_priv, enum color_transfer_func trans,
struct transfer_func_distributed_points *points, struct pwl_float_data_ex *rgb_regamma,
uint32_t hdr_normalization, struct calculate_buffer *cal_buffer)
{
bool ret = false;
if (trans == TRANSFER_FUNC_PQ2084) {
points->end_exponent = 0;
points->x_point_at_y1_red = 1;
points->x_point_at_y1_green = 1;
points->x_point_at_y1_blue = 1;
build_pq(rgb_regamma, MAX_HW_POINTS, coordinates_x, hdr_normalization);
ret = true;
} else if (trans == TRANSFER_FUNC_LINEAR_0_125) {
for (int i = 0; i < MAX_HW_POINTS; i++) {
rgb_regamma[i].r =
vpe_fixpt_mul(coordinates_x[i].x, vpe_fixpt_from_fraction(125, hdr_normalization));
rgb_regamma[i].g = rgb_regamma[i].r;
rgb_regamma[i].b = rgb_regamma[i].r;
}
ret = true;
} else {
// trans == TRANSFER_FUNC_SRGB
// trans == TRANSFER_FUNC_BT709
// trans == TRANSFER_FUNCTION_GAMMA22
// trans == TRANSFER_FUNCTION_GAMMA24
// trans == TRANSFER_FUNCTION_GAMMA26
points->end_exponent = 0;
points->x_point_at_y1_red = 1;
points->x_point_at_y1_green = 1;
points->x_point_at_y1_blue = 1;
build_regamma(vpe_priv, rgb_regamma, MAX_HW_POINTS, coordinates_x, trans, cal_buffer);
ret = true;
}
return ret;
}
#define _EXTRA_POINTS 3
bool vpe_color_calculate_degamma_params(struct vpe_priv *vpe_priv, struct fixed31_32 x_scale,
struct fixed31_32 y_scale, struct transfer_func *input_tf)
{
struct transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
enum color_transfer_func tf;
uint32_t i;
bool ret = true;
tf = input_tf->tf;
if (tf == TRANSFER_FUNC_PQ2084 || tf == TRANSFER_FUNC_NORMALIZED_PQ)
build_de_pq(tf_pts, MAX_HW_POINTS_DEGAMMA, coordinates_x_degamma, x_scale, y_scale);
else if (tf == TRANSFER_FUNC_SRGB || tf == TRANSFER_FUNC_BT709 || tf == TRANSFER_FUNC_BT1886)
build_degamma(tf_pts, MAX_HW_POINTS_DEGAMMA, coordinates_x_degamma, tf, x_scale);
else if (tf == TRANSFER_FUNC_LINEAR_0_125) {
// just copy coordinates_x_degamma into curve
i = 0;
while (i != MAX_HW_POINTS_DEGAMMA) {
tf_pts->red[i] = vpe_fixpt_mul(coordinates_x[i].x, y_scale);
tf_pts->red[i] = tf_pts->red[i];
tf_pts->red[i] = tf_pts->red[i];
i++;
}
} else
ret = false;
return ret;
}
bool vpe_color_calculate_regamma_params(
struct vpe_priv *vpe_priv, struct transfer_func *output_tf, struct calculate_buffer *cal_buffer)
{
struct transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
struct pwl_float_data_ex *rgb_regamma = NULL;
struct pixel_gamma_point *coeff = NULL;
enum color_transfer_func tf;
bool ret = false;
rgb_regamma = (struct pwl_float_data_ex *)vpe_zalloc(
(MAX_HW_POINTS + _EXTRA_POINTS) * sizeof(*rgb_regamma));
if (!rgb_regamma)
goto rgb_regamma_alloc_fail;
coeff =
(struct pixel_gamma_point *)vpe_zalloc((MAX_HW_POINTS + _EXTRA_POINTS) * sizeof(*coeff));
if (!coeff)
goto coeff_alloc_fail;
tf = output_tf->tf;
ret = calculate_curve(vpe_priv, tf, tf_pts, rgb_regamma,
vpe_priv->resource.internal_hdr_normalization, cal_buffer);
if (ret) {
map_regamma_hw_to_x_user(coeff, coordinates_x, rgb_regamma, MAX_HW_POINTS, tf_pts, false);
}
vpe_free(coeff);
coeff_alloc_fail:
vpe_free(rgb_regamma);
rgb_regamma_alloc_fail:
return ret;
}
+459
View File
@@ -0,0 +1,459 @@
/* 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 "color_gamut.h"
#define DIVIDER 10000
struct gamut_space_entry {
unsigned int redX;
unsigned int redY;
unsigned int greenX;
unsigned int greenY;
unsigned int blueX;
unsigned int blueY;
int a0;
int a1;
int a2;
int a3;
int gamma;
};
struct white_point_coodinates_entry {
unsigned int temperature;
unsigned int whiteX;
unsigned int whiteY;
};
static const struct gamut_space_entry predefined_gamuts[] = {
/* x_red y_red x_gr y_gr x_blue y_blue a0 a1 a2 a3 gamma
*/
[gamut_type_bt709] = {6400, 3300, 3000, 6000, 1500, 600, 180000, 4500, 99, 99, 2222},
[gamut_type_bt601] = {6300, 3400, 3100, 5950, 1550, 700, 180000, 4500, 99, 99, 2200},
[gamut_type_adobe_rgb] = {6400, 3300, 2100, 7100, 1500, 600, 180000, 4500, 99, 99, 2200},
[gamut_type_srgb] = {6400, 3300, 3000, 6000, 1500, 600, 31308, 12920, 55, 55, 2400},
[gamut_type_bt2020] = {7080, 2920, 1700, 7970, 1310, 460, 180000, 4500, 99, 99, 2200},
[gamut_type_dcip3] = {6800, 3200, 2650, 6900, 1500, 600, 0, 0, 0, 0, 2600}};
static const struct white_point_coodinates_entry predefined_white_points[] = {
[white_point_type_5000k_horizon] = {5000, 3473, 3561},
[white_point_type_6500k_noon] = {6500, 3127, 3290},
[white_point_type_7500k_north_sky] = {7500, 3022, 3129},
[white_point_type_9300k] = {9300, 2866, 2950}};
struct gamut_src_dst_matrix {
struct fixed31_32 rgbCoeffDst[9];
struct fixed31_32 whiteCoeffDst[3];
struct fixed31_32 rgbCoeffSrc[9];
struct fixed31_32 whiteCoeffSrc[3];
struct fixed31_32 xyzMatrix[9];
struct fixed31_32 xyzOffset[3];
struct fixed31_32 bradford[9];
};
struct gamut_calculation_matrix {
struct fixed31_32 MTransposed[9];
struct fixed31_32 XYZtoRGB_Custom[9];
struct fixed31_32 XYZtoRGB_Ref[9];
struct fixed31_32 RGBtoXYZ_Final[9];
struct fixed31_32 MResult[9];
struct fixed31_32 fXYZofWhiteRef[9];
struct fixed31_32 fXYZofRGBRef[9];
struct fixed31_32 fXYZofRGBRefCopy[9];
struct fixed31_32 MResultOffset[3];
};
static void color_find_predefined_gamut(
struct color_space_coordinates *out_gamut, enum predefined_gamut_type type)
{
out_gamut->redX = predefined_gamuts[type].redX;
out_gamut->redY = predefined_gamuts[type].redY;
out_gamut->greenX = predefined_gamuts[type].greenX;
out_gamut->greenY = predefined_gamuts[type].greenY;
out_gamut->blueX = predefined_gamuts[type].blueX;
out_gamut->blueY = predefined_gamuts[type].blueY;
}
static void color_find_predefined_white_point(
struct color_space_coordinates *out_white_point, enum predefined_white_point_type type)
{
out_white_point->whiteX = predefined_white_points[type].whiteX;
out_white_point->whiteY = predefined_white_points[type].whiteY;
}
static void color_transpose_matrix(const struct fixed31_32 *M, unsigned int Rows, unsigned int Cols,
struct fixed31_32 *MTransposed)
{
unsigned int i, j;
for (i = 0; i < Rows; i++) {
for (j = 0; j < Cols; j++)
MTransposed[(j * Rows) + i] = M[(i * Cols) + j];
}
}
static void color_multiply_matrices(struct fixed31_32 *mResult, const struct fixed31_32 *M1,
const struct fixed31_32 *M2, unsigned int Rows1, unsigned int Cols1, unsigned int Cols2)
{
unsigned int i, j, k;
for (i = 0; i < Rows1; i++) {
for (j = 0; j < Cols2; j++) {
mResult[(i * Cols2) + j] = vpe_fixpt_zero;
for (k = 0; k < Cols1; k++)
mResult[(i * Cols2) + j] = vpe_fixpt_add(mResult[(i * Cols2) + j],
vpe_fixpt_mul(M1[(i * Cols1) + k], M2[(k * Cols2) + j]));
}
}
}
static enum predefined_gamut_type color_space_to_predefined_gamut_types(
enum color_space color_space)
{
switch (color_space) {
case COLOR_SPACE_JFIF:
case COLOR_SPACE_YCBCR709:
case COLOR_SPACE_YCBCR709_LIMITED:
return gamut_type_bt709;
case COLOR_SPACE_YCBCR601:
case COLOR_SPACE_YCBCR601_LIMITED:
return gamut_type_bt601;
case COLOR_SPACE_SRGB:
case COLOR_SPACE_SRGB_LIMITED:
case COLOR_SPACE_MSREF_SCRGB:
return gamut_type_srgb;
case COLOR_SPACE_2020_RGB_FULLRANGE:
case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
case COLOR_SPACE_2020_YCBCR:
return gamut_type_bt2020;
default:
VPE_ASSERT(0);
return gamut_type_unknown;
}
}
static enum vpe_status find_predefined_gamut_and_white_point(
struct vpe_priv *vpe_priv, struct color_gamut_data *gamut, enum color_space color_space)
{
enum predefined_gamut_type gamut_type;
gamut->color_space = color_space;
gamut_type = color_space_to_predefined_gamut_types(color_space);
if (gamut_type == gamut_type_unknown) {
vpe_log("err: color space not supported! %d %d\n", (int)color_space, (int)gamut_type);
return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
}
color_find_predefined_gamut(&gamut->gamut, gamut_type);
gamut->white_point = color_white_point_type_6500k_noon;
color_find_predefined_white_point(&gamut->gamut, white_point_type_6500k_noon);
return VPE_STATUS_OK;
}
static bool build_gamut_remap_matrix(struct color_space_coordinates gamut_description,
struct fixed31_32 *rgb_matrix, struct fixed31_32 *white_point_matrix)
{
struct fixed31_32 fixed_blueX = vpe_fixpt_from_fraction(gamut_description.blueX, DIVIDER);
struct fixed31_32 fixed_blueY = vpe_fixpt_from_fraction(gamut_description.blueY, DIVIDER);
struct fixed31_32 fixed_greenX = vpe_fixpt_from_fraction(gamut_description.greenX, DIVIDER);
struct fixed31_32 fixed_greenY = vpe_fixpt_from_fraction(gamut_description.greenY, DIVIDER);
struct fixed31_32 fixed_redX = vpe_fixpt_from_fraction(gamut_description.redX, DIVIDER);
struct fixed31_32 fixed_redY = vpe_fixpt_from_fraction(gamut_description.redY, DIVIDER);
struct fixed31_32 fixed_whiteX = vpe_fixpt_from_fraction(gamut_description.whiteX, DIVIDER);
struct fixed31_32 fixed_whiteY = vpe_fixpt_from_fraction(gamut_description.whiteY, DIVIDER);
rgb_matrix[0] = vpe_fixpt_div(fixed_redX, fixed_redY);
rgb_matrix[1] = vpe_fixpt_one;
rgb_matrix[2] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_sub(vpe_fixpt_one, fixed_redX), fixed_redY), fixed_redY);
rgb_matrix[3] = vpe_fixpt_div(fixed_greenX, fixed_greenY);
rgb_matrix[4] = vpe_fixpt_one;
rgb_matrix[5] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_sub(vpe_fixpt_one, fixed_greenX), fixed_greenY), fixed_greenY);
rgb_matrix[6] = vpe_fixpt_div(fixed_blueX, fixed_blueY);
rgb_matrix[7] = vpe_fixpt_one;
rgb_matrix[8] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_sub(vpe_fixpt_one, fixed_blueX), fixed_blueY), fixed_blueY);
white_point_matrix[0] = vpe_fixpt_div(fixed_whiteX, fixed_whiteY);
white_point_matrix[1] = vpe_fixpt_one;
white_point_matrix[2] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_sub(vpe_fixpt_one, fixed_whiteX), fixed_whiteY), fixed_whiteY);
return true;
}
static struct fixed31_32 find_3X3_det(const struct fixed31_32 *m)
{
struct fixed31_32 det, A1, A2, A3;
A1 = vpe_fixpt_mul(m[0], vpe_fixpt_sub(vpe_fixpt_mul(m[4], m[8]), vpe_fixpt_mul(m[5], m[7])));
A2 = vpe_fixpt_mul(m[1], vpe_fixpt_sub(vpe_fixpt_mul(m[3], m[8]), vpe_fixpt_mul(m[5], m[6])));
A3 = vpe_fixpt_mul(m[2], vpe_fixpt_sub(vpe_fixpt_mul(m[3], m[7]), vpe_fixpt_mul(m[4], m[6])));
det = vpe_fixpt_add(vpe_fixpt_sub(A1, A2), A3);
return det;
}
static bool compute_inverse_matrix_3x3(const struct fixed31_32 *m, struct fixed31_32 *im)
{
struct fixed31_32 determinant = find_3X3_det(m);
if (vpe_fixpt_eq(determinant, vpe_fixpt_zero) == false) {
im[0] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[4], m[8]), vpe_fixpt_mul(m[5], m[7])), determinant);
im[1] = vpe_fixpt_neg(vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[1], m[8]), vpe_fixpt_mul(m[2], m[7])), determinant));
im[2] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[1], m[5]), vpe_fixpt_mul(m[2], m[4])), determinant);
im[3] = vpe_fixpt_neg(vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[3], m[8]), vpe_fixpt_mul(m[5], m[6])), determinant));
im[4] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[0], m[8]), vpe_fixpt_mul(m[2], m[6])), determinant);
im[5] = vpe_fixpt_neg(vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[0], m[5]), vpe_fixpt_mul(m[2], m[3])), determinant));
im[6] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[3], m[7]), vpe_fixpt_mul(m[4], m[6])), determinant);
im[7] = vpe_fixpt_neg(vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[0], m[7]), vpe_fixpt_mul(m[1], m[6])), determinant));
im[8] = vpe_fixpt_div(
vpe_fixpt_sub(vpe_fixpt_mul(m[0], m[4]), vpe_fixpt_mul(m[1], m[3])), determinant);
return true;
}
return false;
}
static bool calculate_XYZ_to_RGB_3x3(const struct fixed31_32 *XYZofRGB,
const struct fixed31_32 *XYZofWhite, struct fixed31_32 *XYZtoRGB)
{
struct fixed31_32 MInversed[9];
struct fixed31_32 SVector[3];
/*1. Find Inverse matrix 3x3 of MTransposed*/
if (!compute_inverse_matrix_3x3(XYZofRGB, MInversed))
return false;
/*2. Calculate vector: |Sr Sg Sb| = [MInversed] * |Wx Wy Wz|*/
color_multiply_matrices(SVector, MInversed, XYZofWhite, 3, 3, 1);
/*3. Calculate matrix XYZtoRGB 3x3*/
XYZtoRGB[0] = vpe_fixpt_mul(XYZofRGB[0], SVector[0]);
XYZtoRGB[1] = vpe_fixpt_mul(XYZofRGB[1], SVector[1]);
XYZtoRGB[2] = vpe_fixpt_mul(XYZofRGB[2], SVector[2]);
XYZtoRGB[3] = vpe_fixpt_mul(XYZofRGB[3], SVector[0]);
XYZtoRGB[4] = vpe_fixpt_mul(XYZofRGB[4], SVector[1]);
XYZtoRGB[5] = vpe_fixpt_mul(XYZofRGB[5], SVector[2]);
XYZtoRGB[6] = vpe_fixpt_mul(XYZofRGB[6], SVector[0]);
XYZtoRGB[7] = vpe_fixpt_mul(XYZofRGB[7], SVector[1]);
XYZtoRGB[8] = vpe_fixpt_mul(XYZofRGB[8], SVector[2]);
return true;
}
static bool gamut_to_color_matrix(struct vpe_priv *vpe_priv,
const struct gamut_src_dst_matrix *matrices, bool invert, struct fixed31_32 *tempMatrix3X3,
struct fixed31_32 *tempOffset)
{
int i = 0;
struct gamut_calculation_matrix *matrix = vpe_zalloc(sizeof(struct gamut_calculation_matrix));
const struct fixed31_32 *pXYZofRGB = matrices->rgbCoeffDst; /*destination gamut*/
const struct fixed31_32 *pXYZofWhite = matrices->whiteCoeffDst; /*destination of white point*/
const struct fixed31_32 *pRefXYZofRGB = matrices->rgbCoeffSrc; /*source gamut*/
const struct fixed31_32 *pRefXYZofWhite = matrices->whiteCoeffSrc; /*source of white point*/
const struct fixed31_32 *pColorTransformXYZ = matrices->xyzMatrix; /*additional XYZ->XYZ tfm*/
const struct fixed31_32 *pColorTransformXYZOffset = matrices->xyzOffset; /*XYZ tfm offset*/
const struct fixed31_32 *pBradford = matrices->bradford; /*Bradford chromatic adaptation*/
struct fixed31_32 *pXYZtoRGB_Temp;
struct fixed31_32 *pXYZtoRGB_Final;
if (!matrix)
return false;
matrix->fXYZofWhiteRef[0] = pRefXYZofWhite[0];
matrix->fXYZofWhiteRef[1] = pRefXYZofWhite[1];
matrix->fXYZofWhiteRef[2] = pRefXYZofWhite[2];
matrix->fXYZofRGBRef[0] = pRefXYZofRGB[0];
matrix->fXYZofRGBRef[1] = pRefXYZofRGB[1];
matrix->fXYZofRGBRef[2] = pRefXYZofRGB[2];
matrix->fXYZofRGBRef[3] = pRefXYZofRGB[3];
matrix->fXYZofRGBRef[4] = pRefXYZofRGB[4];
matrix->fXYZofRGBRef[5] = pRefXYZofRGB[5];
matrix->fXYZofRGBRef[6] = pRefXYZofRGB[6];
matrix->fXYZofRGBRef[7] = pRefXYZofRGB[7];
matrix->fXYZofRGBRef[8] = pRefXYZofRGB[8];
/*default values - unity matrix*/
while (i < 9) {
if (i == 0 || i == 4 || i == 8)
tempMatrix3X3[i] = vpe_fixpt_one;
else
tempMatrix3X3[i] = vpe_fixpt_zero;
i++;
}
/*1. Decide about the order of calculation.
* bInvert == FALSE --> RGBtoXYZ_Ref * XYZtoRGB_Custom
* bInvert == TRUE --> RGBtoXYZ_Custom * XYZtoRGB_Ref */
if (invert) {
pXYZtoRGB_Temp = matrix->XYZtoRGB_Custom;
pXYZtoRGB_Final = matrix->XYZtoRGB_Ref;
} else {
pXYZtoRGB_Temp = matrix->XYZtoRGB_Ref;
pXYZtoRGB_Final = matrix->XYZtoRGB_Custom;
}
/*2. Calculate XYZtoRGB_Ref*/
color_transpose_matrix(matrix->fXYZofRGBRef, 3, 3, matrix->MTransposed);
if (!calculate_XYZ_to_RGB_3x3(
matrix->MTransposed, matrix->fXYZofWhiteRef, matrix->XYZtoRGB_Ref))
goto function_fail;
/*3. Calculate XYZtoRGB_Custom*/
color_transpose_matrix(pXYZofRGB, 3, 3, matrix->MTransposed);
if (!calculate_XYZ_to_RGB_3x3(matrix->MTransposed, pXYZofWhite, matrix->XYZtoRGB_Custom))
goto function_fail;
/*4. Calculate RGBtoXYZ -
* inverse matrix 3x3 of XYZtoRGB_Ref or XYZtoRGB_Custom*/
if (!compute_inverse_matrix_3x3(pXYZtoRGB_Temp, matrix->RGBtoXYZ_Final))
goto function_fail;
/* The naming is a bit confusing here (and earlier as well if you're
* trying to follow RP 177-1993...), so in short:
* S - source->XYZ
* D - dest->XYZ
* At this point:
* D^-1 = RGBtoXYZ_Final
* S = XYZtoRGB_Ref == pXYZtoRGB_Final
*/
/*5. Calculate M(3x3) = RGBtoXYZ * XYZtoRGB*/
color_multiply_matrices(matrix->MResult, matrix->RGBtoXYZ_Final, pXYZtoRGB_Final, 3, 3, 3);
/*7. Calculate offsets */
for (i = 0; i < 9; i++)
tempMatrix3X3[i] = matrix->MResult[i];
for (i = 0; i < 3; i++)
tempOffset[i] = vpe_fixpt_zero;
vpe_free(matrix);
return true;
function_fail:
vpe_free(matrix);
return false;
}
static bool color_build_gamut_remap_matrix(struct vpe_priv *vpe_priv,
struct color_gamut_data *source_gamut, struct color_gamut_data *destination_gamut,
struct colorspace_transform *gamut_remap_matrix)
{
struct gamut_src_dst_matrix *matrix = NULL;
struct fixed31_32 gamut_result[12];
struct fixed31_32 temp_matrix[9];
struct fixed31_32 temp_offset[3];
int j;
matrix = vpe_zalloc(sizeof(struct gamut_src_dst_matrix));
if (matrix == NULL)
return false;
build_gamut_remap_matrix(source_gamut->gamut, matrix->rgbCoeffSrc, matrix->whiteCoeffSrc);
build_gamut_remap_matrix(destination_gamut->gamut, matrix->rgbCoeffDst, matrix->whiteCoeffDst);
if (!gamut_to_color_matrix(vpe_priv, matrix, true, temp_matrix, temp_offset))
goto function_fail;
gamut_result[0] = temp_matrix[0];
gamut_result[1] = temp_matrix[1];
gamut_result[2] = temp_matrix[2];
gamut_result[4] = temp_matrix[3];
gamut_result[5] = temp_matrix[4];
gamut_result[6] = temp_matrix[5];
gamut_result[8] = temp_matrix[6];
gamut_result[9] = temp_matrix[7];
gamut_result[10] = temp_matrix[8];
gamut_result[3] = temp_offset[0];
gamut_result[7] = temp_offset[1];
gamut_result[11] = temp_offset[2];
gamut_remap_matrix->enable_remap = true;
for (j = 0; j < 12; j++)
gamut_remap_matrix->matrix[j] = gamut_result[j];
vpe_free(matrix);
return true;
function_fail:
vpe_free(matrix);
vpe_log("err: build gamut remap fails!\n");
return false;
}
enum vpe_status vpe_color_update_gamut(struct vpe_priv *vpe_priv, enum color_space in_color,
enum color_space outColor, struct colorspace_transform *gamut_remap, bool bypass_remap)
{
struct output_ctx *output_ctx = &vpe_priv->output_ctx;
struct color_gamut_data src_gamut;
struct color_gamut_data dst_gamut;
enum vpe_status status;
if (bypass_remap || in_color == outColor) {
gamut_remap->enable_remap = false;
return VPE_STATUS_OK;
}
status = find_predefined_gamut_and_white_point(vpe_priv, &src_gamut, in_color);
if (status != VPE_STATUS_OK)
return status;
status = find_predefined_gamut_and_white_point(vpe_priv, &dst_gamut, outColor);
if (status != VPE_STATUS_OK)
return status;
if (!color_build_gamut_remap_matrix(vpe_priv, &src_gamut, &dst_gamut, gamut_remap)) {
vpe_log("err: build gamut remap failure!");
VPE_ASSERT(0);
return VPE_STATUS_ERROR;
}
return VPE_STATUS_OK;
}
+64
View File
@@ -0,0 +1,64 @@
/* 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 "color_table.h"
#include "fixed31_32.h"
static struct fixed31_32 pq_table[MAX_HW_POINTS + 2];
static struct fixed31_32 de_pq_table[MAX_HW_POINTS + 2];
static bool pq_initialized = false;
static bool de_pg_initialized = false;
bool vpe_color_is_table_init(enum table_type type)
{
bool ret = false;
if (type == type_pq_table)
ret = pq_initialized;
if (type == type_de_pq_table)
ret = de_pg_initialized;
return ret;
}
struct fixed31_32 *vpe_color_get_table(enum table_type type)
{
struct fixed31_32 *table = NULL;
if (type == type_pq_table)
table = pq_table;
if (type == type_de_pq_table)
table = de_pq_table;
return table;
}
void vpe_color_set_table_init_state(enum table_type type, bool state)
{
if (type == type_pq_table)
pq_initialized = state;
if (type == type_de_pq_table)
de_pg_initialized = state;
}
File diff suppressed because it is too large Load Diff
+591
View File
@@ -0,0 +1,591 @@
/* 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 "vpe_types.h"
#include "vpe_priv.h"
#include "common.h"
bool vpe_find_color_space_from_table(
const struct vpe_color_space *table, int table_size, const struct vpe_color_space *cs)
{
int i;
for (i = 0; i < table_size; i++) {
if (!memcmp(table, cs, sizeof(struct vpe_color_space)))
return true;
}
return false;
}
bool vpe_is_dual_plane_format(enum vpe_surface_pixel_format format)
{
switch (format) {
// nv12/21
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
// p010
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
return true;
default:
return false;
}
}
bool vpe_is_32bit_packed_rgb(enum vpe_surface_pixel_format format)
{
switch (format) {
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_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_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
return true;
default:
return false;
}
}
bool vpe_is_rgb8(enum vpe_surface_pixel_format format)
{
switch (format) {
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_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
return true;
default:
return false;
}
}
bool vpe_is_rgb10(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
return true;
default:
return false;
}
}
bool vpe_is_fp16(enum vpe_surface_pixel_format format)
{
switch (format) {
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:
return true;
default:
return false;
}
}
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:
return true;
default:
return false;
}
}
bool vpe_is_yuv420_10(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
return true;
default:
return false;
}
}
bool vpe_is_yuv420(enum vpe_surface_pixel_format format)
{
return (vpe_is_yuv420_8(format) || vpe_is_yuv420_10(format));
}
bool vpe_is_yuv444_8(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
return true;
default:
return false;
}
}
bool vpe_is_yuv444_10(enum vpe_surface_pixel_format format)
{
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
return true;
default:
return false;
}
}
static uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int plane_idx)
{
switch (format) {
// nv12/21
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
if (plane_idx == 0)
return 1;
else
return 2;
// P010
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
if (plane_idx == 0)
return 2;
else
return 4;
// 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:
return 8;
default:
break;
}
// default 32bpp packed format
return 4;
}
enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format)
{
enum color_depth c_depth;
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
c_depth = COLOR_DEPTH_666;
break;
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_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_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
c_depth = COLOR_DEPTH_888;
break;
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:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
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_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:
c_depth = COLOR_DEPTH_161616;
break;
default:
c_depth = COLOR_DEPTH_888;
}
return c_depth;
}
bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)
{
bool alpha = true;
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
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_ARGB2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
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_RGBE_ALPHA:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
alpha = true;
break;
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
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_GRPH_RGBE:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
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_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
default:
alpha = false;
break;
}
return alpha;
}
// Note there is another function vpe_is_hdr that performs the same function but with the translated
// internal VPE enums, not the api enums as done below. C does not support function overloading so
// another function is needed here.
static bool is_HDR(enum vpe_transfer_function tf)
{
return (tf == VPE_TF_PQ || tf == VPE_TF_G10);
}
enum vpe_status vpe_check_output_support(struct vpe *vpe, const struct vpe_build_param *param)
{
struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
struct vpec *vpec;
struct dpp *dpp;
struct cdc *cdc;
const struct vpe_surface_info *surface_info = &param->dst_surface;
struct vpe_dcc_surface_param input;
struct vpe_surface_dcc_cap output;
bool support;
vpec = &vpe_priv->resource.vpec;
dpp = vpe_priv->resource.dpp[0];
cdc = vpe_priv->resource.cdc[0];
// swizzle mode
support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
if (!support) {
vpe_log("output swizzle mode not supported %d\n", surface_info->swizzle);
return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
}
// pitch
if ((surface_info->plane_size.surface_pitch *
vpe_get_element_size_in_bytes(surface_info->format, 0) %
vpe->caps->plane_caps.pitch_alignment) ||
((uint32_t)(surface_info->plane_size.surface_size.x +
(int32_t)surface_info->plane_size.surface_size.width) >
surface_info->plane_size.surface_pitch)) {
vpe_log("pitch alignment not supported %lu. %lu\n", surface_info->plane_size.surface_pitch,
vpe->caps->plane_caps.pitch_alignment);
return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
}
// target rect shouldn't exceed width/height
if ((param->target_rect.x < surface_info->plane_size.surface_size.x ||
param->target_rect.x + (int32_t)param->target_rect.width >
surface_info->plane_size.surface_size.x +
(int32_t)surface_info->plane_size.surface_size.width)) {
vpe_log("target rect exceed surface boundary, target x= %d, width = %u, surface x = %d, "
"width = %u\n",
param->target_rect.x, param->target_rect.width, surface_info->plane_size.surface_size.x,
surface_info->plane_size.surface_size.width);
return VPE_STATUS_PARAM_CHECK_ERROR;
}
if ((param->target_rect.y < surface_info->plane_size.surface_size.y ||
param->target_rect.y + (int32_t)param->target_rect.height >
surface_info->plane_size.surface_size.y +
(int32_t)surface_info->plane_size.surface_size.height)) {
vpe_log(
"target rect exceed surface boundary, y= %d, height = %u, surface x = %d, width = %u\n",
param->target_rect.y, param->target_rect.height,
surface_info->plane_size.surface_size.y, surface_info->plane_size.surface_size.height);
return VPE_STATUS_PARAM_CHECK_ERROR;
}
if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
if (((uint32_t)surface_info->plane_size.chroma_pitch *
vpe_get_element_size_in_bytes(surface_info->format, 1) %
vpe->caps->plane_caps.pitch_alignment) ||
((uint32_t)(surface_info->plane_size.chroma_size.x +
(int32_t)surface_info->plane_size.chroma_size.width) >
surface_info->plane_size.chroma_pitch)) {
vpe_log("chroma pitch alignment not supported %u. %u\n",
surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
}
}
// dcc
if (surface_info->dcc.enable) {
input.surface_size.width = surface_info->plane_size.surface_size.width;
input.surface_size.height = surface_info->plane_size.surface_size.height;
input.format = surface_info->format;
input.swizzle_mode = surface_info->swizzle;
input.scan = VPE_SCAN_DIRECTION_HORIZONTAL;
support = vpec->funcs->get_dcc_compression_cap(vpec, &input, &output);
if (!support) {
vpe_log("output dcc not supported\n");
return VPE_STATUS_DCC_NOT_SUPPORTED;
}
}
// pixel format
support = cdc->funcs->check_output_format(cdc, surface_info->format);
if (!support) {
vpe_log("output pixel format not supported %d\n", (int)surface_info->format);
return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
}
// color space value
support = vpe_priv->resource.check_output_color_space(
vpe_priv, surface_info->format, &surface_info->cs);
if (!support) {
vpe_log("output color space not supported fmt: %d, "
"encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
(int)surface_info->format, (int)surface_info->cs.encoding,
(int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
(int)surface_info->cs.primaries);
return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream *stream)
{
struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
struct vpec *vpec;
struct dpp *dpp;
struct cdc *cdc;
const struct vpe_surface_info *surface_info = &stream->surface_info;
struct vpe_dcc_surface_param input;
struct vpe_surface_dcc_cap output;
bool support;
const PHYSICAL_ADDRESS_LOC *addrloc;
bool use_adj = vpe_use_csc_adjust(&stream->color_adj);
vpec = &vpe_priv->resource.vpec;
dpp = vpe_priv->resource.dpp[0];
cdc = vpe_priv->resource.cdc[0];
// swizzle mode
support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
if (!support) {
vpe_log("input swizzle mode not supported %d\n", surface_info->swizzle);
return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
}
// pitch & address
if ((surface_info->plane_size.surface_pitch *
vpe_get_element_size_in_bytes(surface_info->format, 0) %
vpe->caps->plane_caps.pitch_alignment) ||
((uint32_t)(surface_info->plane_size.surface_size.x +
(int32_t)surface_info->plane_size.surface_size.width) >
surface_info->plane_size.surface_pitch)) {
vpe_log("pitch alignment not supported %d. %d\n", surface_info->plane_size.surface_pitch,
vpe->caps->plane_caps.pitch_alignment);
return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
}
if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
addrloc = &surface_info->address.video_progressive.luma_addr;
if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
vpe_log("failed. addr not aligned to 256 bytes\n");
return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
}
if (vpe_is_dual_plane_format(surface_info->format)) {
if ((surface_info->plane_size.chroma_pitch *
vpe_get_element_size_in_bytes(surface_info->format, 1) %
vpe->caps->plane_caps.pitch_alignment) ||
((uint32_t)(surface_info->plane_size.chroma_size.x +
(int32_t)surface_info->plane_size.chroma_size.width) >
surface_info->plane_size.chroma_pitch)) {
vpe_log("chroma pitch alignment not supported %d. %d\n",
surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
}
addrloc = &surface_info->address.video_progressive.chroma_addr;
if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
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) {
vpe_log("failed. addr not aligned to 256 bytes\n");
return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
}
}
// dcc
if (surface_info->dcc.enable) {
input.surface_size.width = surface_info->plane_size.surface_size.width;
input.surface_size.height = surface_info->plane_size.surface_size.height;
input.format = surface_info->format;
input.swizzle_mode = surface_info->swizzle;
if (stream->rotation == VPE_ROTATION_ANGLE_0 || stream->rotation == VPE_ROTATION_ANGLE_180)
input.scan = VPE_SCAN_DIRECTION_HORIZONTAL;
else if (stream->rotation == VPE_ROTATION_ANGLE_90 ||
stream->rotation == VPE_ROTATION_ANGLE_270)
input.scan = VPE_SCAN_DIRECTION_VERTICAL;
else
input.scan = VPE_SCAN_DIRECTION_UNKNOWN;
support = vpec->funcs->get_dcc_compression_cap(vpec, &input, &output);
if (!support) {
vpe_log("input dcc not supported\n");
return VPE_STATUS_DCC_NOT_SUPPORTED;
}
}
// pixel format
support = cdc->funcs->check_input_format(cdc, surface_info->format);
if (!support) {
vpe_log("input pixel format not supported %d\n", (int)surface_info->format);
return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
}
// color space value
support = vpe_priv->resource.check_input_color_space(
vpe_priv, surface_info->format, &surface_info->cs);
if (!support) {
vpe_log("input color space not supported fmt: %d, "
"encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
(int)surface_info->format, (int)surface_info->cs.encoding,
(int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
(int)surface_info->cs.primaries);
return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
}
// TODO: Add support
// adjustments
if (surface_info->cs.primaries == VPE_PRIMARIES_BT2020 &&
surface_info->cs.encoding == VPE_PIXEL_ENCODING_RGB && use_adj) {
// for BT2020 + RGB input with adjustments, it is expected not working.
vpe_log("for BT2020 + RGB input with adjustments, it is expected not working\n");
return VPE_STATUS_ADJUSTMENT_NOT_SUPPORTED;
}
// rotation
if ((stream->rotation != VPE_ROTATION_ANGLE_0) && !vpe->caps->rotation_support) {
vpe_log("output rotation not supported\n");
return VPE_STATUS_ROTATION_NOT_SUPPORTED;
}
// luma keying
if (stream->enable_luma_key && !vpe->caps->color_caps.dpp.luma_key) {
vpe_log("luma keying not supported\n");
return VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED;
}
if (stream->horizontal_mirror && !vpe->caps->h_mirror_support) {
vpe_log("output horizontal mirroring not supported h:%d\n", (int)stream->horizontal_mirror);
return VPE_STATUS_MIRROR_NOT_SUPPORTED;
}
if (stream->vertical_mirror && !vpe->caps->v_mirror_support) {
vpe_log("output vertical mirroring not supported v:%d\n", (int)stream->vertical_mirror);
return VPE_STATUS_MIRROR_NOT_SUPPORTED;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_cache_tone_map_params(
struct stream_ctx *stream_ctx, const struct vpe_build_param *param)
{
stream_ctx->update_3dlut = stream_ctx->update_3dlut || param->streams->tm_params.update_3dlut;
return VPE_STATUS_OK;
}
enum vpe_status vpe_check_tone_map_support(
struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param)
{
enum vpe_status status = VPE_STATUS_OK;
// If tone map enabled but bad luminance reject.
if (stream->tm_params.enable_3dlut &&
stream->hdr_metadata.max_mastering <= param->hdr_metadata.max_mastering) {
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
goto exit;
}
// If tone map enabled but input is not HDR, reject.
if (stream->tm_params.enable_3dlut && !is_HDR(stream->surface_info.cs.tf)) {
status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
goto exit;
}
// If tone map case but enable tm flag is not set or 3dlut pointer is null reject.
if (stream->hdr_metadata.max_mastering > param->hdr_metadata.max_mastering &&
is_HDR(stream->surface_info.cs.tf) &&
(!stream->tm_params.enable_3dlut || stream->tm_params.lut_data == NULL)) {
status = VPE_STATUS_BAD_HDR_METADATA;
}
exit:
return status;
}
+256
View File
@@ -0,0 +1,256 @@
/* 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 "vpe_assert.h"
#include "vpe_command.h"
#include "config_writer.h"
#include "reg_helper.h"
#include "common.h"
// in bytes
#define MAX_DIRECT_CONFIG_SIZE (4 * 0x10000)
#define MAX_INDIRECT_CONFIG_SIZE ((4 + 16 * 3) * sizeof(uint32_t))
void config_writer_init(struct config_writer *writer, struct vpe_buf *buf)
{
writer->base_cpu_va = buf->cpu_va;
writer->base_gpu_va = buf->gpu_va;
writer->buf = buf;
writer->type = CONFIG_TYPE_UNKNOWN;
writer->callback_ctx = NULL;
writer->callback = NULL;
writer->completed = false;
writer->status = VPE_STATUS_OK;
}
void config_writer_set_callback(
struct config_writer *writer, void *callback_ctx, config_callback_t callback)
{
writer->callback_ctx = callback_ctx;
writer->callback = callback;
}
static inline void config_writer_new(struct config_writer *writer)
{
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < (int64_t)sizeof(uint32_t)) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
// new base
writer->base_cpu_va = writer->buf->cpu_va;
writer->base_gpu_va = writer->buf->gpu_va;
// new header. don't need to fill it yet until completion
writer->buf->cpu_va += sizeof(uint32_t);
writer->buf->gpu_va += sizeof(uint32_t);
writer->buf->size -= sizeof(uint32_t);
writer->completed = false;
}
void config_writer_set_type(struct config_writer *writer, enum config_type type)
{
VPE_ASSERT(type != CONFIG_TYPE_UNKNOWN);
if (writer->status != VPE_STATUS_OK)
return;
if (writer->type != type) {
if (writer->type == CONFIG_TYPE_UNKNOWN) {
// new header. don't need to fill it yet until completion
config_writer_new(writer);
} else {
// a new config type, close the previous one
config_writer_complete(writer);
config_writer_new(writer);
}
writer->type = type;
}
}
void config_writer_fill(struct config_writer *writer, uint32_t value)
{
uint32_t *cmd_space;
uint64_t size = writer->buf->cpu_va - writer->base_cpu_va;
VPE_ASSERT(writer->type != CONFIG_TYPE_UNKNOWN);
if (writer->status != VPE_STATUS_OK)
return;
// check overflow, open a new one if it is
if (writer->type == CONFIG_TYPE_DIRECT) {
if (size >= MAX_DIRECT_CONFIG_SIZE) {
config_writer_complete(writer);
config_writer_new(writer);
} else if (writer->completed) {
config_writer_new(writer);
}
} else {
if (size >= MAX_INDIRECT_CONFIG_SIZE) {
config_writer_complete(writer);
config_writer_new(writer);
} else if (writer->completed) {
config_writer_new(writer);
}
}
/* Buffer does not have enough space to write */
if (writer->buf->size < (int64_t)sizeof(uint32_t)) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = value;
writer->buf->cpu_va += sizeof(uint32_t);
writer->buf->gpu_va += sizeof(uint32_t);
writer->buf->size -= sizeof(uint32_t);
}
void config_writer_fill_direct_config_packet_header(
struct config_writer *writer, struct vpep_direct_config_packet *packet)
{
uint32_t *cmd_space;
uint64_t size = writer->buf->cpu_va - writer->base_cpu_va;
VPE_ASSERT(writer->type == CONFIG_TYPE_DIRECT);
if (writer->status != VPE_STATUS_OK)
return;
// first + 1 for header, DATA_SIZE + 1 for real data size
// for estimate overflow, this function only write packet header
if (size + (1 + packet->bits.VPEP_CONFIG_DATA_SIZE + 1) * sizeof(uint32_t) >=
MAX_DIRECT_CONFIG_SIZE) {
config_writer_complete(writer);
config_writer_new(writer);
} else if (writer->completed) {
config_writer_new(writer);
}
/* Buffer does not have enough space to write */
if (writer->buf->size < (int64_t)sizeof(uint32_t)) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = packet->u32all;
writer->buf->cpu_va += sizeof(uint32_t);
writer->buf->gpu_va += sizeof(uint32_t);
writer->buf->size -= sizeof(uint32_t);
}
void config_writer_fill_direct_config_packet(
struct config_writer *writer, struct vpep_direct_config_packet *packet)
{
uint32_t *cmd_space;
uint64_t size = writer->buf->cpu_va - writer->base_cpu_va;
VPE_ASSERT(writer->type == CONFIG_TYPE_DIRECT);
VPE_ASSERT(packet->bits.VPEP_CONFIG_DATA_SIZE == 0);
if (writer->status != VPE_STATUS_OK)
return;
// first + 1 for header, DATA_SIZE + 1 for real data size
// this function writes both header and the data
if (size + 1 + (packet->bits.VPEP_CONFIG_DATA_SIZE + 1) * sizeof(uint32_t) >=
MAX_DIRECT_CONFIG_SIZE) {
config_writer_complete(writer);
config_writer_new(writer);
} else if (writer->completed) {
config_writer_new(writer);
}
if (writer->buf->size < (int64_t)(2 * sizeof(uint32_t))) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
*cmd_space++ = packet->u32all; // Write header
writer->buf->cpu_va += sizeof(uint32_t);
writer->buf->gpu_va += sizeof(uint32_t);
writer->buf->size -= sizeof(uint32_t);
*cmd_space++ = packet->data[0]; // Write data
writer->buf->cpu_va += sizeof(uint32_t);
writer->buf->gpu_va += sizeof(uint32_t);
writer->buf->size -= sizeof(uint32_t);
}
void config_writer_fill_indirect_data_array(
struct config_writer *writer, const uint64_t data_gpuva, uint32_t size)
{
VPE_ASSERT(writer->type == CONFIG_TYPE_INDIRECT);
VPE_ASSERT(size > 0);
// the DATA_ARRAY_SIZE is 1-based, hence -1 from actual size
config_writer_fill(writer, VPEC_FIELD_VALUE(VPE_IND_CFG_DATA_ARRAY_SIZE, size - 1));
config_writer_fill(writer, ADDR_LO(data_gpuva));
config_writer_fill(writer, ADDR_HI(data_gpuva));
}
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)
{
VPE_ASSERT(writer->type == CONFIG_TYPE_INDIRECT);
config_writer_fill(writer, VPEC_FIELD_VALUE(VPE_IND_CFG_PKT_REGISTER_OFFSET, offset_index));
config_writer_fill(writer, start_index);
config_writer_fill(writer, VPEC_FIELD_VALUE(VPE_IND_CFG_PKT_REGISTER_OFFSET, offset_data));
}
void config_writer_complete(struct config_writer *writer)
{
uint32_t *cmd_space = (uint32_t *)(uintptr_t)writer->base_cpu_va;
uint32_t size = (uint32_t)(writer->buf->cpu_va - writer->base_cpu_va);
if (writer->status != VPE_STATUS_OK)
return;
VPE_ASSERT(writer->type != CONFIG_TYPE_UNKNOWN);
VPE_ASSERT(writer->buf->cpu_va != writer->base_cpu_va);
if (writer->type == CONFIG_TYPE_DIRECT) {
// -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 {
// -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
uint32_t num_dst = (uint32_t)((size - (4 * sizeof(uint32_t))) / (3 * sizeof(uint32_t)) - 1);
*cmd_space = VPE_IND_CFG_CMD_HEADER(num_dst);
}
writer->completed = true;
if (writer->callback) {
writer->callback(writer->callback_ctx, writer->base_gpu_va, writer->base_cpu_va, size);
}
}
@@ -0,0 +1,34 @@
/* 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 "hw_shared.h"
#include "vpe_priv.h"
#include "common.h"
#define LUT3D_SIZE_17x17x17 4913
#define LUT3D_SIZE_9x9x9 729
bool convert_to_tetrahedral(struct vpe_priv *vpe_priv, uint16_t rgb[17 * 17 * 17 * 3],
struct vpe_3dlut *params, bool enable_3dlut);
+42
View File
@@ -0,0 +1,42 @@
/* 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 "resource.h"
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void vpe_create_bg_segments(
struct vpe_priv *vpe_priv, struct vpe_rect *gaps, uint16_t gaps_cnt, enum vpe_cmd_ops ops);
uint16_t vpe_find_bg_gaps(struct vpe_priv *vpe_priv, const struct vpe_rect *target_rect,
struct vpe_rect *gaps, uint16_t max_gaps);
void vpe_full_bg_gaps(struct vpe_rect *gaps, const struct vpe_rect *target_rect, uint16_t max_gaps);
#ifdef __cplusplus
}
#endif
+67
View File
@@ -0,0 +1,67 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct cdc;
struct vpe_priv;
/** note: all program_* functions shall return number of config packet created */
struct cdc_funcs {
bool (*check_input_format)(struct cdc *cdc, enum vpe_surface_pixel_format format);
bool (*check_output_format)(struct cdc *cdc, enum vpe_surface_pixel_format format);
/** non segment specific */
void (*program_surface_config)(struct cdc *cdc, enum vpe_surface_pixel_format format,
enum vpe_rotation_angle rotation, bool horizontal_mirror,
enum vpe_swizzle_mode_values swizzle);
void (*program_crossbar_config)(struct cdc *cdc, enum vpe_surface_pixel_format format);
void (*program_global_sync)(
struct cdc *cdc, uint32_t vupdate_offset, uint32_t vupdate_width, uint32_t vready_offset);
void (*program_p2b_config)(struct cdc *cdc, enum vpe_surface_pixel_format format);
/** segment specific */
void (*program_viewport)(
struct cdc *cdc, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c);
};
struct cdc {
struct vpe_priv *vpe_priv;
struct cdc_funcs *funcs;
};
#ifdef __cplusplus
}
#endif
+50
View File
@@ -0,0 +1,50 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe_priv;
struct cmd_builder {
enum vpe_status (*build_noops)(
struct vpe_priv *vpe_priv, uint32_t **ppbuf, uint32_t num_dwords);
// prelimenary APIs
enum vpe_status (*build_vpe_cmd)(
struct vpe_priv *vpe_priv, struct vpe_build_bufs *cur_bufs, uint32_t cmd_idx);
enum vpe_status (*build_plane_descriptor)(
struct vpe_priv *vpe_priv, struct vpe_buf *buf, uint32_t cmd_idx);
};
#ifdef __cplusplus
}
#endif
+247
View File
@@ -0,0 +1,247 @@
/* 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 "vpe_types.h"
#include "fixed31_32.h"
#include "hw_shared.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SDR_VIDEO_WHITE_POINT 100 // nits
#define SDR_WHITE_POINT 80 // nits
#define HDR_PEAK_WHITE 10000
struct vpe_priv;
struct stream_ctx;
enum color_depth {
COLOR_DEPTH_UNDEFINED,
COLOR_DEPTH_666,
COLOR_DEPTH_888,
COLOR_DEPTH_101010,
COLOR_DEPTH_121212,
COLOR_DEPTH_141414,
COLOR_DEPTH_161616,
COLOR_DEPTH_999,
COLOR_DEPTH_111111,
COLOR_DEPTH_COUNT
};
enum color_transfer_func {
TRANSFER_FUNC_UNKNOWN,
TRANSFER_FUNC_SRGB,
TRANSFER_FUNC_BT709,
TRANSFER_FUNC_BT1886,
TRANSFER_FUNC_PQ2084,
TRANSFER_FUNC_LINEAR_0_125,
TRANSFER_FUNC_NORMALIZED_PQ
};
enum dither_option {
DITHER_OPTION_DEFAULT,
DITHER_OPTION_DISABLE,
DITHER_OPTION_FM6,
DITHER_OPTION_FM8,
DITHER_OPTION_FM10,
DITHER_OPTION_SPATIAL6_FRAME_RANDOM,
DITHER_OPTION_SPATIAL8_FRAME_RANDOM,
DITHER_OPTION_SPATIAL10_FRAME_RANDOM,
DITHER_OPTION_SPATIAL6,
DITHER_OPTION_SPATIAL8,
DITHER_OPTION_SPATIAL10,
DITHER_OPTION_TRUN6,
DITHER_OPTION_TRUN8,
DITHER_OPTION_TRUN10,
DITHER_OPTION_TRUN10_SPATIAL8,
DITHER_OPTION_TRUN10_SPATIAL6,
DITHER_OPTION_TRUN10_FM8,
DITHER_OPTION_TRUN10_FM6,
DITHER_OPTION_TRUN10_SPATIAL8_FM6,
DITHER_OPTION_SPATIAL10_FM8,
DITHER_OPTION_SPATIAL10_FM6,
DITHER_OPTION_TRUN8_SPATIAL6,
DITHER_OPTION_TRUN8_FM6,
DITHER_OPTION_SPATIAL8_FM6,
DITHER_OPTION_MAX = DITHER_OPTION_SPATIAL8_FM6,
DITHER_OPTION_INVALID
};
enum color_space {
COLOR_SPACE_UNKNOWN,
COLOR_SPACE_SRGB,
COLOR_SPACE_SRGB_LIMITED,
COLOR_SPACE_MSREF_SCRGB,
COLOR_SPACE_YCBCR601,
COLOR_SPACE_YCBCR709,
COLOR_SPACE_JFIF,
COLOR_SPACE_YCBCR601_LIMITED,
COLOR_SPACE_YCBCR709_LIMITED,
COLOR_SPACE_2020_RGB_FULLRANGE,
COLOR_SPACE_2020_RGB_LIMITEDRANGE,
COLOR_SPACE_2020_YCBCR,
COLOR_SPACE_2020_YCBCR_LIMITED,
COLOR_SPACE_MAX,
};
enum transfer_func_type {
TF_TYPE_PREDEFINED,
TF_TYPE_DISTRIBUTED_POINTS,
TF_TYPE_BYPASS,
TF_TYPE_HWPWL
};
enum {
TRANSFER_FUNC_POINTS = 1025
};
typedef struct fixed31_32 white_point_gain;
struct transfer_func_distributed_points {
struct fixed31_32 red[TRANSFER_FUNC_POINTS];
struct fixed31_32 green[TRANSFER_FUNC_POINTS];
struct fixed31_32 blue[TRANSFER_FUNC_POINTS];
uint16_t end_exponent;
uint16_t x_point_at_y1_red;
uint16_t x_point_at_y1_green;
uint16_t x_point_at_y1_blue;
};
struct transfer_func {
enum transfer_func_type type;
enum color_transfer_func tf;
/* FP16 1.0 reference level in nits, default is 80 nits, only for PQ*/
uint32_t sdr_ref_white_level;
union {
struct pwl_params pwl;
struct transfer_func_distributed_points tf_pts;
};
bool use_pre_calculated_table;
};
enum color_white_point_type {
color_white_point_type_unknown,
color_white_point_type_5000k_horizon,
color_white_point_type_6500k_noon,
color_white_point_type_7500k_north_sky,
color_white_point_type_9300k,
color_white_point_type_custom_coordinates
};
struct color_space_coordinates {
unsigned int redX;
unsigned int redY;
unsigned int greenX;
unsigned int greenY;
unsigned int blueX;
unsigned int blueY;
unsigned int whiteX;
unsigned int whiteY;
};
enum predefined_gamut_type {
gamut_type_bt709,
gamut_type_bt601,
gamut_type_adobe_rgb,
gamut_type_srgb,
gamut_type_bt2020,
gamut_type_dcip3,
gamut_type_unknown,
};
enum predefined_white_point_type {
white_point_type_5000k_horizon,
white_point_type_6500k_noon,
white_point_type_7500k_north_sky,
white_point_type_9300k,
white_point_type_unknown,
};
struct colorspace_transform {
struct fixed31_32 matrix[12];
bool enable_remap;
};
struct color_gamut_data {
enum color_space color_space;
enum color_white_point_type white_point;
struct color_space_coordinates gamut;
};
union vpe_3dlut_state {
struct {
uint32_t initialized : 1; /*if 3dlut is went through color module for initialization */
uint32_t reserved : 15;
} bits;
uint32_t raw;
};
struct vpe_3dlut {
// struct kref refcount;
struct tetrahedral_params lut_3d;
struct fixed31_32 hdr_multiplier;
union vpe_3dlut_state state;
};
enum vpe_status vpe_color_update_color_space_and_tf(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
enum vpe_status vpe_color_update_movable_cm(
struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
void vpe_color_get_color_space_and_tf(
const struct vpe_color_space *vcs, enum color_space *cs, enum color_transfer_func *tf);
bool vpe_use_csc_adjust(const struct vpe_color_adjust *adjustments);
bool vpe_is_rgb_equal(const struct pwl_result_data *rgb, uint32_t num);
bool vpe_is_HDR(enum color_transfer_func tf);
void vpe_convert_full_range_color_enum(enum color_space *cs);
enum vpe_status vpe_color_update_whitepoint(
const struct vpe_priv *vpe_priv, const struct vpe_build_param *param);
enum vpe_status vpe_color_tm_update_hdr_mult(uint16_t shaper_in_exp_max, uint32_t peak_white,
struct fixed31_32 *hdr_multiplier, bool enable_3dlut);
enum vpe_status vpe_color_update_shaper(
uint16_t shaper_in_exp_max, struct transfer_func *shaper_func, bool enable_3dlut);
enum vpe_status vpe_color_update_blnd_gam(struct vpe_priv *vpe_priv,
const struct vpe_build_param *param, const struct vpe_tonemap_params *tm_params,
struct transfer_func *blnd_tf_func, bool enable_3dlut);
enum vpe_status vpe_color_build_tm_cs(const struct vpe_tonemap_params *tm_params,
struct vpe_surface_info surface_info, struct vpe_color_space *vcs);
#ifdef __cplusplus
}
#endif
+33
View File
@@ -0,0 +1,33 @@
/* 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"
void vpe_bg_color_convert(
enum color_space cs, struct transfer_func *output_tf, struct vpe_color *bg_color);
enum vpe_status vpe_bg_color_outside_cs_gamut(
const struct vpe_color_space *vcs, struct vpe_color *bg_color);
+58
View File
@@ -0,0 +1,58 @@
/* 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 "fixed31_32.h"
#include "color_table.h"
#ifdef __cplusplus
extern "C" {
#endif
struct color_range {
int current;
int min;
int max;
};
struct vpe_color_adjustments {
struct color_range contrast;
struct color_range saturation;
struct color_range brightness;
struct color_range hue;
};
bool vpe_color_calculate_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
const struct vpe_color_adjust *vpe_adjust, struct vpe_csc_matrix *input_cs,
struct fixed31_32 *matrix_scaling_factor);
bool vpe_color_different_color_adjusts(
const struct vpe_color_adjust *new_vpe_adjusts, struct vpe_color_adjust *crt_vpe_adjusts);
void vpe_color_set_adjustments_to_default(struct vpe_color_adjust *crt_vpe_adjusts);
#ifdef __cplusplus
}
#endif
+64
View File
@@ -0,0 +1,64 @@
/* 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 "fixed31_32.h"
#include "color_table.h"
#ifdef __cplusplus
extern "C" {
#endif
struct calculate_buffer {
int buffer_index;
struct fixed31_32 buffer[NUM_PTS_IN_REGION];
struct fixed31_32 gamma_of_2;
};
struct translate_from_linear_space_args {
struct fixed31_32 arg;
struct fixed31_32 a0;
struct fixed31_32 a1;
struct fixed31_32 a2;
struct fixed31_32 a3;
struct fixed31_32 gamma;
struct calculate_buffer *cal_buffer;
};
void vpe_color_setup_x_points_distribution(void);
void vpe_color_setup_x_points_distribution_degamma(void);
bool vpe_color_calculate_regamma_params(struct vpe_priv *vpe_priv, struct transfer_func *output_tf,
struct calculate_buffer *cal_buffer);
bool vpe_color_calculate_degamma_params(struct vpe_priv *vpe_priv, struct fixed31_32 x_scale,
struct fixed31_32 y_scale, struct transfer_func *input_tf);
void vpe_compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y);
#ifdef __cplusplus
}
#endif
+40
View File
@@ -0,0 +1,40 @@
/* 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 "vpe_types.h"
#include "fixed31_32.h"
#include "vpe_priv.h"
#ifdef __cplusplus
extern "C" {
#endif
enum vpe_status vpe_color_update_gamut(struct vpe_priv *vpe_priv, enum color_space in_color,
enum color_space outColor, struct colorspace_transform *gamut_remap, bool bypass_remap);
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
+66
View File
@@ -0,0 +1,66 @@
/* 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 "fixed31_32.h"
#include "color.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NUM_PTS_IN_REGION 16
#define NUM_REGIONS 32
#define MAX_HW_POINTS (NUM_PTS_IN_REGION * NUM_REGIONS)
#define MAX_HW_POINTS_DEGAMMA 257
enum table_type {
type_pq_table,
type_de_pq_table
};
bool vpe_color_is_table_init(enum table_type type);
struct fixed31_32 *vpe_color_get_table(enum table_type type);
void vpe_color_set_table_init_state(enum table_type type, bool state);
struct vpe_csc_matrix {
enum color_space cs;
uint16_t regval[12];
};
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,
{0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef, 0, 0x2000, 0x38b4, 0xe3a6}},
{COLOR_SPACE_YCBCR709,
{0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0, 0x2000, 0x3b61, 0xe24f}},
{COLOR_SPACE_2020_YCBCR,
{0x2f2f, 0x2000, 0, 0xe869, 0xedb8, 0x2000, 0xfabc, 0xbc6, 0x0, 0x2000, 0x3c34, 0xe1e6}}};
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,48 @@
/* 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 "common.h"
#include "fixed31_32.h"
#include "color_table.h"
#ifdef __cplusplus
extern "C" {
#endif
enum test3d_type {
lut3d_identity = 0,
lut3d_sce
};
bool build_test_shaper_sdr(struct transfer_func *shaper);
bool build_test_post1dlut_sdr(struct transfer_func *post1D);
bool build_test_3dlut(enum test3d_type type, struct vpe_3dlut *lut3d);
#ifdef __cplusplus
}
#endif
+91
View File
@@ -0,0 +1,91 @@
/* 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 <string.h>
#include "vpe_types.h"
#include "color.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ADDR_LO(addr) ((addr) & 0xFFFFFFFF)
#define ADDR_HI(addr) (((addr) >> 32) & 0xFFFFFFFF)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define 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)
#ifndef min
#define min(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef max
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
bool vpe_find_color_space_from_table(
const struct vpe_color_space *table, int table_size, const struct vpe_color_space *cs);
bool vpe_is_dual_plane_format(enum vpe_surface_pixel_format format);
// RGB checkers
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_fp16(enum vpe_surface_pixel_format format);
// yuv 4:2:0 check
bool vpe_is_yuv420_8(enum vpe_surface_pixel_format format);
bool vpe_is_yuv420_10(enum vpe_surface_pixel_format format);
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);
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);
enum vpe_status vpe_check_output_support(struct vpe *vpe, const struct vpe_build_param *param);
enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream *stream);
enum vpe_status vpe_cache_tone_map_params(struct stream_ctx *, const struct vpe_build_param *param);
enum vpe_status vpe_check_tone_map_support(
struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param);
#ifdef __cplusplus
}
#endif
+167
View File
@@ -0,0 +1,167 @@
/* 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 "vpe_types.h"
#if defined(LITTLEENDIAN_CPU)
#elif defined(BIGENDIAN_CPU)
#else
#error "BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined"
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum config_type {
CONFIG_TYPE_UNKNOWN,
CONFIG_TYPE_DIRECT,
CONFIG_TYPE_INDIRECT
};
typedef void (*config_callback_t)(
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, int64_t size);
#define MAX_CONFIG_PACKET_DATA_SIZE_DWORD 0x01000
struct vpep_direct_config_packet {
union {
struct {
#if defined(LITTLEENDIAN_CPU)
uint32_t INC : 1;
uint32_t : 1;
uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18;
uint32_t VPEP_CONFIG_DATA_SIZE : 12;
#elif defined(BIGENDIAN_CPU)
uint32_t VPEP_CONFIG_DATA_SIZE : 12;
uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18;
uint32_t : 1;
uint32_t INC : 1;
#endif
} bitfields, bits;
uint32_t u32all;
};
uint32_t data[1];
};
/* config writer only help initialize the 1st DWORD,
* and 'close' the config (i.e. finalize the size) once it is completed.
* it doesn't help generate the content, which shall be prepared by the caller
* and then call config_writer_fill()
*/
struct config_writer {
struct vpe_buf *buf; /**< store the current buf pointer */
/* store the base addr of the currnet config
* i.e. config header
* it is always constructed in emb_buf
*/
uint64_t base_gpu_va;
uint64_t base_cpu_va;
enum config_type type;
bool completed;
void *callback_ctx;
config_callback_t callback;
enum vpe_status status;
};
/** initialize the config writer.
* Calls right before building any VPEP configs
*
* /param writer writer instance
* /param emb_buf points to the current cmd_buf,
* each config_writer_fill will update the address
*/
void config_writer_init(struct config_writer *writer, struct vpe_buf *emb_buf);
/** set the callback function (can be null) for notifying any config completion
* In the callback, caller can:
* 1. save the config for later reuse
* 2. write it to vpe descriptor
*/
void config_writer_set_callback(
struct config_writer *writer, void *callback_ctx, config_callback_t callback);
/** set the config type before config_writer_fill()
* if the config_type has changed, it will finalize the current one,
* 1) direct config
* VPEP_DIRECT_CONFIG_ARRAY_SIZE is finalized (in DW0) automatically.
* 2) indirect config
* NUM_DST is finalized (in DW0) automatically.
* and run callback (if set) to notify the completion.
* A new config desc header DW0 will be generated.
*
* /param writer writer instance
* /param type config type
*/
void config_writer_set_type(struct config_writer *writer, enum config_type type);
/** fill the value to the buffer.
* If the dword exceeds the config packet size limit,
* callback will be called and a new config desc is created.
*
* /param writer writer instance
* /param value fill the DW to the config desc body
*/
void config_writer_fill(struct config_writer *writer, uint32_t value);
/** fill the header value to the buffer.
* If the current size + number of dwords in the array
* exceeds the config packet size limit,
* callback will be called and a new config desc is created.
*
* /param writer writer instance
* /param packet config packet with header filled properly
*/
void config_writer_fill_direct_config_packet_header(
struct config_writer *writer, struct vpep_direct_config_packet *packet);
/** fill the header and data value to the buffer.
* For single DATA element ONLY.
* If the current size + number of dwords in the array
* exceeds the config packet size limit,
* callback will be called and a new config desc is created.
*
* /param writer writer instance
* /param packet config packet with valid header and data
*/
void config_writer_fill_direct_config_packet(
struct config_writer *writer, struct vpep_direct_config_packet *packet);
void config_writer_fill_indirect_data_array(
struct config_writer *writer, const uint64_t data_gpuva, uint32_t size);
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);
/** explicitly complete the config */
void config_writer_complete(struct config_writer *writer);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,60 @@
/*
* 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
*/
#ifndef DRIVERS_VPELIB_INC_DIAG_REG_HELPER_H_
#define DRIVERS_VPELIB_INC_DIAG_REG_HELPER_H_
#pragma once
#include "reg_helper.h"
#ifdef __cplusplus
extern "C" {
#endif
/** CTX is defined in the .c files */
#define DIAG_PROGRAM_ENTRY() \
struct vpe_priv *vpe_priv = CTX_BASE->vpe_priv; \
struct CTX *CTX = (struct CTX *)CTX_BASE; \
struct config_writer *config_writer = &vpe_priv->config_diag_writer; \
struct vpep_direct_config_packet packet = {0}
#define DIAG_REG_SET(reg_name, val) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = (uint32_t)val; \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define DIAG_REG_CURRENT(reg_name) REG_CURRENT(reg_name)
#define DIAG_REG_UPDATE(reg, field, val) REG_UPDATE(reg, field, val)
#ifdef __cplusplus
}
#endif
#endif /* DRIVERS_VPELIB_INC_REG_HELPER_H_ */
+121
View File
@@ -0,0 +1,121 @@
/* 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 "vpe_types.h"
#include "hw_shared.h"
#include "color.h"
#include "transform.h"
#ifdef __cplusplus
extern "C" {
#endif
struct dpp;
struct vpe_priv;
struct vpe_csc_matrix;
struct cnv_alpha_2bit_lut {
int lut0;
int lut1;
int lut2;
int lut3;
};
enum CNV_COLOR_KEYER_MODE {
CNV_COLOR_KEYER_MODE_FORCE_00 = 0,
CNV_COLOR_KEYER_MODE_FORCE_FF = 1,
CNV_COLOR_KEYER_MODE_RANGE_00 = 2,
CNV_COLOR_KEYER_MODE_RANGE_FF = 3
};
struct cnv_color_keyer_params {
int color_keyer_en;
int color_keyer_mode;
int color_keyer_alpha_low;
int color_keyer_alpha_high;
int color_keyer_red_low;
int color_keyer_red_high;
int color_keyer_green_low;
int color_keyer_green_high;
int color_keyer_blue_low;
int color_keyer_blue_high;
};
enum input_csc_select {
INPUT_CSC_SELECT_BYPASS = 0,
INPUT_CSC_SELECT_ICSC = 1,
};
struct dpp_funcs {
bool (*get_optimal_number_of_taps)(
struct dpp *dpp, struct scaler_data *scl_data, const struct vpe_scaling_taps *taps);
void (*dscl_calc_lb_num_partitions)(const struct scaler_data *scl_data,
enum lb_memory_config lb_config, uint32_t *num_part_y, uint32_t *num_part_c);
/** non segment specific */
void (*program_cnv)(
struct dpp *dpp, enum vpe_surface_pixel_format format, enum vpe_expansion_mode mode);
void (*program_pre_dgam)(struct dpp *dpp, enum color_transfer_func tr);
void (*program_cnv_bias_scale)(struct dpp *dpp, struct bias_and_scale *bias_and_scale);
void (*program_alpha_keyer)(struct dpp *dpp, struct cnv_color_keyer_params *color_keyer);
void (*program_input_transfer_func)(struct dpp *dpp, struct transfer_func *input_tf);
void (*program_gamut_remap)(struct dpp *dpp, struct colorspace_transform *gamut_remap);
/*program post scaler scs block in dpp CM*/
void (*program_post_csc)(struct dpp *dpp, enum color_space color_space,
enum input_csc_select input_select, struct vpe_csc_matrix *input_cs);
void (*set_hdr_multiplier)(struct dpp *dpp, uint32_t multiplier);
/** scaler */
void (*set_segment_scaler)(struct dpp *dpp, const struct scaler_data *scl_data);
void (*set_frame_scaler)(struct dpp *dpp, const struct scaler_data *scl_data);
uint32_t (*get_line_buffer_size)(void);
bool (*validate_number_of_taps)(struct dpp *dpp, struct scaler_data *scl_data);
void (*program_crc)(struct dpp *opp, bool enable);
};
struct dpp {
struct vpe_priv *vpe_priv;
struct dpp_funcs *funcs;
struct pwl_params degamma_params;
};
#ifdef __cplusplus
}
#endif
+193
View File
@@ -0,0 +1,193 @@
/* 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 "fixed31_32.h"
#ifdef __cplusplus
extern "C" {
#endif
enum cm_type {
CM_DEGAM,
CM_REGAM,
};
struct bias_and_scale {
uint32_t scale_red;
uint32_t bias_red;
uint32_t scale_green;
uint32_t bias_green;
uint32_t scale_blue;
uint32_t bias_blue;
};
struct gamma_curve {
uint32_t offset;
uint32_t segments_num;
};
struct curve_points {
struct fixed31_32 x;
struct fixed31_32 y;
struct fixed31_32 offset;
struct fixed31_32 slope;
uint32_t custom_float_x;
uint32_t custom_float_y;
uint32_t custom_float_offset;
uint32_t custom_float_slope;
};
struct curve_points3 {
struct curve_points red;
struct curve_points green;
struct curve_points blue;
};
struct pwl_result_data {
struct fixed31_32 red;
struct fixed31_32 green;
struct fixed31_32 blue;
struct fixed31_32 delta_red;
struct fixed31_32 delta_green;
struct fixed31_32 delta_blue;
uint32_t red_reg;
uint32_t green_reg;
uint32_t blue_reg;
uint32_t delta_red_reg;
uint32_t delta_green_reg;
uint32_t delta_blue_reg;
};
/* arr_curve_points - regamma regions/segments specification
* arr_points - beginning and end point specified separately (only one on DCE)
* corner_points - beginning and end point for all 3 colors (DCN)
* rgb_resulted - final curve
*/
struct pwl_params {
struct gamma_curve arr_curve_points[34];
union {
struct curve_points arr_points[2];
struct curve_points3 corner_points[2];
};
struct pwl_result_data rgb_resulted[256 + 3];
uint32_t hw_points_num;
};
struct hw_x_point {
uint32_t custom_float_x;
struct fixed31_32 x;
struct fixed31_32 regamma_y_red;
struct fixed31_32 regamma_y_green;
struct fixed31_32 regamma_y_blue;
};
struct gamma_coefficients {
struct fixed31_32 a0[3];
struct fixed31_32 a1[3];
struct fixed31_32 a2[3];
struct fixed31_32 a3[3];
struct fixed31_32 user_gamma[3];
struct fixed31_32 user_contrast;
struct fixed31_32 user_brightness;
};
struct pwl_float_data_ex {
struct fixed31_32 r;
struct fixed31_32 g;
struct fixed31_32 b;
struct fixed31_32 delta_r;
struct fixed31_32 delta_g;
struct fixed31_32 delta_b;
};
enum hw_point_position {
/* hw point sits between left and right sw points */
HW_POINT_POSITION_MIDDLE,
/* hw point lays left from left (smaller) sw point */
HW_POINT_POSITION_LEFT,
/* hw point lays stays from right (bigger) sw point */
HW_POINT_POSITION_RIGHT
};
struct gamma_point {
int32_t left_index;
int32_t right_index;
enum hw_point_position pos;
struct fixed31_32 coeff;
};
struct pixel_gamma_point {
struct gamma_point r;
struct gamma_point g;
struct gamma_point b;
};
enum gamut_remap_select {
GAMUT_REMAP_BYPASS = 0,
GAMUT_REMAP_COMA_COEFF,
};
struct vpe_rgb {
uint32_t red;
uint32_t green;
uint32_t blue;
};
struct tetrahedral_17x17x17 {
struct vpe_rgb lut0[1229];
struct vpe_rgb lut1[1228];
struct vpe_rgb lut2[1228];
struct vpe_rgb lut3[1228];
};
struct tetrahedral_9x9x9 {
struct vpe_rgb lut0[183];
struct vpe_rgb lut1[182];
struct vpe_rgb lut2[182];
struct vpe_rgb lut3[182];
};
struct tetrahedral_params {
union {
struct tetrahedral_17x17x17 tetrahedral_17;
struct tetrahedral_9x9x9 tetrahedral_9;
};
bool use_tetrahedral_9;
bool use_12bits;
};
enum vpe_lut_mode {
LUT_BYPASS,
LUT_RAM_A,
LUT_RAM_B
};
#ifdef __cplusplus
}
#endif
+183
View File
@@ -0,0 +1,183 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mpc;
struct vpe_priv;
struct output_ctx;
enum mpc_mpccid {
MPC_MPCCID_0 = 0,
MPC_MPCCID_COUNT,
};
enum mpc_mux_topsel {
MPC_MUX_TOPSEL_DPP0 = 0,
MPC_MUX_TOPSEL_DISABLE = 0x0f,
};
enum mpc_mux_botsel {
MPC_MUX_BOTSEL_MPCC0 = 0,
MPC_MUX_BOTSEL_DISABLE = 0x0f,
};
enum mpc_mux_outmux {
MPC_MUX_OUTMUX_MPCC0 = 0,
MPC_MUX_OUTMUX_DISABLE = 0x0f,
};
enum mpc_mux_oppid {
MPC_MUX_OPPID_OPP0 = 0,
MPC_MUX_OPPID_DISABLE = 0x0f,
};
enum mpcc_blend_mode {
MPCC_BLEND_MODE_BYPASS, // Direct digital bypass
MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH, // Top layer pass-through
MPCC_BLEND_MODE_TOP_LAYER_ONLY, // Top layer bleneded with background color
MPCC_BLEND_MODE_TOP_BOT_BLENDING // Top and bottom blending
};
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 blending configuration
*/
struct mpcc_blnd_cfg {
struct vpe_color bg_color; /* background color */
enum mpcc_alpha_blend_mode alpha_mode; /* alpha blend mode */
bool pre_multiplied_alpha; /* alpha pre-multiplied mode flag */
uint8_t global_gain;
uint8_t global_alpha;
bool overlap_only;
/* MPCC top/bottom gain settings */
int bottom_gain_mode;
int background_color_bpc;
int top_gain;
int bottom_inside_gain;
int bottom_outside_gain;
};
enum mpc_output_csc_mode {
MPC_OUTPUT_CSC_DISABLE = 0,
MPC_OUTPUT_CSC_COEF_A,
};
struct mpc_denorm_clamp {
int clamp_max_r_cr;
int clamp_min_r_cr;
int clamp_max_g_y;
int clamp_min_g_y;
int clamp_max_b_cb;
int clamp_min_b_cb;
};
struct mpc_funcs {
// TODO finalize it
void (*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 (*program_mpcc_blending)(
struct mpc *mpc, enum mpc_mpccid mpcc_idx, struct mpcc_blnd_cfg *blnd_cfg);
void (*program_mpc_bypass_bg_color)(struct mpc *mpc, struct mpcc_blnd_cfg *blnd_cfg);
void (*power_on_ogam_lut)(struct mpc *mpc, bool power_on);
void (*set_output_csc)(
struct mpc *mpc, const uint16_t *regval, enum mpc_output_csc_mode ocsc_mode);
void (*set_ocsc_default)(struct mpc *mpc, enum vpe_surface_pixel_format pixel_format,
enum color_space color_space, enum mpc_output_csc_mode ocsc_mode);
void (*program_output_csc)(struct mpc *mpc, enum vpe_surface_pixel_format pixel_format,
enum color_space colorspace, uint16_t *matrix);
void (*set_output_gamma)(struct mpc *mpc, const struct pwl_params *params);
void (*set_gamut_remap)(struct mpc *mpc, struct colorspace_transform *gamut_remap);
void (*power_on_1dlut_shaper_3dlut)(struct mpc *mpc, bool power_on);
bool (*program_shaper)(struct mpc *mpc, const struct pwl_params *params);
// using direct config to program the 3dlut specified in params
void (*program_3dlut)(struct mpc *mpc, const struct tetrahedral_params *params);
// using indirect config to configure the 3DLut
bool (*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);
// Blend-gamma control.
void (*program_1dlut)(struct mpc *mpc, const struct pwl_params *params);
void (*program_cm_location)(struct mpc *mpc, uint8_t location);
void (*set_denorm)(struct mpc *mpc, int opp_id, enum color_depth output_depth,
struct mpc_denorm_clamp *denorm_clamp);
void (*set_out_float_en)(struct mpc *mpc, bool float_enable);
void (*program_mpc_out)(struct mpc *mpc, enum vpe_surface_pixel_format format);
void (*set_output_transfer_func)(struct mpc *mpc, struct output_ctx *output_ctx);
void (*set_mpc_shaper_3dlut)(struct mpc *mpc, const struct transfer_func *func_shaper,
const struct vpe_3dlut *lut3d_func);
void (*set_blend_lut)(struct mpc *mpc, const struct transfer_func *blend_tf);
bool (*program_movable_cm)(struct mpc *mpc, const struct transfer_func *func_shaper,
const struct vpe_3dlut *lut3d_func, const struct transfer_func *blend_tf, bool afterblend);
void (*program_crc)(struct mpc *mpc, bool enable);
};
struct mpc {
struct vpe_priv *vpe_priv;
struct mpc_funcs *funcs;
struct pwl_params regamma_params;
struct pwl_params blender_params;
struct pwl_params shaper_params;
};
const uint16_t *vpe_find_color_matrix(
enum color_space color_space, enum vpe_surface_pixel_format pixel_format, uint32_t *array_size);
#ifdef __cplusplus
}
#endif
+128
View File
@@ -0,0 +1,128 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct opp;
struct vpe_priv;
enum clamping_range {
CLAMPING_FULL_RANGE = 0, /* No Clamping */
CLAMPING_LIMITED_RANGE_8BPC, /* 8 bpc: Clamping 1 to FE */
CLAMPING_LIMITED_RANGE_10BPC, /* 10 bpc: Clamping 4 to 3FB */
CLAMPING_LIMITED_RANGE_12BPC, /* 12 bpc: Clamping 10 to FEF */
/* Use programmable clampping value on FMT_CLAMP_COMPONENT_R/G/B. */
CLAMPING_LIMITED_RANGE_PROGRAMMABLE
};
struct clamping_and_pixel_encoding_params {
// enum vpe_pixel_encoding pixel_encoding; /* Pixel Encoding, not used and not initialized yet
// */
enum clamping_range clamping_level; /* Clamping identifier */
enum color_depth c_depth; /* Deep color use. */
uint32_t r_clamp_component_upper;
uint32_t b_clamp_component_upper;
uint32_t g_clamp_component_upper;
uint32_t r_clamp_component_lower;
uint32_t b_clamp_component_lower;
uint32_t g_clamp_component_lower;
};
struct bit_depth_reduction_params {
struct {
/* truncate/round */
/* trunc/round enabled*/
uint32_t TRUNCATE_ENABLED : 1;
/* 2 bits: 0=6 bpc, 1=8 bpc, 2 = 10bpc*/
uint32_t TRUNCATE_DEPTH : 2;
/* truncate or round*/
uint32_t TRUNCATE_MODE : 1;
/* spatial dither */
/* Spatial Bit Depth Reduction enabled*/
uint32_t SPATIAL_DITHER_ENABLED : 1;
/* 2 bits: 0=6 bpc, 1 = 8 bpc, 2 = 10bpc*/
uint32_t SPATIAL_DITHER_DEPTH : 2;
/* 0-3 to select patterns*/
uint32_t SPATIAL_DITHER_MODE : 2;
/* Enable RGB random dithering*/
uint32_t RGB_RANDOM : 1;
/* Enable Frame random dithering*/
uint32_t FRAME_RANDOM : 1;
/* Enable HighPass random dithering*/
uint32_t HIGHPASS_RANDOM : 1;
/* temporal dither*/
/* frame modulation enabled*/
uint32_t FRAME_MODULATION_ENABLED : 1;
/* same as for trunc/spatial*/
uint32_t FRAME_MODULATION_DEPTH : 2;
/* 2/4 gray levels*/
uint32_t TEMPORAL_LEVEL : 1;
uint32_t FRC25 : 2;
uint32_t FRC50 : 2;
uint32_t FRC75 : 2;
} flags;
uint32_t r_seed_value;
uint32_t b_seed_value;
uint32_t g_seed_value;
// enum vpe_pixel_encoding pixel_encoding; // not used and not initialized yet
};
struct opp_funcs {
void (*set_clamping)(struct opp *opp, const struct clamping_and_pixel_encoding_params *params);
void (*set_dyn_expansion)(struct opp *opp, bool enable, enum color_depth color_dpth);
void (*set_truncation)(struct opp *opp, const struct bit_depth_reduction_params *params);
void (*set_spatial_dither)(struct opp *opp, const struct bit_depth_reduction_params *params);
void (*program_bit_depth_reduction)(
struct opp *opp, const struct bit_depth_reduction_params *params);
void (*program_fmt)(struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth,
struct clamping_and_pixel_encoding_params *clamping);
void (*program_pipe_alpha)(struct opp *opp, uint16_t alpha);
void (*program_pipe_bypass)(struct opp *opp, bool enable);
void (*program_pipe_crc)(struct opp *opp, bool enable);
};
struct opp {
struct vpe_priv *vpe_priv;
struct opp_funcs *funcs;
};
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,101 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct plane_desc_writer {
struct vpe_buf *buf; /**< store the current buf pointer */
/* store the base addr of the currnet config
* i.e. config header
* it is always constructed in emb_buf
*/
uint64_t base_gpu_va;
uint64_t base_cpu_va;
int32_t num_src;
int32_t num_dst;
enum vpe_status status;
};
struct plane_desc_src {
bool tmz;
enum vpe_swizzle_mode_values swizzle;
enum vpe_rotation_angle rotation;
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;
};
struct plane_desc_dst {
bool tmz;
enum vpe_swizzle_mode_values swizzle;
enum vpe_mirror mirror;
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;
};
/** initialize the plane descriptor writer.
* Calls right before building any plane descriptor
*
* /param writer writer instance
* /param buf points to the current buf,
* each config_writer_fill will update the address
* /param nps0 number of plane for source 0
* /param npd0 number of plane for desination 0
* /param nps1 number of plane for source 1
* /param npd1 number of plane for desination 1
* /param subop subop code
*/
void plane_desc_writer_init(struct plane_desc_writer *writer, struct vpe_buf *buf, int32_t nps0,
int32_t npd0, int32_t nps1, int32_t npd1, int32_t subop);
/** fill the value to the embedded buffer. */
void plane_desc_writer_add_source(
struct plane_desc_writer *writer, struct plane_desc_src *source, bool is_plane0);
/** fill the value to the embedded buffer. */
void plane_desc_writer_add_destination(
struct plane_desc_writer *writer, struct plane_desc_dst *destination, bool is_plane0);
#ifdef __cplusplus
}
#endif
+275
View File
@@ -0,0 +1,275 @@
/*
* 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
*/
#ifndef DRIVERS_VPELIB_INC_REG_HELPER_H_
#define DRIVERS_VPELIB_INC_REG_HELPER_H_
#pragma once
#include <stdint.h>
#include "vpe_command.h"
#include "config_writer.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct reg_id_val {
const uint32_t id;
const uint32_t default_value;
uint32_t lastWritten_value;
bool isWritten;
} reg_id_val;
/** CTX is defined in the .c files */
#define PROGRAM_ENTRY() \
struct vpe_priv *vpe_priv = CTX_BASE->vpe_priv; \
struct CTX *CTX = (struct CTX *)CTX_BASE; \
struct config_writer *config_writer = &vpe_priv->config_writer; \
struct vpep_direct_config_packet packet = {0}
// for use with reg_id_val struct that stores id, default and current val together
#define REG_OFFSET(reg_name) CTX->regs->reg_name.id // Register offset in DWORD
#define REG_DEFAULT(reg_name) CTX->regs->reg_name.default_value
#define REG_IS_WRITTEN(reg_name) CTX->regs->reg_name.isWritten
#define REG_LAST_WRITTEN_VAL(reg_name) CTX->regs->reg_name.lastWritten_value
#define REG_CURRENT(reg_name) \
(REG_IS_WRITTEN(reg_name) ? REG_LAST_WRITTEN_VAL(reg_name) : REG_DEFAULT(reg_name))
#define REG_FIELD_VALUE(field, value) ((uint32_t)((value) << CTX->shift->field) & CTX->mask->field)
#define REG_FIELD_SHIFT(field) CTX->shift->field
#define REG_FIELD_MASK(field) CTX->mask->field
#define VPEC_FIELD_VALUE(field, data) ((uint32_t)((data) << field##__SHIFT) & field##_MASK)
/* macro to set register fields. */
#define REG_SET_DEFAULT(reg_name) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = REG_DEFAULT(reg_name); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET(reg_name, init_val, field, val) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(field))) | \
REG_FIELD_VALUE(field, (uint32_t)val)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_2(reg_name, init_val, f1, v1, f2, v2) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_3(reg_name, init_val, f1, v1, f2, v2, f3, v3) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_4(reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_5(reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_6(reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5)) & \
~(REG_FIELD_MASK(f6))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5) | REG_FIELD_VALUE(f6, (uint32_t)v6)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_7(reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5)) & \
~(REG_FIELD_MASK(f6)) & ~(REG_FIELD_MASK(f7))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5) | REG_FIELD_VALUE(f6, (uint32_t)v6) | \
REG_FIELD_VALUE(f7, (uint32_t)v7)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_8( \
reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5)) & \
~(REG_FIELD_MASK(f6)) & ~(REG_FIELD_MASK(f7)) & ~(REG_FIELD_MASK(f8))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5) | REG_FIELD_VALUE(f6, (uint32_t)v6) | \
REG_FIELD_VALUE(f7, (uint32_t)v7) | REG_FIELD_VALUE(f8, (uint32_t)v8)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_9( \
reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5)) & \
~(REG_FIELD_MASK(f6)) & ~(REG_FIELD_MASK(f7)) & ~(REG_FIELD_MASK(f8)) & \
~(REG_FIELD_MASK(f9))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5) | REG_FIELD_VALUE(f6, (uint32_t)v6) | \
REG_FIELD_VALUE(f7, (uint32_t)v7) | REG_FIELD_VALUE(f8, (uint32_t)v8) | \
REG_FIELD_VALUE(f9, (uint32_t)v9)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_SET_10(reg_name, init_val, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, \
v8, f9, v9, f10, v10) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = \
(((uint32_t)init_val & ~(REG_FIELD_MASK(f1)) & ~(REG_FIELD_MASK(f2)) & \
~(REG_FIELD_MASK(f3)) & ~(REG_FIELD_MASK(f4)) & ~(REG_FIELD_MASK(f5)) & \
~(REG_FIELD_MASK(f6)) & ~(REG_FIELD_MASK(f7)) & ~(REG_FIELD_MASK(f8)) & \
~(REG_FIELD_MASK(f9)) & ~(REG_FIELD_MASK(f10))) | \
REG_FIELD_VALUE(f1, (uint32_t)v1) | REG_FIELD_VALUE(f2, (uint32_t)v2) | \
REG_FIELD_VALUE(f3, (uint32_t)v3) | REG_FIELD_VALUE(f4, (uint32_t)v4) | \
REG_FIELD_VALUE(f5, (uint32_t)v5) | REG_FIELD_VALUE(f6, (uint32_t)v6) | \
REG_FIELD_VALUE(f7, (uint32_t)v7) | REG_FIELD_VALUE(f8, (uint32_t)v8) | \
REG_FIELD_VALUE(f9, (uint32_t)v9) | REG_FIELD_VALUE(f10, (uint32_t)v10)); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#define REG_UPDATE(reg, field, val) REG_SET(reg, REG_CURRENT(reg), field, val)
#define REG_UPDATE_2(reg, f1, v1, f2, v2) REG_SET_2(reg, REG_CURRENT(reg), f1, v1, f2, v2)
#define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3) \
REG_SET_3(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3)
#define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4) \
REG_SET_4(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4)
#define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
REG_SET_5(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)
#define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
REG_SET_6(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)
#define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
REG_SET_7(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)
#define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
REG_SET_8(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)
#define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) \
REG_SET_9(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, \
v8, f9, v9)
#define REG_UPDATE_10( \
reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) \
REG_SET_10(reg, REG_CURRENT(reg), f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, \
v8, f9, v9, f10, v10)
#define REG_SET_DEFAULT(reg_name) \
do { \
packet.bits.INC = 0; \
packet.bits.VPEP_CONFIG_DATA_SIZE = 0; \
packet.bits.VPEP_CONFIG_REGISTER_OFFSET = REG_OFFSET(reg_name); \
REG_IS_WRITTEN(reg_name) = true; \
packet.data[0] = REG_LAST_WRITTEN_VAL(reg_name) = REG_DEFAULT(reg_name); \
config_writer_fill_direct_config_packet(config_writer, &packet); \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* DRIVERS_VPELIB_INC_REG_HELPER_H_ */
+160
View File
@@ -0,0 +1,160 @@
/* 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 "vpe_types.h"
#include "cmd_builder.h"
#include "vpec.h"
#include "cdc.h"
#include "dpp.h"
#include "mpc.h"
#include "opp.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe_priv;
struct vpe_cmd_info;
struct segment_ctx;
#define MAX_PIPE 2
enum vpe_cmd_ops;
/** struct resource stores all the hw subblocks function pointers
* which assist in constructing the command packets.
*
* As differnt asic may have its own deviation in the subblocks,
* each hw ip has its own set of function pointers to expose
* the programming interface of the blocks.
*
* The upper level should have a sequencer that constructs the
* final programming sequence using subblock functions
*/
struct resource {
struct vpe_priv *vpe_priv;
struct vpec vpec;
bool (*check_input_color_space)(struct vpe_priv *vpe_priv, enum vpe_surface_pixel_format format,
const struct vpe_color_space *vcs);
bool (*check_output_color_space)(struct vpe_priv *vpe_priv,
enum vpe_surface_pixel_format format, const struct vpe_color_space *vcs);
bool (*check_h_mirror_support)(bool *input_mirror, bool *output_miror);
enum vpe_status (*calculate_segments)(
struct vpe_priv *vpe_priv, const struct vpe_build_param *params);
enum vpe_status (*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);
bool (*split_bg_gap)(struct vpe_rect *gaps, const struct vpe_rect *target_rect,
uint32_t max_width, uint16_t max_gaps, uint16_t *num_gaps, uint16_t num_instances);
void (*calculate_dst_viewport_and_active)(
struct segment_ctx *segment_ctx, uint32_t max_seg_width);
uint16_t (*find_bg_gaps)(struct vpe_priv *vpe_priv, const struct vpe_rect *target_rect,
struct vpe_rect *gaps, uint16_t max_gaps);
void (*create_bg_segments)(
struct vpe_priv *vpe_priv, struct vpe_rect *gaps, uint16_t gaps_cnt, enum vpe_cmd_ops ops);
enum vpe_status (*populate_cmd_info)(struct vpe_priv *vpe_priv);
int32_t (*program_frontend)(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx,
uint32_t cmd_input_idx, bool seg_only);
int32_t (*program_backend)(
struct vpe_priv *vpe_priv, uint32_t pipe_idx, uint32_t cmd_idx, bool seg_only);
void (*get_bufs_req)(struct vpe_priv *vpe_priv, struct vpe_bufs_req *req);
void (*get_tf_pwl_params)(const struct transfer_func *output_tf, struct pwl_params **lut_params,
enum cm_type vpe_cm_type);
// Indicates the nominal range hdr input content should be in during processing.
int internal_hdr_normalization;
// vpep components
struct cdc *cdc[MAX_PIPE];
struct dpp *dpp[MAX_PIPE];
struct opp *opp[MAX_PIPE];
struct mpc *mpc[MAX_PIPE];
struct cmd_builder cmd_builder;
};
/** translate the vpe ip version into vpe hw level */
enum vpe_ip_level vpe_resource_parse_ip_version(
uint8_t mj, uint8_t mi, uint8_t rv);
/** initialize the resource ased on vpe hw level */
enum vpe_status vpe_construct_resource(
struct vpe_priv *vpe_priv, enum vpe_ip_level level, struct resource *resource);
/** destroy the resource */
void vpe_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res);
/** alloc segment ctx*/
struct segment_ctx *vpe_alloc_segment_ctx(struct vpe_priv *vpe_priv, uint16_t num_segments);
/** stream ctx */
struct stream_ctx *vpe_alloc_stream_ctx(struct vpe_priv *vpe_priv, uint32_t num_streams);
void vpe_free_stream_ctx(struct vpe_priv *vpe_priv);
/** output ctx */
void vpe_free_output_ctx(struct vpe_priv *vpe_priv);
/** pipe resource management */
void vpe_pipe_reset(struct vpe_priv *vpe_priv);
void vpe_pipe_reclaim(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info);
struct pipe_ctx *vpe_pipe_find_owner(struct vpe_priv *vpe_priv, uint32_t stream_idx, bool *reuse);
/** resource helper */
void vpe_clip_stream(
struct vpe_rect *src_rect, struct vpe_rect *dst_rect, const struct vpe_rect *target_rect);
void calculate_scaling_ratios(struct scaler_data *scl_data, struct vpe_rect *src_rect,
struct vpe_rect *dst_rect, enum vpe_surface_pixel_format format);
uint16_t vpe_get_num_segments(struct vpe_priv *vpe_priv, const struct vpe_rect *src,
const struct vpe_rect *dst, const uint32_t max_seg_width);
enum vpe_status vpe_resource_build_scaling_params(struct segment_ctx *segment);
void vpe_handle_output_h_mirror(struct vpe_priv *vpe_priv);
void vpe_resource_build_bit_depth_reduction_params(
struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,40 @@
/* 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 "vpe_types.h"
#include "hw_shared.h"
#include <math.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define SHAPER_EXP_MAX_IN 16
struct vpe_shaper_setup_in {
double source_luminance;
double shaper_in_max;
bool use_const_hdr_mult;
};
enum vpe_status vpe_build_shaper(
const struct vpe_shaper_setup_in *shaper_in, struct pwl_params *shaper_out);
+113
View File
@@ -0,0 +1,113 @@
/* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "vpe_hw_types.h"
#include "fixed31_32.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VPE_GAMUT_REMAP_MATRIX_SIZE 12
enum gamut_adjust_type {
GAMUT_ADJUST_TYPE_BYPASS = 0,
GAMUT_ADJUST_TYPE_SW /* use adjustments */
};
struct gamut_remap_matrix {
struct fixed31_32 matrix[VPE_GAMUT_REMAP_MATRIX_SIZE];
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;
struct fixed31_32 horz_c;
struct fixed31_32 vert_c;
};
struct sharpness_adj {
int horz;
int vert;
};
struct line_buffer_params {
bool alpha_en;
};
struct scl_inits {
struct fixed31_32 h;
struct fixed31_32 h_c;
struct fixed31_32 v;
struct fixed31_32 v_c;
};
struct scaler_data {
uint32_t h_active;
uint32_t v_active;
struct vpe_scaling_taps taps;
struct vpe_rect viewport;
struct vpe_rect viewport_c;
struct vpe_rect dst_viewport;
struct vpe_rect dst_viewport_c;
struct vpe_rect recout;
struct scaling_ratios ratios;
struct scl_inits inits;
struct sharpness_adj sharpness;
enum vpe_surface_pixel_format format;
struct line_buffer_params lb_params;
struct vpe_scaling_filter_coeffs *polyphase_filter_coeffs;
};
const uint16_t *vpe_get_filter_2tap_64p(void);
const uint16_t *vpe_get_2tap_bilinear_64p(void);
const uint16_t *vpe_get_filter_4tap_64p(struct fixed31_32 ratio);
const uint16_t *vpe_get_filter_6tap_64p(struct fixed31_32 ratio);
const uint16_t *vpe_get_filter_8tap_64p(struct fixed31_32 ratio);
#ifdef __cplusplus
}
#endif
+52
View File
@@ -0,0 +1,52 @@
/* 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
#include <assert.h>
#if defined(_WIN32)
#define VPE_DEBUG_BREAK() __debugbreak()
#else
#include <signal.h>
#define VPE_DEBUG_BREAK() raise(SIGTRAP);
#endif
#ifdef _DEBUG
#define VPE_ASSERT(_expr) assert(_expr)
#else
#define VPE_ASSERT(_expr) ((void)0)
#endif
#ifdef __cplusplus
}
#endif
+206
View File
@@ -0,0 +1,206 @@
/* 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
/****************
* VPE OP Codes
****************/
enum VPE_CMD_OPCODE {
VPE_CMD_OPCODE_NOP = 0x0,
VPE_CMD_OPCODE_VPE_DESC = 0x1,
VPE_CMD_OPCODE_PLANE_CFG = 0x2,
VPE_CMD_OPCODE_VPEP_CFG = 0x3,
VPE_CMD_OPCODE_FENCE = 0x5,
VPE_CMD_OPCODE_TRAP = 0x6,
VPE_CMD_OPCODE_REG_WRITE = 0x7,
VPE_CMD_OPCODE_POLL_REGMEM = 0x8,
VPE_CMD_OPCODE_ATOMIC = 0xA,
VPE_CMD_OPCODE_PLANE_FILL = 0xB,
VPE_CMD_OPCODE_TIMESTAMP = 0xD
};
/** 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 0x000F0000
#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 0x0000000000000003
#define VPE_DESC_NUM_CONFIG_DESCRIPTOR__SHIFT 0
#define VPE_DESC_NUM_CONFIG_DESCRIPTOR_MASK 0x000000FF
#define VPE_DESC_REUSE__MASK 0x00000002
#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_CFG_ONE_PLANE 0
#define VPE_PLANE_CFG_TWO_PLANES 1
#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_TMZ__SHIFT 16
#define VPE_PLANE_CFG_TMZ_MASK 0x00010000
#define VPE_PLANE_CFG_SWIZZLE_MODE__SHIFT 3
#define VPE_PLANE_CFG_SWIZZLE_MODE_MASK 0x000000F8
#define VPE_PLANE_CFG_ROTATION__SHIFT 0
#define VPE_PLANE_CFG_ROTATION_MASK 0x00000003
#define VPE_PLANE_CFG_MIRROR__SHIFT 0
#define VPE_PLANE_CFG_MIRROR_MASK 0x00000003
#define VPE_PLANE_ADDR_LO__SHIFT 0
#define VPE_PLANE_ADDR_LO_MASK 0xFFFFFF00
#define VPE_PLANE_CFG_PITCH__SHIFT 0
#define VPE_PLANE_CFG_PITCH_MASK 0x00003FFF
#define VPE_PLANE_CFG_VIEWPORT_Y__SHIFT 16
#define VPE_PLANE_CFG_VIEWPORT_Y_MASK 0x3FFF0000
#define VPE_PLANE_CFG_VIEWPORT_X__SHIFT 0
#define VPE_PLANE_CFG_VIEWPORT_X_MASK 0x00003FFF
#define VPE_PLANE_CFG_VIEWPORT_HEIGHT__SHIFT 16
#define VPE_PLANE_CFG_VIEWPORT_HEIGHT_MASK 0x1FFF0000
#define VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE__SHIFT 13
#define VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE_MASK 0x0000E000
#define VPE_PLANE_CFG_VIEWPORT_WIDTH__SHIFT 0
#define VPE_PLANE_CFG_VIEWPORT_WIDTH_MASK 0x00001FFF
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) \
(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) | \
(((npd0) << VPE_PLANE_CFG_NPD1__SHIFT) & VPE_PLANE_CFG_NPD1_MASK))
/************************
* VPEP Config
************************/
enum VPE_VPEP_CFG_SUBOP {
VPE_VPEP_CFG_SUBOP_DIR_CFG = 0x0,
VPE_VPEP_CFG_SUBOP_IND_CFG = 0x1
};
// Direct Config Command Header
#define VPE_DIR_CFG_HEADER_ARRAY_SIZE__SHIFT 16
#define VPE_DIR_CFG_HEADER_ARRAY_SIZE_MASK 0xFFFF0000
#define VPE_DIR_CFG_CMD_HEADER(arr_sz) \
(VPE_CMD_HEADER(VPE_CMD_OPCODE_VPEP_CFG, VPE_VPEP_CFG_SUBOP_DIR_CFG) | \
(((arr_sz) << VPE_DIR_CFG_HEADER_ARRAY_SIZE__SHIFT) & VPE_DIR_CFG_HEADER_ARRAY_SIZE_MASK))
#define VPE_DIR_CFG_PKT_REGISTER_OFFSET__SHIFT 2
#define VPE_DIR_CFG_PKT_REGISTER_OFFSET_MASK 0x000FFFFC
#define VPE_DIR_CFG_PKT_DATA_SIZE__SHIFT 20
#define VPE_DIR_CFG_PKT_DATA_SIZE_MASK 0xFFF00000
// InDirect Config Command Header
#define VPE_IND_CFG_HEADER_NUM_DST__SHIFT 28
#define VPE_IND_CFG_HEADER_NUM_DST_MASK 0xF0000000
#define VPE_IND_CFG_CMD_HEADER(num_dst) \
(VPE_CMD_HEADER(VPE_CMD_OPCODE_VPEP_CFG, VPE_VPEP_CFG_SUBOP_IND_CFG) | \
((((uint32_t)num_dst) << VPE_IND_CFG_HEADER_NUM_DST__SHIFT) & \
VPE_IND_CFG_HEADER_NUM_DST_MASK))
#define VPE_IND_CFG_DATA_ARRAY_SIZE__SHIFT 0
#define VPE_IND_CFG_DATA_ARRAY_SIZE_MASK 0x0007FFFF
#define VPE_IND_CFG_PKT_REGISTER_OFFSET__SHIFT 2
#define VPE_IND_CFG_PKT_REGISTER_OFFSET_MASK 0x000FFFFC
/**************************
* Poll Reg/Mem Sub-OpCode
**************************/
enum VPE_POLL_REGMEM_SUBOP {
VPE_POLL_REGMEM_SUBOP_REGMEM = 0x0,
VPE_POLL_REGMEM_SUBOP_REGMEM_WRITE = 0x1
};
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,70 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpe_desc_writer {
struct vpe_buf *buf; /**< store the current buf pointer */
/* store the base addr of the currnet config
* i.e. config header
* it is always constructed in emb_buf
*/
uint64_t base_gpu_va;
uint64_t base_cpu_va;
uint32_t num_config_desc;
bool plane_desc_added;
enum vpe_status status;
};
/** initialize the vpe descriptor writer.
* Calls right before building any vpe descriptor
*
* /param writer writer instance
* /param buf points to the current buf,
* each config_writer_fill will update the address
* /param cd count down of slice in a frame
*/
void vpe_desc_writer_init(struct vpe_desc_writer *writer, struct vpe_buf *buf, int cd);
/** fill the value to the command buffer. */
void vpe_desc_writer_add_plane_desc(
struct vpe_desc_writer *writer, uint64_t plane_desc_addr, bool tmz);
/** fill the value to the command buffer. */
void vpe_desc_writer_add_config_desc(
struct vpe_desc_writer *writer, uint64_t config_desc_addr, bool reuse, bool tmz);
void vpe_desc_writer_complete(struct vpe_desc_writer *writer);
#ifdef __cplusplus
}
#endif
+262
View File
@@ -0,0 +1,262 @@
/* 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 "vpe_types.h"
#include "resource.h"
#include "transform.h"
#include "color.h"
#include "color_gamma.h"
#include "vpe_desc_writer.h"
#include "plane_desc_writer.h"
#include "config_writer.h"
#include "color_cs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define vpe_zalloc(size) vpe_priv->init.funcs.zalloc(vpe_priv->init.funcs.mem_ctx, size)
#define vpe_free(ptr) vpe_priv->init.funcs.free(vpe_priv->init.funcs.mem_ctx, (ptr))
#define vpe_log(...) \
do { \
vpe_priv->init.funcs.log(vpe_priv->init.funcs.log_ctx, "vpe: "); \
vpe_priv->init.funcs.log(vpe_priv->init.funcs.log_ctx, __VA_ARGS__); \
} while (0)
#define container_of(ptr, type, member) (type *)(void *)((char *)ptr - offsetof(type, member))
#define VPE_MIN_VIEWPORT_SIZE \
2 // chroma viewport size is half of it, thus need to be 2 for YUV420
// for simplication we just use 2 for all types
#define MAX_VPE_CMD 256 // TODO Dynamic allocation
#define MAX_LINE_SIZE 1024 // without 16 pixels for the seams
#define MAX_LINE_CNT 4
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
};
enum vpe_cmd_type {
VPE_CMD_TYPE_COMPOSITING,
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_COUNT
};
/** this represents a segement context.
* each segment has its own version of data */
struct segment_ctx {
uint16_t segment_idx;
struct stream_ctx *stream_ctx;
struct scaler_data scaler_data;
};
struct vpe_cmd_input {
uint16_t stream_idx;
struct scaler_data scaler_data;
};
struct vpe_cmd_info {
enum vpe_cmd_ops ops;
uint8_t cd; // count down value
// input
uint16_t num_inputs;
struct vpe_cmd_input inputs[MAX_PIPE];
// output
struct vpe_rect dst_viewport;
struct vpe_rect dst_viewport_c;
bool tm_enabled;
bool is_begin;
bool is_end;
};
struct config_record {
uint64_t config_base_addr;
int64_t config_size;
};
/** represents a stream input, i.e. common to all segments */
struct stream_ctx {
struct vpe_priv *vpe_priv;
int32_t stream_idx;
struct vpe_stream stream; /**< stores all the input data */
uint16_t num_segments;
struct segment_ctx *segment_ctx;
uint16_t num_configs; // shared among same stream
uint16_t num_stream_op_configs[VPE_CMD_TYPE_COUNT]; // shared among same cmd type within the
// same stream
struct config_record configs[16];
struct config_record stream_op_configs[VPE_CMD_TYPE_COUNT][16];
// cached color properties
bool per_pixel_alpha;
enum color_transfer_func tf;
enum color_space cs;
bool enable_3dlut;
bool update_3dlut;
union {
struct {
unsigned int color_space : 1;
unsigned int transfer_function : 1;
unsigned int pixel_format : 1;
unsigned int reserved : 1;
};
unsigned int u32All;
} dirty_bits;
struct bias_and_scale *bias_scale;
struct transfer_func *input_tf;
struct vpe_csc_matrix *input_cs;
struct colorspace_transform *gamut_remap;
struct transfer_func *in_shaper_func; // for shaper lut
struct vpe_3dlut *lut3d_func; // for 3dlut
struct transfer_func *blend_tf; // for 1dlut
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 scaling factor that acts as a gain on the transfer function
};
struct output_ctx {
// stores the paramters built for generating vpep configs
struct vpe_surface_info surface;
struct vpe_color bg_color;
struct vpe_rect target_rect;
enum vpe_alpha_mode alpha_mode;
struct vpe_clamping_params clamping_params;
// cached color properties
enum color_transfer_func tf;
enum color_space cs;
uint32_t num_configs;
struct config_record configs[8];
union {
struct {
unsigned int color_space : 1;
unsigned int transfer_function : 1;
unsigned int lut3d : 1;
unsigned int reserved : 1;
};
unsigned int u32All;
} dirty_bits;
struct transfer_func *output_tf;
const struct transfer_func *in_shaper_func; // for shaper lut
const struct vpe_3dlut *lut3d_func; // for 3dlut
const struct transfer_func *blend_tf; // for 1dlut
struct colorspace_transform *gamut_remap; // post blend gamut remap
struct {
uint32_t hdr_metadata : 1;
uint32_t reserved : 31;
} flags;
struct vpe_hdr_metadata hdr_metadata;
};
#define PIPE_CTX_NO_OWNER ((uint32_t)(-1))
struct pipe_ctx {
uint32_t pipe_idx;
uint32_t owner; // stream_idx
bool is_top_pipe;
int32_t top_pipe_idx;
};
struct config_frontend_cb_ctx {
struct vpe_priv *vpe_priv;
uint32_t stream_idx;
bool stream_sharing;
bool stream_op_sharing;
enum vpe_cmd_type cmd_type; // command type, i.e. bg or compositing
};
struct config_backend_cb_ctx {
struct vpe_priv *vpe_priv;
bool share; // add to output_ctx if true
};
/** internal vpe instance */
struct vpe_priv {
/** public */
struct vpe pub; /**< public member */
/** internal */
struct vpe_init_data init;
struct resource resource;
struct calculate_buffer cal_buffer;
struct vpe_bufs_req bufs_required; /**< cached required buffer size for the checked ops */
// number of total vpe cmds
uint16_t num_vpe_cmds;
struct vpe_cmd_info vpe_cmd_info[MAX_VPE_CMD];
bool ops_support;
// writers
struct vpe_desc_writer vpe_desc_writer;
struct plane_desc_writer plane_desc_writer;
struct config_writer config_writer;
struct config_frontend_cb_ctx fe_cb_ctx;
struct config_backend_cb_ctx be_cb_ctx;
// input ctx
uint32_t num_streams;
struct stream_ctx *stream_ctx;
// output ctx
struct output_ctx output_ctx;
uint16_t num_pipe;
struct pipe_ctx pipe_ctx[MAX_PIPE];
// internal temp structure for creating pure BG filling
struct vpe_build_param *dummy_input_param;
struct vpe_stream *dummy_stream;
bool scale_yuv_matrix; // this is a flag that forces scaling the yuv->rgb matrix
// when embedding the color adjustments
enum vpe_expansion_mode expansion_mode;
};
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,43 @@
/* Copyright 2023 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 "resource.h"
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define VISUAL_CONFIRM_HEIGHT 8
struct vpe_color vpe_get_visual_confirm_color(enum vpe_surface_pixel_format format,
struct vpe_color_space cs, enum color_space output_cs, struct transfer_func *output_tf,
bool enable_3dLut);
enum vpe_status vpe_create_visual_confirm_segs(
struct vpe_priv *vpe_priv, const struct vpe_build_param *params, uint32_t max_seg_width);
#ifdef __cplusplus
}
#endif
+51
View File
@@ -0,0 +1,51 @@
/* 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 "vpe_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vpec;
struct vpe_priv;
struct vpec_funcs {
/** functions for capability check */
bool (*check_swmode_support)(struct vpec *vpec, enum vpe_swizzle_mode_values sw_mode);
bool (*get_dcc_compression_cap)(struct vpec *vpec, const struct vpe_dcc_surface_param *input,
struct vpe_surface_dcc_cap *output);
};
struct vpec {
struct vpe_priv *vpe_priv;
struct vpec_funcs *funcs;
};
#ifdef __cplusplus
}
#endif
+179
View File
@@ -0,0 +1,179 @@
/* 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 "vpe_priv.h"
#include "common.h"
#include "mpc.h"
enum mpc_color_space_type {
COLOR_SPACE_RGB_TYPE,
COLOR_SPACE_RGB_LIMITED_8PBC_TYPE,
COLOR_SPACE_RGB_LIMITED_10PBC_TYPE,
COLOR_SPACE_YCBCR601_TYPE,
COLOR_SPACE_YCBCR709_TYPE,
COLOR_SPACE_YCBCR2020_TYPE,
COLOR_SPACE_YCBCR601_LIMITED_TYPE,
COLOR_SPACE_YCBCR709_LIMITED_TYPE,
// COLOR_SPACE_YCBCR709_BLACK_TYPE,
};
struct out_csc_color_matrix_type {
enum mpc_color_space_type color_space_type;
uint16_t regval[12];
};
static const struct out_csc_color_matrix_type output_csc_matrix[] = {
{COLOR_SPACE_RGB_TYPE, {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0}},
{COLOR_SPACE_RGB_LIMITED_8PBC_TYPE,
{0x1B7B, 0, 0, 0x202, 0, 0x1B7B, 0, 0x202, 0, 0, 0x1B7B, 0x202}},
{COLOR_SPACE_RGB_LIMITED_10PBC_TYPE,
{0x1B66, 0, 0, 0x200, 0, 0x1B66, 0, 0x200, 0, 0, 0x1B66, 0x200}},
{COLOR_SPACE_YCBCR601_TYPE, {0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
0xF6B7, 0xE04, 0x1004}},
{COLOR_SPACE_YCBCR709_TYPE, {0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA, 0x201, 0xFCCA,
0xF533, 0xE04, 0x1004}},
/* TODO: correct values below */
{COLOR_SPACE_YCBCR601_LIMITED_TYPE, {0xE00, 0xF447, 0xFDB9, 0x1000, 0x991, 0x12C9, 0x3A6, 0x200,
0xFB47, 0xF6B9, 0xE00, 0x1000}},
{COLOR_SPACE_YCBCR709_LIMITED_TYPE, {0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, 0x24F, 0x200,
0xFCCB, 0xF535, 0xE00, 0x1000}},
{COLOR_SPACE_YCBCR2020_TYPE, {0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2, 0x01E6, 0x0000,
0xFB88, 0xF478, 0x1000, 0x0000}},
};
static bool is_rgb_full_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_SRGB || color_space == COLOR_SPACE_MSREF_SCRGB ||
color_space == COLOR_SPACE_2020_RGB_FULLRANGE)
ret = true;
return ret;
}
static bool is_rgb_limited_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_SRGB_LIMITED || color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
ret = true;
return ret;
}
static bool is_ycbcr601_full_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_YCBCR601)
ret = true;
return ret;
}
static bool is_ycbcr601_limited_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
ret = true;
return ret;
}
static bool is_ycbcr709_full_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_YCBCR709)
ret = true;
return ret;
}
static bool is_ycbcr709_limited_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
ret = true;
return ret;
}
static bool is_ycbcr2020_type(enum color_space color_space)
{
bool ret = false;
if (color_space == COLOR_SPACE_2020_YCBCR)
ret = true;
return ret;
}
static enum mpc_color_space_type get_color_space_type(
enum color_space color_space, enum vpe_surface_pixel_format pixel_format)
{
enum mpc_color_space_type type = COLOR_SPACE_RGB_TYPE;
if (is_rgb_full_type(color_space))
type = COLOR_SPACE_RGB_TYPE;
else if (is_rgb_limited_type(color_space))
type = vpe_is_rgb8(pixel_format) ? COLOR_SPACE_RGB_LIMITED_8PBC_TYPE
: COLOR_SPACE_RGB_LIMITED_10PBC_TYPE;
else if (is_ycbcr601_full_type(color_space))
type = COLOR_SPACE_YCBCR601_TYPE;
else if (is_ycbcr709_full_type(color_space))
type = COLOR_SPACE_YCBCR709_TYPE;
else if (is_ycbcr601_limited_type(color_space))
type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
else if (is_ycbcr709_limited_type(color_space))
type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
else if (is_ycbcr2020_type(color_space))
type = COLOR_SPACE_YCBCR2020_TYPE;
return type;
}
#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
const uint16_t *vpe_find_color_matrix(
enum color_space color_space, enum vpe_surface_pixel_format pixel_format, uint32_t *array_size)
{
int i;
enum mpc_color_space_type type;
const uint16_t *val = NULL;
int arr_size = NUM_ELEMENTS(output_csc_matrix);
type = get_color_space_type(color_space, pixel_format);
for (i = 0; i < arr_size; i++)
if (output_csc_matrix[i].color_space_type == type) {
val = output_csc_matrix[i].regval;
*array_size = 12;
break;
}
return val;
}
+143
View File
@@ -0,0 +1,143 @@
/* 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 "vpe_assert.h"
#include "vpe_command.h"
#include "plane_desc_writer.h"
#include "reg_helper.h"
void plane_desc_writer_init(struct plane_desc_writer *writer, struct vpe_buf *buf, int32_t nps0,
int32_t npd0, int32_t nps1, int32_t npd1, int32_t subop)
{
uint32_t *cmd_space;
uint64_t size = 4;
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 < (int64_t)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(subop, nps0, npd0, nps1, npd1);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
/** fill the value to the embedded buffer. */
void plane_desc_writer_add_source(
struct plane_desc_writer *writer, struct plane_desc_src *src, 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);
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < (int64_t)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_ROTATION, src->rotation);
writer->num_src++;
}
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); // 1-based number of element
*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) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE, src->elem_size);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
/** fill the value to the embedded buffer. */
void plane_desc_writer_add_destination(
struct plane_desc_writer *writer, struct plane_desc_dst *dst, 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);
if (writer->status != VPE_STATUS_OK)
return;
/* Buffer does not have enough space to write */
if (writer->buf->size < (int64_t)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, dst->tmz) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_SWIZZLE_MODE, dst->swizzle) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_MIRROR, dst->mirror);
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); // 1-based number of element
*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) |
VPEC_FIELD_VALUE(VPE_PLANE_CFG_VIEWPORT_ELEMENT_SIZE, dst->elem_size);
writer->buf->cpu_va += size;
writer->buf->gpu_va += size;
writer->buf->size -= size;
}
+660
View File
@@ -0,0 +1,660 @@
/* 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 <math.h>
#include "vpe_types.h"
#include "vpe_priv.h"
#include "vpe_version.h"
#include "common.h"
#ifdef VPE_BUILD_1_0
#include "vpe10_resource.h"
#endif
static const struct vpe_debug_options debug_defaults = {
.flags = {0},
.cm_in_bypass = 0,
.vpcnvc_bypass = 0,
.mpc_bypass = 0,
.identity_3dlut = 0,
.sce_3dlut = 0,
.disable_reuse_bit = 0,
.bg_bit_depth = 0,
.bypass_gamcor = 0,
.bypass_ogam = 0,
.bypass_dpp_gamut_remap = 0,
.bypass_post_csc = 0,
.bg_color_fill_only = 0,
.assert_when_not_support = 0,
.enable_mem_low_power =
{
.bits =
{
.cm = false,
.dscl = false,
.mpc = false,
},
},
.force_tf_calculation = 1,
.expansion_mode = 1,
.clamping_setting = 1,
.clamping_params =
{
.r_clamp_component_lower = 0x1000,
.g_clamp_component_lower = 0x1000,
.b_clamp_component_lower = 0x1000,
.r_clamp_component_upper = 0xEB00,
.g_clamp_component_upper = 0xEB00,
.b_clamp_component_upper = 0xEB00,
.clamping_range = 4,
},
.bypass_per_pixel_alpha = 0,
.opp_pipe_crc_ctrl = 0,
.dpp_crc_ctrl = 0,
.mpc_crc_ctrl = 0,
.visual_confirm_params = {{{0}}},
};
enum vpe_ip_level vpe_resource_parse_ip_version(
uint8_t mj, uint8_t mn, uint8_t rv)
{
enum vpe_ip_level ip_level = VPE_IP_LEVEL_UNKNOWN;
switch (VPE_VERSION(mj, mn, rv)) {
#if VPE_BUILD_1_X
#if VPE_BUILD_1_0
case VPE_VERSION(6, 1, 0):
ip_level = VPE_IP_LEVEL_1_0;
#endif
break;
#endif
default:
ip_level = VPE_IP_LEVEL_UNKNOWN;
break;
}
return ip_level;
}
enum vpe_status vpe_construct_resource(
struct vpe_priv *vpe_priv, enum vpe_ip_level level, struct resource *res)
{
enum vpe_status status = VPE_STATUS_OK;
switch (level) {
#ifdef VPE_BUILD_1_0
case VPE_IP_LEVEL_1_0:
status = vpe10_construct_resource(vpe_priv, res);
break;
#endif
default:
status = VPE_STATUS_NOT_SUPPORTED;
vpe_log("invalid ip level: %d", (int)level);
break;
}
vpe_priv->init.debug = debug_defaults;
vpe_priv->expansion_mode = vpe_priv->init.debug.expansion_mode;
if (res)
res->vpe_priv = vpe_priv;
return status;
}
void vpe_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res)
{
switch (vpe_priv->pub.level) {
#ifdef VPE_BUILD_1_0
case VPE_IP_LEVEL_1_0:
vpe10_destroy_resource(vpe_priv, res);
break;
#endif
default:
break;
}
}
struct segment_ctx *vpe_alloc_segment_ctx(struct vpe_priv *vpe_priv, uint16_t num_segments)
{
struct segment_ctx *segment_ctx_base;
segment_ctx_base = (struct segment_ctx *)vpe_zalloc(sizeof(struct segment_ctx) * num_segments);
if (!segment_ctx_base)
return NULL;
return segment_ctx_base;
}
struct stream_ctx *vpe_alloc_stream_ctx(struct vpe_priv *vpe_priv, uint32_t num_streams)
{
struct stream_ctx *ctx_base, *ctx;
uint32_t i;
ctx_base = (struct stream_ctx *)vpe_zalloc(sizeof(struct stream_ctx) * num_streams);
if (!ctx_base)
return NULL;
for (i = 0; i < num_streams; i++) {
ctx = &ctx_base[i];
ctx->cs = COLOR_SPACE_UNKNOWN;
ctx->tf = TRANSFER_FUNC_UNKNOWN;
ctx->vpe_priv = vpe_priv;
vpe_color_set_adjustments_to_default(&ctx->color_adjustments);
ctx->tf_scaling_factor = vpe_fixpt_one;
}
return ctx_base;
}
void vpe_free_stream_ctx(struct vpe_priv *vpe_priv)
{
uint16_t i;
struct stream_ctx *ctx;
if (!vpe_priv->stream_ctx || !vpe_priv->num_streams)
return;
for (i = 0; i < vpe_priv->num_streams; i++) {
ctx = &vpe_priv->stream_ctx[i];
if (ctx->input_tf) {
vpe_free(ctx->input_tf);
ctx->input_tf = NULL;
}
if (ctx->bias_scale) {
vpe_free(ctx->bias_scale);
ctx->bias_scale = NULL;
}
if (ctx->input_cs) {
vpe_free(ctx->input_cs);
ctx->input_cs = NULL;
}
if (ctx->gamut_remap) {
vpe_free(ctx->gamut_remap);
ctx->gamut_remap = NULL;
}
if (ctx->in_shaper_func) {
vpe_free(ctx->in_shaper_func);
ctx->in_shaper_func = NULL;
}
if (ctx->blend_tf) {
vpe_free(ctx->blend_tf);
ctx->blend_tf = NULL;
}
if (ctx->lut3d_func) {
vpe_free(ctx->lut3d_func);
ctx->lut3d_func = NULL;
}
if (ctx->segment_ctx) {
vpe_free(ctx->segment_ctx);
ctx->segment_ctx = NULL;
}
}
vpe_free(vpe_priv->stream_ctx);
vpe_priv->stream_ctx = NULL;
vpe_priv->num_streams = 0;
}
void vpe_free_output_ctx(struct vpe_priv *vpe_priv)
{
if (vpe_priv->output_ctx.gamut_remap)
vpe_free(vpe_priv->output_ctx.gamut_remap);
if (vpe_priv->output_ctx.output_tf)
vpe_free(vpe_priv->output_ctx.output_tf);
}
void vpe_pipe_reset(struct vpe_priv *vpe_priv)
{
int i;
struct pipe_ctx *pipe_ctx;
for (i = 0; i < vpe_priv->num_pipe; i++) {
pipe_ctx = &vpe_priv->pipe_ctx[i];
pipe_ctx->is_top_pipe = true;
pipe_ctx->owner = PIPE_CTX_NO_OWNER;
pipe_ctx->top_pipe_idx = 0xff;
}
}
void vpe_pipe_reclaim(struct vpe_priv *vpe_priv, struct vpe_cmd_info *cmd_info)
{
int i, j;
struct pipe_ctx *pipe_ctx;
for (i = 0; i < vpe_priv->num_pipe; i++) {
pipe_ctx = &vpe_priv->pipe_ctx[i];
if (pipe_ctx->owner != PIPE_CTX_NO_OWNER) {
for (j = 0; j < cmd_info->num_inputs; j++)
if (pipe_ctx->owner == cmd_info->inputs[j].stream_idx)
break;
if (j == cmd_info->num_inputs) {
// that stream no longer exists
pipe_ctx->is_top_pipe = true;
pipe_ctx->owner = PIPE_CTX_NO_OWNER;
pipe_ctx->top_pipe_idx = 0xff;
}
}
}
}
struct pipe_ctx *vpe_pipe_find_owner(struct vpe_priv *vpe_priv, uint32_t stream_idx, bool *reuse)
{
int i;
struct pipe_ctx *pipe_ctx;
struct pipe_ctx *free_pipe = NULL;
for (i = 0; i < vpe_priv->num_pipe; i++) {
pipe_ctx = &vpe_priv->pipe_ctx[i];
if (!free_pipe && (pipe_ctx->owner == PIPE_CTX_NO_OWNER))
free_pipe = pipe_ctx;
// re-use the same pipe
else if (pipe_ctx->owner == stream_idx) {
*reuse = true;
return pipe_ctx;
}
}
if (free_pipe) {
free_pipe->owner = stream_idx;
}
*reuse = false;
return free_pipe;
}
static void calculate_recout(struct segment_ctx *segment)
{
struct stream_ctx *stream_ctx = segment->stream_ctx;
struct scaler_data *data = &segment->scaler_data;
struct vpe_rect *dst_rect;
int32_t split_count, split_idx;
dst_rect = &stream_ctx->stream.scaling_info.dst_rect;
split_count = stream_ctx->num_segments - 1;
split_idx = segment->segment_idx;
// src & dst rect has been clipped earlier
data->recout.x = 0;
data->recout.y = 0;
data->recout.width = dst_rect->width;
data->recout.height = dst_rect->height;
if (split_count) {
/* extra pixels in the division remainder need to go to pipes after
* the extra pixel index minus one(epimo) defined here as:
*/
int32_t epimo = split_count - (int32_t)data->recout.width % (split_count + 1);
data->recout.x += ((int32_t)data->recout.width / (split_count + 1)) * split_idx;
if (split_idx > epimo)
data->recout.x += split_idx - epimo - 1;
data->recout.width =
data->recout.width / (uint32_t)(split_count + 1) + (split_idx > epimo ? 1 : 0);
}
}
void calculate_scaling_ratios(struct scaler_data *scl_data, struct vpe_rect *src_rect,
struct vpe_rect *dst_rect, enum vpe_surface_pixel_format format)
{
// no rotation support
scl_data->ratios.horz = vpe_fixpt_from_fraction(src_rect->width, dst_rect->width);
scl_data->ratios.vert = vpe_fixpt_from_fraction(src_rect->height, dst_rect->height);
scl_data->ratios.horz_c = scl_data->ratios.horz;
scl_data->ratios.vert_c = scl_data->ratios.vert;
if (vpe_is_yuv420(format)) {
scl_data->ratios.horz_c.value /= 2;
scl_data->ratios.vert_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);
scl_data->ratios.vert_c = vpe_fixpt_truncate(scl_data->ratios.vert_c, 19);
}
/*
* This is a preliminary vp size calculation to allow us to check taps support.
* The result is completely overridden afterwards.
*/
static void calculate_viewport_size(struct segment_ctx *segment_ctx)
{
struct scaler_data *data = &segment_ctx->scaler_data;
data->viewport.width =
(uint32_t)vpe_fixpt_ceil(vpe_fixpt_mul_int(data->ratios.horz, (int)data->recout.width));
data->viewport.height =
(uint32_t)vpe_fixpt_ceil(vpe_fixpt_mul_int(data->ratios.vert, (int)data->recout.height));
data->viewport_c.width =
(uint32_t)vpe_fixpt_ceil(vpe_fixpt_mul_int(data->ratios.horz_c, (int)data->recout.width));
data->viewport_c.height =
(uint32_t)vpe_fixpt_ceil(vpe_fixpt_mul_int(data->ratios.vert_c, (int)data->recout.height));
}
/*
* We completely calculate vp offset, size and inits here based entirely on scaling
* ratios and recout for pixel perfect pipe combine.
*/
static void calculate_init_and_vp(bool flip_scan_dir, int32_t recout_offset, uint32_t recout_size,
uint32_t src_size, uint32_t taps, struct fixed31_32 ratio, struct fixed31_32 init_adj,
struct fixed31_32 *init, int32_t *vp_offset, uint32_t *vp_size)
{
struct fixed31_32 src_offset, temp;
int32_t int_part;
/*
* First of the taps starts sampling pixel number <init_int_part> corresponding to recout
* pixel 1. Next recout pixel samples int part of <init + scaling ratio> and so on.
* All following calculations are based on this logic.
*/
src_offset = vpe_fixpt_mul_int(ratio, recout_offset);
*vp_offset = vpe_fixpt_floor(src_offset);
// calculate the phase
init->value = src_offset.value & 0xffffffff; // for phase accumulation
*init = vpe_fixpt_add(*init, init_adj);
int_part = vpe_fixpt_floor(vpe_fixpt_from_fraction(taps, 2)) +
1; // middle point of the sampling window
*init = vpe_fixpt_add_int(*init, int_part);
*init = vpe_fixpt_truncate(*init, 19);
/*
* If there are more pixels on the left hand side (top for vertical scaling) of the
* sampling point which can be covered by the taps, init value needs go get increased
* to be able to buffer the pixels as much as taps.
*/
if (int_part < (int32_t)taps) {
int32_t left = (int32_t)taps - int_part;
if (left > *vp_offset)
left = *vp_offset;
*vp_offset -= left;
*init = vpe_fixpt_add_int(*init, left);
}
/*
* If taps are sampling outside of viewport at end of recout and there are more pixels
* available in the surface we should increase the viewport size, regardless set vp to
* only what is used.
*/
temp = vpe_fixpt_add(*init, vpe_fixpt_mul_int(ratio, (int)(recout_size - 1)));
*vp_size = (uint32_t)vpe_fixpt_floor(temp);
if ((uint32_t)((int32_t)*vp_size + *vp_offset) > src_size)
*vp_size = (uint32_t)((int32_t)src_size - *vp_offset);
/* We did all the math assuming we are scanning same direction as display does,
* however mirror/rotation changes how vp scans vs how it is offset. If scan direction
* is flipped we simply need to calculate offset from the other side of plane.
* Note that outside of viewport all scaling hardware works in recout space.
*/
if (flip_scan_dir)
*vp_offset = (int32_t)src_size - *vp_offset - (int32_t)*vp_size;
}
static inline void get_vp_scan_direction(enum vpe_rotation_angle rotation, bool horizontal_mirror,
bool *orthogonal_rotation, bool *flip_vert_scan_dir, bool *flip_horz_scan_dir)
{
*orthogonal_rotation = false;
*flip_vert_scan_dir = false;
*flip_horz_scan_dir = false;
if (rotation == VPE_ROTATION_ANGLE_180) {
*flip_vert_scan_dir = true;
*flip_horz_scan_dir = true;
} else if (rotation == VPE_ROTATION_ANGLE_90) {
*orthogonal_rotation = true;
*flip_horz_scan_dir = true;
} else if (rotation == VPE_ROTATION_ANGLE_270) {
*orthogonal_rotation = true;
*flip_vert_scan_dir = true;
}
if (horizontal_mirror)
*flip_horz_scan_dir = !*flip_horz_scan_dir;
}
static enum vpe_status calculate_inits_and_viewports(struct segment_ctx *segment_ctx)
{
struct stream_ctx *stream_ctx = segment_ctx->stream_ctx;
struct vpe_surface_info *surface_info = &stream_ctx->stream.surface_info;
struct vpe_rect src_rect = stream_ctx->stream.scaling_info.src_rect;
struct vpe_rect *dst_rect = &stream_ctx->stream.scaling_info.dst_rect;
struct scaler_data *data = &segment_ctx->scaler_data;
uint32_t vpc_div = vpe_is_yuv420(data->format) ? 2 : 1;
bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
struct fixed31_32 init_adj_h = vpe_fixpt_zero;
struct fixed31_32 init_adj_v = vpe_fixpt_zero;
get_vp_scan_direction(stream_ctx->stream.rotation, stream_ctx->stream.horizontal_mirror,
&orthogonal_rotation, &flip_vert_scan_dir, &flip_horz_scan_dir);
if (orthogonal_rotation) {
swap(src_rect.width, src_rect.height);
swap(flip_vert_scan_dir, flip_horz_scan_dir);
}
if (flip_horz_scan_dir) {
if (stream_ctx->flip_horizonal_output)
// flip at the output instead
flip_horz_scan_dir = false;
}
if (vpe_is_yuv420(data->format)) {
int sign = -1; // this gives the direction of the cositing (negative will move left, right
// otherwise)
switch (surface_info->cs.cositing) {
case VPE_CHROMA_COSITING_LEFT:
init_adj_h = vpe_fixpt_zero;
init_adj_v = vpe_fixpt_from_fraction(sign, 4);
break;
case VPE_CHROMA_COSITING_NONE:
init_adj_h = vpe_fixpt_from_fraction(sign, 4);
init_adj_v = vpe_fixpt_from_fraction(sign, 4);
break;
case VPE_CHROMA_COSITING_TOPLEFT:
default:
init_adj_h = vpe_fixpt_zero;
init_adj_v = vpe_fixpt_zero;
break;
}
}
calculate_init_and_vp(flip_horz_scan_dir, data->recout.x, data->recout.width, src_rect.width,
data->taps.h_taps, data->ratios.horz, vpe_fixpt_zero, &data->inits.h, &data->viewport.x,
&data->viewport.width);
calculate_init_and_vp(flip_horz_scan_dir, data->recout.x, data->recout.width,
src_rect.width / vpc_div, data->taps.h_taps_c, data->ratios.horz_c, init_adj_h,
&data->inits.h_c, &data->viewport_c.x, &data->viewport_c.width);
calculate_init_and_vp(flip_vert_scan_dir, data->recout.y, data->recout.height, src_rect.height,
data->taps.v_taps, data->ratios.vert, vpe_fixpt_zero, &data->inits.v, &data->viewport.y,
&data->viewport.height);
calculate_init_and_vp(flip_vert_scan_dir, data->recout.y, data->recout.height,
src_rect.height / vpc_div, data->taps.v_taps_c, data->ratios.vert_c, init_adj_v,
&data->inits.v_c, &data->viewport_c.y, &data->viewport_c.height);
// convert to absolute address
data->viewport.x += src_rect.x;
data->viewport.y += src_rect.y;
data->viewport_c.x += src_rect.x / (int32_t)vpc_div;
data->viewport_c.y += src_rect.y / (int32_t)vpc_div;
return VPE_STATUS_OK;
}
uint16_t vpe_get_num_segments(struct vpe_priv *vpe_priv, const struct vpe_rect *src,
const struct vpe_rect *dst, const uint32_t max_seg_width)
{
int num_seg_src = (int)(ceil((double)src->width / max_seg_width));
int num_seg_dst = (int)(ceil((double)dst->width / max_seg_width));
return (uint16_t)(max(max(num_seg_src, num_seg_dst), 1));
}
void vpe_clip_stream(
struct vpe_rect *src_rect, struct vpe_rect *dst_rect, const struct vpe_rect *target_rect)
{
struct fixed31_32 scaling_ratio_h;
struct fixed31_32 scaling_ratio_v;
struct vpe_rect clipped_dst_rect, clipped_src_rect;
uint32_t clipped_pixels;
clipped_dst_rect = *dst_rect;
clipped_src_rect = *src_rect;
scaling_ratio_h = vpe_fixpt_from_fraction(src_rect->width, dst_rect->width);
scaling_ratio_v = vpe_fixpt_from_fraction(src_rect->height, dst_rect->height);
if (dst_rect->x < target_rect->x) {
clipped_pixels = (uint32_t)(target_rect->x - dst_rect->x);
clipped_dst_rect.x = target_rect->x;
clipped_dst_rect.width -= clipped_pixels;
clipped_pixels = (uint32_t)vpe_fixpt_round(
vpe_fixpt_mul_int(scaling_ratio_h, (int)(target_rect->x - dst_rect->x)));
clipped_src_rect.x += (int32_t)clipped_pixels;
clipped_src_rect.width -= clipped_pixels;
}
if (dst_rect->y < target_rect->y) {
clipped_pixels = (uint32_t)(target_rect->y - dst_rect->y);
clipped_dst_rect.y = target_rect->y;
clipped_dst_rect.height -= clipped_pixels;
clipped_pixels = (uint32_t)vpe_fixpt_round(
vpe_fixpt_mul_int(scaling_ratio_v, (int)(target_rect->y - dst_rect->y)));
clipped_src_rect.y += (int32_t)clipped_pixels;
clipped_src_rect.height -= clipped_pixels;
}
if (dst_rect->x + (int32_t)dst_rect->width > target_rect->x + (int32_t)target_rect->width) {
clipped_dst_rect.width =
(uint32_t)(target_rect->x + (int32_t)target_rect->width - clipped_dst_rect.x);
clipped_src_rect.width = (uint32_t)vpe_fixpt_round(
vpe_fixpt_mul_int(scaling_ratio_h, (int)clipped_dst_rect.width));
}
if (dst_rect->y + (int32_t)dst_rect->height > target_rect->y + (int32_t)target_rect->height) {
clipped_dst_rect.height =
(uint32_t)(target_rect->y + (int32_t)target_rect->height - clipped_dst_rect.y);
clipped_src_rect.height = (uint32_t)vpe_fixpt_round(
vpe_fixpt_mul_int(scaling_ratio_v, (int)clipped_dst_rect.height));
}
*src_rect = clipped_src_rect;
*dst_rect = clipped_dst_rect;
}
enum vpe_status vpe_resource_build_scaling_params(struct segment_ctx *segment_ctx)
{
struct stream_ctx *stream_ctx = segment_ctx->stream_ctx;
struct scaler_data *scl_data = &segment_ctx->scaler_data;
struct dpp *dpp = stream_ctx->vpe_priv->resource.dpp[0];
scl_data->format = stream_ctx->stream.surface_info.format;
scl_data->lb_params.alpha_en = stream_ctx->per_pixel_alpha;
// h/v active will be set later
/* recout.x is temporary for viewport calculation,
* will be finalized in calculate_dst_viewport_and_active()
*/
calculate_recout(segment_ctx);
calculate_viewport_size(segment_ctx);
if (scl_data->viewport.height < 1 || scl_data->viewport.width < 1)
return VPE_STATUS_VIEWPORT_SIZE_NOT_SUPPORTED;
if (!dpp->funcs->validate_number_of_taps(dpp, scl_data)) {
return VPE_STATUS_SCALING_RATIO_NOT_SUPPORTED;
}
calculate_inits_and_viewports(segment_ctx);
if (scl_data->viewport.height < VPE_MIN_VIEWPORT_SIZE ||
scl_data->viewport.width < VPE_MIN_VIEWPORT_SIZE)
return VPE_STATUS_VIEWPORT_SIZE_NOT_SUPPORTED;
return VPE_STATUS_OK;
}
void vpe_handle_output_h_mirror(struct vpe_priv *vpe_priv)
{
uint16_t stream_idx;
int seg_idx;
struct stream_ctx *stream_ctx;
// swap the stream output location
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
if (stream_ctx->flip_horizonal_output) {
struct segment_ctx *first_seg, *last_seg;
// swap the segment output order, init the last segment first
first_seg = &stream_ctx->segment_ctx[0];
last_seg = &stream_ctx->segment_ctx[stream_ctx->num_segments - 1];
// last segment becomes first
last_seg->scaler_data.dst_viewport.x = first_seg->scaler_data.dst_viewport.x;
for (seg_idx = (int)(stream_ctx->num_segments - 2); seg_idx >= 0; seg_idx--) {
struct segment_ctx *prev_seg, *curr_seg;
// set the x in reverse order
prev_seg = &stream_ctx->segment_ctx[seg_idx + 1];
curr_seg = &stream_ctx->segment_ctx[seg_idx];
curr_seg->scaler_data.dst_viewport.x =
prev_seg->scaler_data.dst_viewport.x +
(int32_t)prev_seg->scaler_data.dst_viewport.width;
curr_seg->scaler_data.dst_viewport_c.x =
prev_seg->scaler_data.dst_viewport_c.x +
(int32_t)prev_seg->scaler_data.dst_viewport_c.width;
}
}
}
}
void vpe_resource_build_bit_depth_reduction_params(
struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth)
{
struct vpe_priv *vpe_priv = opp->vpe_priv;
struct vpe_surface_info *dst_surface = &vpe_priv->output_ctx.surface;
enum color_depth display_color_depth;
memset(fmt_bit_depth, 0, sizeof(*fmt_bit_depth));
display_color_depth = vpe_get_color_depth(dst_surface->format);
switch (display_color_depth) {
case COLOR_DEPTH_888:
case COLOR_DEPTH_101010:
fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
fmt_bit_depth->flags.TRUNCATE_DEPTH = (display_color_depth == COLOR_DEPTH_888) ? 1 : 2;
fmt_bit_depth->flags.TRUNCATE_MODE = 1;
break;
default:
break;
}
}
+272
View File
@@ -0,0 +1,272 @@
/* 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 "shaper_builder.h"
#include "custom_fp16.h"
#include "fixed31_32.h"
struct x_axis_config {
int offset;
int segments_num;
};
struct point_config {
int custom_float_x;
int custom_float_y;
int custom_float_slope;
};
struct curve_points32 {
struct point_config red;
struct point_config green;
struct point_config blue;
};
struct lut_point {
int red;
int green;
int blue;
int delta_red;
int delta_green;
int delta_blue;
};
struct pwl_parameter2 {
struct x_axis_config arr_curve_points[34];
struct curve_points32 corner_points[2];
struct lut_point rgb_resulted[256];
int hw_points_num;
};
struct shaper_setup_out {
int exp_begin_raw;
int exp_end_raw;
int begin_custom_1_6_12;
int end_custom_0_6_10;
int end_base_fixed_0_14;
};
static bool calculate_shaper_properties_const_hdr_mult(
const struct vpe_shaper_setup_in *shaper_in, struct shaper_setup_out *shaper_out)
{
double x;
struct vpe_custom_float_format2 fmt;
struct vpe_custom_float_value2 custom_float;
int num_exp;
bool ret = false;
int isize = 1 << 14;
double divider = isize - 1;
double x_double_begin;
double multiplyer = shaper_in->source_luminance / 10000.0 * shaper_in->shaper_in_max;
fmt.flags.Uint = 0;
fmt.flags.bits.sign = 1;
fmt.mantissaBits = 12;
fmt.exponentaBits = 6;
x = pow(1.0 / divider, 2.2) * multiplyer;
if (!vpe_convert_to_custom_float_ex_generic(x, &fmt, &custom_float))
goto release;
shaper_out->exp_begin_raw = custom_float.exponenta;
if (!vpe_from_1_6_12_to_double(false, custom_float.exponenta, 0, &x_double_begin))
goto release;
if (!vpe_convert_to_custom_float_generic(
x_double_begin, &fmt, &shaper_out->begin_custom_1_6_12))
goto release;
fmt.flags.bits.sign = 0;
fmt.mantissaBits = 10;
if (!vpe_convert_to_custom_float_ex_generic(multiplyer, &fmt, &custom_float))
goto release;
shaper_out->exp_end_raw = custom_float.exponenta;
if (!vpe_convert_to_custom_float_generic(multiplyer, &fmt, &shaper_out->end_custom_0_6_10))
goto release;
shaper_out->end_base_fixed_0_14 = isize - 1;
num_exp = shaper_out->exp_end_raw - shaper_out->exp_begin_raw + 1;
if (num_exp > 34)
goto release;
ret = true;
release:
return ret;
}
static bool calculate_shaper_properties_variable_hdr_mult(
const struct vpe_shaper_setup_in *shaper_in, struct shaper_setup_out *shaper_out)
{
struct vpe_custom_float_format2 fmt;
struct vpe_custom_float_value2 custom_float;
int num_exp;
bool ret = false;
int isize = 1 << 14;
double divider = isize - 1;
double x_double_begin = 0;
fmt.flags.Uint = 0;
fmt.exponentaBits = 6;
fmt.mantissaBits = 10;
if (!vpe_convert_to_custom_float_ex_generic(shaper_in->shaper_in_max, &fmt, &custom_float))
goto release;
if (!vpe_convert_to_custom_float_generic(
shaper_in->shaper_in_max, &fmt, &shaper_out->end_custom_0_6_10))
goto release;
shaper_out->exp_end_raw = custom_float.exponenta;
shaper_out->exp_begin_raw = shaper_out->exp_end_raw - 33;
shaper_out->end_base_fixed_0_14 = isize - 1;
if (!vpe_from_1_6_12_to_double(false, shaper_out->exp_begin_raw, 0, &x_double_begin))
goto release;
fmt.mantissaBits = 12;
fmt.flags.bits.sign = 1;
if (!vpe_convert_to_custom_float_generic(
x_double_begin, &fmt, &shaper_out->begin_custom_1_6_12))
goto release;
num_exp = shaper_out->exp_end_raw - shaper_out->exp_begin_raw + 1;
if (num_exp > 34)
goto release;
ret = true;
release:
return ret;
}
static int build_shaper_2_2_segments_distribution(int num_regions, int *arr_segments)
{
int i;
int counter;
int num_segments = 0;
int num_segments_total = 0;
const int proposed_2_2_distribution[] = {5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int proposed_regions = ARRAY_SIZE(proposed_2_2_distribution);
if (proposed_regions < num_regions)
goto release;
counter = 0;
for (i = num_regions - 1; i >= 0; i--) {
arr_segments[counter] = proposed_2_2_distribution[i];
num_segments += 1 << proposed_2_2_distribution[i];
counter++;
}
release:
return num_segments;
}
enum vpe_status vpe_build_shaper(
const struct vpe_shaper_setup_in *shaper_in, struct pwl_params *shaper)
{
enum vpe_status ret = VPE_STATUS_ERROR;
int num_points = 0;
int arr_regions[34];
struct shaper_setup_out shaper_params;
int i, j;
int num_exp;
unsigned int exp;
double x, delta_segments;
int lut_counter = 0;
int segments_current;
int segments_offset;
unsigned int decimalBits = 14;
unsigned int mask = (1 << decimalBits) - 1;
double d_norm = mask;
double divider = shaper_in->shaper_in_max;
if (shaper_in->use_const_hdr_mult &&
!calculate_shaper_properties_const_hdr_mult(shaper_in, &shaper_params))
goto release;
else if (!calculate_shaper_properties_variable_hdr_mult(shaper_in, &shaper_params))
goto release;
exp = shaper_params.exp_begin_raw;
num_exp = shaper_params.exp_end_raw - shaper_params.exp_begin_raw + 1;
num_points = build_shaper_2_2_segments_distribution(num_exp, arr_regions);
segments_offset = 0;
for (i = 0; i < num_exp; i++) {
segments_current = 1 << arr_regions[i];
shaper->arr_curve_points[i].segments_num = arr_regions[i];
shaper->arr_curve_points[i].offset = segments_offset;
segments_offset = segments_offset + segments_current;
if (!vpe_from_1_6_12_to_double(false, exp, 0, &x))
goto release;
x /= divider;
shaper->rgb_resulted[lut_counter].red_reg =
vpe_to_fixed_point(decimalBits, x, mask, d_norm);
shaper->rgb_resulted[lut_counter].green_reg = shaper->rgb_resulted[lut_counter].red_reg;
shaper->rgb_resulted[lut_counter].blue_reg = shaper->rgb_resulted[lut_counter].red_reg;
delta_segments = x / segments_current;
lut_counter++;
for (j = 0; j < segments_current - 1; j++) {
x += delta_segments;
shaper->rgb_resulted[lut_counter].red_reg =
vpe_to_fixed_point(decimalBits, x, mask, d_norm);
shaper->rgb_resulted[lut_counter].green_reg = shaper->rgb_resulted[lut_counter].red_reg;
shaper->rgb_resulted[lut_counter].blue_reg = shaper->rgb_resulted[lut_counter].red_reg;
lut_counter++;
}
exp++;
}
shaper->corner_points[0].red.custom_float_x = shaper_params.begin_custom_1_6_12;
shaper->corner_points[0].green.custom_float_x = shaper->corner_points[0].red.custom_float_x;
shaper->corner_points[0].blue.custom_float_x = shaper->corner_points[0].red.custom_float_x;
shaper->corner_points[1].red.custom_float_x = shaper_params.end_custom_0_6_10;
shaper->corner_points[1].green.custom_float_x = shaper->corner_points[1].red.custom_float_x;
shaper->corner_points[1].blue.custom_float_x = shaper->corner_points[1].red.custom_float_x;
shaper->corner_points[1].red.custom_float_y = shaper_params.end_base_fixed_0_14;
shaper->corner_points[1].green.custom_float_y = shaper->corner_points[1].red.custom_float_y;
shaper->corner_points[1].blue.custom_float_y = shaper->corner_points[1].red.custom_float_y;
for (i = 1; i < num_points; i++) {
shaper->rgb_resulted[i - 1].delta_red_reg =
shaper->rgb_resulted[i].red_reg - shaper->rgb_resulted[i - 1].red_reg;
shaper->rgb_resulted[i - 1].delta_green_reg = shaper->rgb_resulted[i - 1].delta_red_reg;
shaper->rgb_resulted[i - 1].delta_blue_reg = shaper->rgb_resulted[i - 1].delta_red_reg;
}
shaper->hw_points_num = num_points;
ret = VPE_STATUS_OK;
release:
return ret;
}
+129
View File
@@ -0,0 +1,129 @@
/* 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 "vpe_assert.h"
#include "common.h"
#include "reg_helper.h"
#include "vpe_desc_writer.h"
#include "vpe_command.h"
void 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 < (int64_t)size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
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;
}
/** fill the value to the command buffer. */
void vpe_desc_writer_add_plane_desc(
struct vpe_desc_writer *writer, uint64_t plane_desc_addr, bool 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 < (int64_t)size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
VPE_ASSERT(!(plane_desc_addr & 0x3));
VPE_ASSERT(!writer->plane_desc_added);
*cmd_space++ = (ADDR_LO(plane_desc_addr) | (unsigned)tmz);
*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;
}
/** fill the value to the command buffer. */
void vpe_desc_writer_add_config_desc(
struct vpe_desc_writer *writer, uint64_t config_desc_addr, bool reuse, bool 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 < (int64_t)size) {
writer->status = VPE_STATUS_BUFFER_OVERFLOW;
return;
}
cmd_space = (uint32_t *)(uintptr_t)writer->buf->cpu_va;
VPE_ASSERT(!(config_desc_addr & 0x3));
*cmd_space++ = (ADDR_LO(config_desc_addr) | ((unsigned)reuse << 1) | (unsigned)tmz);
*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++;
}
void vpe_desc_writer_complete(struct vpe_desc_writer *writer)
{
uint32_t *cmd_space;
if (writer->status != VPE_STATUS_OK)
return;
// NUM_CONFIG_DESCRIPTOR is at DW3
cmd_space = (uint32_t *)(uintptr_t)(writer->base_cpu_va + 3 * sizeof(uint32_t));
VPE_ASSERT(!(writer->num_config_desc & 0xFFFFFF00));
VPE_ASSERT(writer->num_config_desc > 0);
// NUM_CONFIG_DESCRIPTOR is 1-based
*cmd_space = (writer->num_config_desc - 1) & 0xFF;
}
+429
View File
@@ -0,0 +1,429 @@
/*
* 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 "transform.h"
//=========================================
// <num_taps> = 2
// <num_phases> = 64
// <CoefType> = Bilinear
//=========================================
static const uint16_t filter_2tap_bilinear_64p[66] = {0x1000, 0x0000, 0x0fc0, 0x0040, 0x0f80,
0x0080, 0x0f40, 0x00c0, 0x0f00, 0x0100, 0x0ec0, 0x0140, 0x0e80, 0x0180, 0x0e40, 0x01c0, 0x0e00,
0x0200, 0x0dc0, 0x0240, 0x0d80, 0x0280, 0x0d40, 0x02c0, 0x0d00, 0x0300, 0x0cc0, 0x0340, 0x0c80,
0x0380, 0x0c40, 0x03c0, 0x0c00, 0x0400, 0x0bc0, 0x0440, 0x0b80, 0x0480, 0x0b40, 0x04c0, 0x0b00,
0x0500, 0x0ac0, 0x0540, 0x0a80, 0x0580, 0x0a40, 0x05c0, 0x0a00, 0x0600, 0x09c0, 0x0640, 0x0980,
0x0680, 0x0940, 0x06c0, 0x0900, 0x0700, 0x08c0, 0x0740, 0x0880, 0x0780, 0x0840, 0x07c0, 0x0800,
0x0800};
//=========================================
// <num_taps> = 2
// <num_phases> = 64
// <scale_ratio> = 0.833333 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = s1.10
// <CoefOut> = s1.12
//=========================================
static const uint16_t filter_2tap_64p[66] = {0x1000, 0x0000, 0x1000, 0x0000, 0x0FFC, 0x0004, 0x0FF8,
0x0008, 0x0FF0, 0x0010, 0x0FE4, 0x001C, 0x0FD8, 0x0028, 0x0FC4, 0x003C, 0x0FB0, 0x0050, 0x0F98,
0x0068, 0x0F7C, 0x0084, 0x0F58, 0x00A8, 0x0F34, 0x00CC, 0x0F08, 0x00F8, 0x0ED8, 0x0128, 0x0EA4,
0x015C, 0x0E68, 0x0198, 0x0E28, 0x01D8, 0x0DE4, 0x021C, 0x0D98, 0x0268, 0x0D44, 0x02BC, 0x0CEC,
0x0314, 0x0C90, 0x0370, 0x0C2C, 0x03D4, 0x0BC4, 0x043C, 0x0B58, 0x04A8, 0x0AE8, 0x0518, 0x0A74,
0x058C, 0x09FC, 0x0604, 0x0980, 0x0680, 0x0900, 0x0700, 0x0880, 0x0780, 0x0800, 0x0800};
//=========================================
// <num_taps> = 4
// <num_phases> = 64
// <scale_ratio> = 0.83333 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_4tap_64p_upscale[132] = {0x0000, 0x1000, 0x0000, 0x0000, 0x3FDC,
0x0FFC, 0x0028, 0x0000, 0x3FB4, 0x0FF8, 0x0054, 0x0000, 0x3F94, 0x0FE8, 0x0084, 0x0000, 0x3F74,
0x0FDC, 0x00B4, 0x3FFC, 0x3F58, 0x0FC4, 0x00E8, 0x3FFC, 0x3F3C, 0x0FAC, 0x0120, 0x3FF8, 0x3F24,
0x0F90, 0x0158, 0x3FF4, 0x3F0C, 0x0F70, 0x0194, 0x3FF0, 0x3EF8, 0x0F4C, 0x01D0, 0x3FEC, 0x3EE8,
0x0F20, 0x0210, 0x3FE8, 0x3ED8, 0x0EF4, 0x0254, 0x3FE0, 0x3ECC, 0x0EC4, 0x0298, 0x3FD8, 0x3EC0,
0x0E90, 0x02DC, 0x3FD4, 0x3EB8, 0x0E58, 0x0324, 0x3FCC, 0x3EB0, 0x0E20, 0x036C, 0x3FC4, 0x3EAC,
0x0DE4, 0x03B8, 0x3FB8, 0x3EA8, 0x0DA4, 0x0404, 0x3FB0, 0x3EA4, 0x0D60, 0x0454, 0x3FA8, 0x3EA4,
0x0D1C, 0x04A4, 0x3F9C, 0x3EA4, 0x0CD8, 0x04F4, 0x3F90, 0x3EA8, 0x0C88, 0x0548, 0x3F88, 0x3EAC,
0x0C3C, 0x059C, 0x3F7C, 0x3EB0, 0x0BF0, 0x05F0, 0x3F70, 0x3EB8, 0x0BA0, 0x0644, 0x3F64, 0x3EBC,
0x0B54, 0x0698, 0x3F58, 0x3EC4, 0x0B00, 0x06F0, 0x3F4C, 0x3ECC, 0x0AAC, 0x0748, 0x3F40, 0x3ED8,
0x0A54, 0x07A0, 0x3F34, 0x3EE0, 0x0A04, 0x07F8, 0x3F24, 0x3EEC, 0x09AC, 0x0850, 0x3F18, 0x3EF8,
0x0954, 0x08A8, 0x3F0C, 0x3F00, 0x08FC, 0x0900, 0x3F04};
//=========================================
// <num_taps> = 4
// <num_phases> = 64
// <scale_ratio> = 1.16666 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_4tap_64p_116[132] = {0x01A8, 0x0CB4, 0x01A4, 0x0000, 0x017C, 0x0CB8,
0x01D0, 0x3FFC, 0x0158, 0x0CB8, 0x01F8, 0x3FF8, 0x0130, 0x0CB4, 0x0228, 0x3FF4, 0x0110, 0x0CB0,
0x0254, 0x3FEC, 0x00EC, 0x0CA8, 0x0284, 0x3FE8, 0x00CC, 0x0C9C, 0x02B4, 0x3FE4, 0x00AC, 0x0C90,
0x02E8, 0x3FDC, 0x0090, 0x0C80, 0x031C, 0x3FD4, 0x0070, 0x0C70, 0x0350, 0x3FD0, 0x0058, 0x0C5C,
0x0384, 0x3FC8, 0x003C, 0x0C48, 0x03BC, 0x3FC0, 0x0024, 0x0C2C, 0x03F4, 0x3FBC, 0x0010, 0x0C10,
0x042C, 0x3FB4, 0x3FFC, 0x0BF4, 0x0464, 0x3FAC, 0x3FE8, 0x0BD4, 0x04A0, 0x3FA4, 0x3FD8, 0x0BAC,
0x04DC, 0x3FA0, 0x3FC4, 0x0B8C, 0x0518, 0x3F98, 0x3FB4, 0x0B68, 0x0554, 0x3F90, 0x3FA8, 0x0B40,
0x0590, 0x3F88, 0x3F9C, 0x0B14, 0x05CC, 0x3F84, 0x3F90, 0x0AEC, 0x0608, 0x3F7C, 0x3F84, 0x0ABC,
0x0648, 0x3F78, 0x3F7C, 0x0A90, 0x0684, 0x3F70, 0x3F70, 0x0A60, 0x06C4, 0x3F6C, 0x3F6C, 0x0A2C,
0x0700, 0x3F68, 0x3F64, 0x09F8, 0x0740, 0x3F64, 0x3F60, 0x09C4, 0x077C, 0x3F60, 0x3F5C, 0x098C,
0x07BC, 0x3F5C, 0x3F58, 0x0958, 0x07F8, 0x3F58, 0x3F58, 0x091C, 0x0834, 0x3F58, 0x3F54, 0x08E4,
0x0870, 0x3F58, 0x3F54, 0x08AC, 0x08AC, 0x3F54};
//=========================================
// <num_taps> = 4
// <num_phases> = 64
// <scale_ratio> = 1.49999 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_4tap_64p_149[132] = {0x02B8, 0x0A90, 0x02B8, 0x0000, 0x0294, 0x0A94,
0x02DC, 0x3FFC, 0x0274, 0x0A94, 0x0300, 0x3FF8, 0x0250, 0x0A94, 0x0328, 0x3FF4, 0x0230, 0x0A90,
0x0350, 0x3FF0, 0x0214, 0x0A8C, 0x0374, 0x3FEC, 0x01F0, 0x0A88, 0x03A0, 0x3FE8, 0x01D4, 0x0A80,
0x03C8, 0x3FE4, 0x01B8, 0x0A78, 0x03F0, 0x3FE0, 0x0198, 0x0A70, 0x041C, 0x3FDC, 0x0180, 0x0A64,
0x0444, 0x3FD8, 0x0164, 0x0A54, 0x0470, 0x3FD8, 0x0148, 0x0A48, 0x049C, 0x3FD4, 0x0130, 0x0A38,
0x04C8, 0x3FD0, 0x0118, 0x0A24, 0x04F4, 0x3FD0, 0x0100, 0x0A14, 0x0520, 0x3FCC, 0x00E8, 0x0A00,
0x054C, 0x3FCC, 0x00D4, 0x09E8, 0x057C, 0x3FC8, 0x00C0, 0x09D0, 0x05A8, 0x3FC8, 0x00AC, 0x09B8,
0x05D4, 0x3FC8, 0x0098, 0x09A0, 0x0600, 0x3FC8, 0x0084, 0x0984, 0x0630, 0x3FC8, 0x0074, 0x0964,
0x065C, 0x3FCC, 0x0064, 0x0948, 0x0688, 0x3FCC, 0x0054, 0x0928, 0x06B4, 0x3FD0, 0x0044, 0x0908,
0x06E0, 0x3FD4, 0x0038, 0x08E8, 0x070C, 0x3FD4, 0x002C, 0x08C4, 0x0738, 0x3FD8, 0x001C, 0x08A4,
0x0760, 0x3FE0, 0x0014, 0x087C, 0x078C, 0x3FE4, 0x0008, 0x0858, 0x07B4, 0x3FEC, 0x0000, 0x0830,
0x07DC, 0x3FF4, 0x3FFC, 0x0804, 0x0804, 0x3FFC};
//=========================================
// <num_taps> = 4
// <num_phases> = 64
// <scale_ratio> = 1.83332 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_4tap_64p_183[132] = {0x03B0, 0x08A0, 0x03B0, 0x0000, 0x0394, 0x08A0,
0x03CC, 0x0000, 0x037C, 0x089C, 0x03E8, 0x0000, 0x0360, 0x089C, 0x0400, 0x0004, 0x0348, 0x0898,
0x041C, 0x0004, 0x032C, 0x0894, 0x0438, 0x0008, 0x0310, 0x0890, 0x0454, 0x000C, 0x02F8, 0x0888,
0x0474, 0x000C, 0x02DC, 0x0884, 0x0490, 0x0010, 0x02C4, 0x087C, 0x04AC, 0x0014, 0x02AC, 0x0874,
0x04C8, 0x0018, 0x0290, 0x086C, 0x04E4, 0x0020, 0x0278, 0x0864, 0x0500, 0x0024, 0x0264, 0x0858,
0x051C, 0x0028, 0x024C, 0x084C, 0x0538, 0x0030, 0x0234, 0x0844, 0x0554, 0x0034, 0x021C, 0x0838,
0x0570, 0x003C, 0x0208, 0x0828, 0x058C, 0x0044, 0x01F0, 0x081C, 0x05A8, 0x004C, 0x01DC, 0x080C,
0x05C4, 0x0054, 0x01C8, 0x07FC, 0x05E0, 0x005C, 0x01B4, 0x07EC, 0x05FC, 0x0064, 0x019C, 0x07DC,
0x0618, 0x0070, 0x018C, 0x07CC, 0x0630, 0x0078, 0x0178, 0x07B8, 0x064C, 0x0084, 0x0164, 0x07A8,
0x0664, 0x0090, 0x0150, 0x0794, 0x0680, 0x009C, 0x0140, 0x0780, 0x0698, 0x00A8, 0x0130, 0x076C,
0x06B0, 0x00B4, 0x0120, 0x0758, 0x06C8, 0x00C0, 0x0110, 0x0740, 0x06E0, 0x00D0, 0x0100, 0x072C,
0x06F8, 0x00DC, 0x00F0, 0x0714, 0x0710, 0x00EC};
//=========================================
// <num_taps> = 6
// <num_phases> = 64
// <scale_ratio> = 0.83333 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_6tap_64p_upscale[198] = {0x0000, 0x0000, 0x1000, 0x0000, 0x0000,
0x0000, 0x000C, 0x3FD0, 0x0FFC, 0x0034, 0x3FF4, 0x0000, 0x0018, 0x3F9C, 0x0FF8, 0x006C, 0x3FE8,
0x0000, 0x0024, 0x3F6C, 0x0FF0, 0x00A8, 0x3FD8, 0x0000, 0x002C, 0x3F44, 0x0FE4, 0x00E4, 0x3FC8,
0x0000, 0x0038, 0x3F18, 0x0FD4, 0x0124, 0x3FB8, 0x0000, 0x0040, 0x3EF0, 0x0FC0, 0x0164, 0x3FA8,
0x0004, 0x0048, 0x3EC8, 0x0FAC, 0x01A8, 0x3F98, 0x0004, 0x0050, 0x3EA8, 0x0F94, 0x01EC, 0x3F84,
0x0004, 0x0058, 0x3E84, 0x0F74, 0x0234, 0x3F74, 0x0008, 0x0060, 0x3E68, 0x0F54, 0x027C, 0x3F60,
0x0008, 0x0064, 0x3E4C, 0x0F30, 0x02C8, 0x3F4C, 0x000C, 0x006C, 0x3E30, 0x0F04, 0x0314, 0x3F3C,
0x0010, 0x0070, 0x3E18, 0x0EDC, 0x0360, 0x3F28, 0x0014, 0x0074, 0x3E04, 0x0EB0, 0x03B0, 0x3F14,
0x0014, 0x0078, 0x3DF0, 0x0E80, 0x0400, 0x3F00, 0x0018, 0x0078, 0x3DE0, 0x0E4C, 0x0454, 0x3EEC,
0x001C, 0x007C, 0x3DD0, 0x0E14, 0x04A8, 0x3ED8, 0x0020, 0x007C, 0x3DC4, 0x0DDC, 0x04FC, 0x3EC4,
0x0024, 0x007C, 0x3DBC, 0x0DA0, 0x0550, 0x3EB0, 0x0028, 0x0080, 0x3DB4, 0x0D5C, 0x05A8, 0x3E9C,
0x002C, 0x0080, 0x3DAC, 0x0D1C, 0x0600, 0x3E88, 0x0030, 0x007C, 0x3DA8, 0x0CDC, 0x0658, 0x3E74,
0x0034, 0x007C, 0x3DA4, 0x0C94, 0x06B0, 0x3E64, 0x0038, 0x007C, 0x3DA4, 0x0C48, 0x0708, 0x3E50,
0x0040, 0x0078, 0x3DA4, 0x0C00, 0x0760, 0x3E40, 0x0044, 0x0078, 0x3DA8, 0x0BB4, 0x07B8, 0x3E2C,
0x0048, 0x0074, 0x3DAC, 0x0B68, 0x0810, 0x3E1C, 0x004C, 0x0070, 0x3DB4, 0x0B18, 0x0868, 0x3E0C,
0x0050, 0x006C, 0x3DBC, 0x0AC4, 0x08C4, 0x3DFC, 0x0054, 0x0068, 0x3DC4, 0x0A74, 0x0918, 0x3DF0,
0x0058, 0x0068, 0x3DCC, 0x0A20, 0x0970, 0x3DE0, 0x005C, 0x0064, 0x3DD4, 0x09C8, 0x09C8, 0x3DD4,
0x0064};
//=========================================
// <num_taps> = 6
// <num_phases> = 64
// <scale_ratio> = 1.16666 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_6tap_64p_116[198] = {0x3F0C, 0x0240, 0x0D68, 0x0240, 0x3F0C, 0x0000,
0x3F18, 0x0210, 0x0D64, 0x0274, 0x3F00, 0x0000, 0x3F24, 0x01E0, 0x0D58, 0x02A8, 0x3EF8, 0x0004,
0x3F2C, 0x01B0, 0x0D58, 0x02DC, 0x3EEC, 0x0004, 0x3F38, 0x0180, 0x0D50, 0x0310, 0x3EE0, 0x0008,
0x3F44, 0x0154, 0x0D40, 0x0348, 0x3ED8, 0x0008, 0x3F50, 0x0128, 0x0D34, 0x037C, 0x3ECC, 0x000C,
0x3F5C, 0x00FC, 0x0D20, 0x03B4, 0x3EC4, 0x0010, 0x3F64, 0x00D4, 0x0D14, 0x03EC, 0x3EB8, 0x0010,
0x3F70, 0x00AC, 0x0CFC, 0x0424, 0x3EB0, 0x0014, 0x3F78, 0x0084, 0x0CE8, 0x0460, 0x3EA8, 0x0014,
0x3F84, 0x0060, 0x0CCC, 0x0498, 0x3EA0, 0x0018, 0x3F90, 0x003C, 0x0CB4, 0x04D0, 0x3E98, 0x0018,
0x3F98, 0x0018, 0x0C9C, 0x050C, 0x3E90, 0x0018, 0x3FA0, 0x3FFC, 0x0C78, 0x0548, 0x3E88, 0x001C,
0x3FAC, 0x3FDC, 0x0C54, 0x0584, 0x3E84, 0x001C, 0x3FB4, 0x3FBC, 0x0C3C, 0x05BC, 0x3E7C, 0x001C,
0x3FBC, 0x3FA0, 0x0C14, 0x05F8, 0x3E78, 0x0020, 0x3FC4, 0x3F84, 0x0BF0, 0x0634, 0x3E74, 0x0020,
0x3FCC, 0x3F68, 0x0BCC, 0x0670, 0x3E70, 0x0020, 0x3FD4, 0x3F50, 0x0BA4, 0x06AC, 0x3E6C, 0x0020,
0x3FDC, 0x3F38, 0x0B78, 0x06E8, 0x3E6C, 0x0020, 0x3FE0, 0x3F24, 0x0B50, 0x0724, 0x3E68, 0x0020,
0x3FE8, 0x3F0C, 0x0B24, 0x0760, 0x3E68, 0x0020, 0x3FF0, 0x3EFC, 0x0AF4, 0x0798, 0x3E68, 0x0020,
0x3FF4, 0x3EE8, 0x0AC8, 0x07D4, 0x3E68, 0x0020, 0x3FFC, 0x3ED8, 0x0A94, 0x0810, 0x3E6C, 0x001C,
0x0000, 0x3EC8, 0x0A64, 0x0848, 0x3E70, 0x001C, 0x0000, 0x3EB8, 0x0A38, 0x0880, 0x3E74, 0x001C,
0x0004, 0x3EAC, 0x0A04, 0x08BC, 0x3E78, 0x0018, 0x0008, 0x3EA4, 0x09D0, 0x08F4, 0x3E7C, 0x0014,
0x000C, 0x3E98, 0x0998, 0x092C, 0x3E84, 0x0014, 0x0010, 0x3E90, 0x0964, 0x0960, 0x3E8C, 0x0010};
//=========================================
// <num_taps> = 6
// <num_phases> = 64
// <scale_ratio> = 1.49999 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_6tap_64p_149[198] = {0x3F14, 0x0394, 0x0AB0, 0x0394, 0x3F14, 0x0000,
0x3F18, 0x036C, 0x0AB0, 0x03B8, 0x3F14, 0x0000, 0x3F18, 0x0348, 0x0AAC, 0x03E0, 0x3F14, 0x0000,
0x3F1C, 0x0320, 0x0AAC, 0x0408, 0x3F10, 0x0000, 0x3F20, 0x02FC, 0x0AA8, 0x042C, 0x3F10, 0x0000,
0x3F24, 0x02D8, 0x0AA0, 0x0454, 0x3F10, 0x0000, 0x3F28, 0x02B4, 0x0A98, 0x047C, 0x3F10, 0x0000,
0x3F28, 0x0290, 0x0A90, 0x04A4, 0x3F14, 0x0000, 0x3F30, 0x026C, 0x0A84, 0x04CC, 0x3F14, 0x0000,
0x3F34, 0x024C, 0x0A7C, 0x04F4, 0x3F14, 0x3FFC, 0x3F38, 0x0228, 0x0A70, 0x051C, 0x3F18, 0x3FFC,
0x3F3C, 0x0208, 0x0A64, 0x0544, 0x3F1C, 0x3FF8, 0x3F40, 0x01E8, 0x0A54, 0x056C, 0x3F20, 0x3FF8,
0x3F44, 0x01C8, 0x0A48, 0x0594, 0x3F24, 0x3FF4, 0x3F4C, 0x01A8, 0x0A34, 0x05BC, 0x3F28, 0x3FF4,
0x3F50, 0x0188, 0x0A28, 0x05E4, 0x3F2C, 0x3FF0, 0x3F54, 0x016C, 0x0A10, 0x060C, 0x3F34, 0x3FF0,
0x3F5C, 0x014C, 0x09FC, 0x0634, 0x3F3C, 0x3FEC, 0x3F60, 0x0130, 0x09EC, 0x065C, 0x3F40, 0x3FE8,
0x3F68, 0x0114, 0x09D0, 0x0684, 0x3F48, 0x3FE8, 0x3F6C, 0x00F8, 0x09B8, 0x06AC, 0x3F54, 0x3FE4,
0x3F74, 0x00E0, 0x09A0, 0x06D0, 0x3F5C, 0x3FE0, 0x3F78, 0x00C4, 0x098C, 0x06F8, 0x3F64, 0x3FDC,
0x3F7C, 0x00AC, 0x0970, 0x0720, 0x3F70, 0x3FD8, 0x3F84, 0x0094, 0x0954, 0x0744, 0x3F7C, 0x3FD4,
0x3F88, 0x007C, 0x093C, 0x0768, 0x3F88, 0x3FD0, 0x3F90, 0x0064, 0x091C, 0x0790, 0x3F94, 0x3FCC,
0x3F94, 0x0050, 0x08FC, 0x07B4, 0x3FA4, 0x3FC8, 0x3F98, 0x003C, 0x08E0, 0x07D8, 0x3FB0, 0x3FC4,
0x3FA0, 0x0024, 0x08C0, 0x07FC, 0x3FC0, 0x3FC0, 0x3FA4, 0x0014, 0x08A4, 0x081C, 0x3FD0, 0x3FB8,
0x3FAC, 0x0000, 0x0880, 0x0840, 0x3FE0, 0x3FB4, 0x3FB0, 0x3FF0, 0x0860, 0x0860, 0x3FF0, 0x3FB0};
//=========================================
// <num_taps> = 6
// <num_phases> = 64
// <scale_ratio> = 1.83332 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_6tap_64p_183[198] = {0x002C, 0x0420, 0x076C, 0x041C, 0x002C, 0x0000,
0x0028, 0x040C, 0x0768, 0x0430, 0x0034, 0x0000, 0x0020, 0x03F8, 0x0768, 0x0448, 0x003C, 0x3FFC,
0x0018, 0x03E4, 0x0768, 0x045C, 0x0044, 0x3FFC, 0x0014, 0x03D0, 0x0768, 0x0470, 0x004C, 0x3FF8,
0x000C, 0x03BC, 0x0764, 0x0484, 0x0058, 0x3FF8, 0x0008, 0x03A4, 0x0764, 0x049C, 0x0060, 0x3FF4,
0x0004, 0x0390, 0x0760, 0x04B0, 0x0068, 0x3FF4, 0x0000, 0x037C, 0x0760, 0x04C4, 0x0070, 0x3FF0,
0x3FFC, 0x0364, 0x075C, 0x04D8, 0x007C, 0x3FF0, 0x3FF8, 0x0350, 0x0758, 0x04F0, 0x0084, 0x3FEC,
0x3FF4, 0x033C, 0x0750, 0x0504, 0x0090, 0x3FEC, 0x3FF0, 0x0328, 0x074C, 0x0518, 0x009C, 0x3FE8,
0x3FEC, 0x0314, 0x0744, 0x052C, 0x00A8, 0x3FE8, 0x3FE8, 0x0304, 0x0740, 0x0540, 0x00B0, 0x3FE4,
0x3FE4, 0x02EC, 0x073C, 0x0554, 0x00BC, 0x3FE4, 0x3FE0, 0x02DC, 0x0734, 0x0568, 0x00C8, 0x3FE0,
0x3FE0, 0x02C4, 0x072C, 0x057C, 0x00D4, 0x3FE0, 0x3FDC, 0x02B4, 0x0724, 0x058C, 0x00E4, 0x3FDC,
0x3FDC, 0x02A0, 0x0718, 0x05A0, 0x00F0, 0x3FDC, 0x3FD8, 0x028C, 0x0714, 0x05B4, 0x00FC, 0x3FD8,
0x3FD8, 0x0278, 0x0704, 0x05C8, 0x010C, 0x3FD8, 0x3FD4, 0x0264, 0x0700, 0x05D8, 0x0118, 0x3FD8,
0x3FD4, 0x0254, 0x06F0, 0x05EC, 0x0128, 0x3FD4, 0x3FD0, 0x0244, 0x06E8, 0x05FC, 0x0134, 0x3FD4,
0x3FD0, 0x0230, 0x06DC, 0x060C, 0x0144, 0x3FD4, 0x3FD0, 0x021C, 0x06D0, 0x0620, 0x0154, 0x3FD0,
0x3FD0, 0x0208, 0x06C4, 0x0630, 0x0164, 0x3FD0, 0x3FD0, 0x01F8, 0x06B8, 0x0640, 0x0170, 0x3FD0,
0x3FCC, 0x01E8, 0x06AC, 0x0650, 0x0180, 0x3FD0, 0x3FCC, 0x01D8, 0x069C, 0x0660, 0x0190, 0x3FD0,
0x3FCC, 0x01C4, 0x068C, 0x0670, 0x01A4, 0x3FD0, 0x3FCC, 0x01B8, 0x0680, 0x067C, 0x01B4, 0x3FCC};
//=========================================
// <num_taps> = 8
// <num_phases> = 64
// <scale_ratio> = 0.83333 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_8tap_64p_upscale[264] = {0x0000, 0x0000, 0x0000, 0x1000, 0x0000,
0x0000, 0x0000, 0x0000, 0x3FFC, 0x0014, 0x3FC8, 0x1000, 0x0038, 0x3FEC, 0x0004, 0x0000, 0x3FF4,
0x0024, 0x3F94, 0x0FFC, 0x0074, 0x3FD8, 0x000C, 0x0000, 0x3FF0, 0x0038, 0x3F60, 0x0FEC, 0x00B4,
0x3FC4, 0x0014, 0x0000, 0x3FEC, 0x004C, 0x3F2C, 0x0FE4, 0x00F4, 0x3FAC, 0x0018, 0x0000, 0x3FE4,
0x005C, 0x3F00, 0x0FD4, 0x0138, 0x3F94, 0x0020, 0x0000, 0x3FE0, 0x006C, 0x3ED0, 0x0FC4, 0x017C,
0x3F7C, 0x0028, 0x0000, 0x3FDC, 0x007C, 0x3EA8, 0x0FA4, 0x01C4, 0x3F68, 0x0030, 0x0000, 0x3FD8,
0x0088, 0x3E80, 0x0F90, 0x020C, 0x3F50, 0x0038, 0x3FFC, 0x3FD4, 0x0098, 0x3E58, 0x0F70, 0x0258,
0x3F38, 0x0040, 0x3FFC, 0x3FD0, 0x00A4, 0x3E34, 0x0F54, 0x02A0, 0x3F1C, 0x004C, 0x3FFC, 0x3FD0,
0x00B0, 0x3E14, 0x0F28, 0x02F0, 0x3F04, 0x0054, 0x3FFC, 0x3FCC, 0x00BC, 0x3DF4, 0x0F08, 0x033C,
0x3EEC, 0x005C, 0x3FF8, 0x3FC8, 0x00C8, 0x3DD8, 0x0EDC, 0x038C, 0x3ED4, 0x0064, 0x3FF8, 0x3FC8,
0x00D0, 0x3DC0, 0x0EAC, 0x03E0, 0x3EBC, 0x006C, 0x3FF4, 0x3FC4, 0x00D8, 0x3DA8, 0x0E7C, 0x0430,
0x3EA4, 0x0078, 0x3FF4, 0x3FC4, 0x00E0, 0x3D94, 0x0E48, 0x0484, 0x3E8C, 0x0080, 0x3FF0, 0x3FC4,
0x00E8, 0x3D80, 0x0E10, 0x04D8, 0x3E74, 0x0088, 0x3FF0, 0x3FC4, 0x00F0, 0x3D70, 0x0DD8, 0x052C,
0x3E5C, 0x0090, 0x3FEC, 0x3FC0, 0x00F4, 0x3D60, 0x0DA0, 0x0584, 0x3E44, 0x0098, 0x3FEC, 0x3FC0,
0x00F8, 0x3D54, 0x0D68, 0x05D8, 0x3E2C, 0x00A0, 0x3FE8, 0x3FC0, 0x00FC, 0x3D48, 0x0D20, 0x0630,
0x3E18, 0x00AC, 0x3FE8, 0x3FC0, 0x0100, 0x3D40, 0x0CE0, 0x0688, 0x3E00, 0x00B4, 0x3FE4, 0x3FC4,
0x0100, 0x3D3C, 0x0C98, 0x06DC, 0x3DEC, 0x00BC, 0x3FE4, 0x3FC4, 0x0100, 0x3D38, 0x0C58, 0x0734,
0x3DD8, 0x00C0, 0x3FE0, 0x3FC4, 0x0104, 0x3D38, 0x0C0C, 0x078C, 0x3DC4, 0x00C8, 0x3FDC, 0x3FC4,
0x0100, 0x3D38, 0x0BC4, 0x07E4, 0x3DB0, 0x00D0, 0x3FDC, 0x3FC4, 0x0100, 0x3D38, 0x0B78, 0x083C,
0x3DA0, 0x00D8, 0x3FD8, 0x3FC8, 0x0100, 0x3D3C, 0x0B28, 0x0890, 0x3D90, 0x00DC, 0x3FD8, 0x3FC8,
0x00FC, 0x3D40, 0x0ADC, 0x08E8, 0x3D80, 0x00E4, 0x3FD4, 0x3FCC, 0x00FC, 0x3D48, 0x0A84, 0x093C,
0x3D74, 0x00E8, 0x3FD4, 0x3FCC, 0x00F8, 0x3D50, 0x0A38, 0x0990, 0x3D64, 0x00F0, 0x3FD0, 0x3FD0,
0x00F4, 0x3D58, 0x09E0, 0x09E4, 0x3D5C, 0x00F4, 0x3FD0};
//=========================================
// <num_taps> = 8
// <num_phases> = 64
// <scale_ratio> = 1.16666 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_8tap_64p_116[264] = {0x0080, 0x3E90, 0x0268, 0x0D14, 0x0264, 0x3E90,
0x0080, 0x0000, 0x007C, 0x3E9C, 0x0238, 0x0D14, 0x0298, 0x3E84, 0x0080, 0x0000, 0x0078, 0x3EAC,
0x0200, 0x0D10, 0x02D0, 0x3E78, 0x0084, 0x0000, 0x0078, 0x3EB8, 0x01D0, 0x0D0C, 0x0304, 0x3E6C,
0x0084, 0x0000, 0x0074, 0x3EC8, 0x01A0, 0x0D00, 0x033C, 0x3E60, 0x0088, 0x0000, 0x0070, 0x3ED4,
0x0170, 0x0D00, 0x0374, 0x3E54, 0x0088, 0x3FFC, 0x006C, 0x3EE4, 0x0140, 0x0CF8, 0x03AC, 0x3E48,
0x0088, 0x3FFC, 0x006C, 0x3EF0, 0x0114, 0x0CE8, 0x03E4, 0x3E3C, 0x008C, 0x3FFC, 0x0068, 0x3F00,
0x00E8, 0x0CD8, 0x041C, 0x3E34, 0x008C, 0x3FFC, 0x0064, 0x3F10, 0x00BC, 0x0CCC, 0x0454, 0x3E28,
0x008C, 0x3FFC, 0x0060, 0x3F1C, 0x0090, 0x0CBC, 0x0490, 0x3E20, 0x008C, 0x3FFC, 0x005C, 0x3F2C,
0x0068, 0x0CA4, 0x04CC, 0x3E18, 0x008C, 0x3FFC, 0x0058, 0x3F38, 0x0040, 0x0C94, 0x0504, 0x3E10,
0x008C, 0x3FFC, 0x0054, 0x3F48, 0x001C, 0x0C7C, 0x0540, 0x3E08, 0x0088, 0x3FFC, 0x0050, 0x3F54,
0x3FF8, 0x0C60, 0x057C, 0x3E04, 0x0088, 0x3FFC, 0x004C, 0x3F64, 0x3FD4, 0x0C44, 0x05B8, 0x3DFC,
0x0088, 0x3FFC, 0x0048, 0x3F70, 0x3FB4, 0x0C28, 0x05F4, 0x3DF8, 0x0084, 0x3FFC, 0x0044, 0x3F80,
0x3F90, 0x0C0C, 0x0630, 0x3DF4, 0x0080, 0x3FFC, 0x0040, 0x3F8C, 0x3F70, 0x0BE8, 0x066C, 0x3DF4,
0x0080, 0x3FFC, 0x003C, 0x3F9C, 0x3F50, 0x0BC8, 0x06A8, 0x3DF0, 0x007C, 0x3FFC, 0x0038, 0x3FA8,
0x3F34, 0x0BA0, 0x06E4, 0x3DF0, 0x0078, 0x0000, 0x0034, 0x3FB4, 0x3F18, 0x0B80, 0x071C, 0x3DF0,
0x0074, 0x0000, 0x0030, 0x3FC0, 0x3EFC, 0x0B5C, 0x0758, 0x3DF0, 0x0070, 0x0000, 0x002C, 0x3FCC,
0x3EE4, 0x0B34, 0x0794, 0x3DF4, 0x0068, 0x0000, 0x002C, 0x3FDC, 0x3ECC, 0x0B08, 0x07CC, 0x3DF4,
0x0064, 0x0000, 0x0028, 0x3FE4, 0x3EB4, 0x0AE0, 0x0808, 0x3DF8, 0x0060, 0x0000, 0x0024, 0x3FF0,
0x3EA0, 0x0AB0, 0x0840, 0x3E00, 0x0058, 0x0004, 0x0020, 0x3FFC, 0x3E90, 0x0A84, 0x0878, 0x3E04,
0x0050, 0x0004, 0x001C, 0x0004, 0x3E7C, 0x0A54, 0x08B0, 0x3E0C, 0x004C, 0x0008, 0x0018, 0x000C,
0x3E68, 0x0A28, 0x08E8, 0x3E18, 0x0044, 0x0008, 0x0018, 0x0018, 0x3E54, 0x09F4, 0x0920, 0x3E20,
0x003C, 0x000C, 0x0014, 0x0020, 0x3E48, 0x09C0, 0x0954, 0x3E2C, 0x0034, 0x0010, 0x0010, 0x002C,
0x3E3C, 0x098C, 0x0988, 0x3E38, 0x002C, 0x0010};
//=========================================
// <num_taps> = 8
// <num_phases> = 64
// <scale_ratio> = 1.49999 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_8tap_64p_149[264] = {0x0008, 0x3E8C, 0x03F8, 0x0AE8, 0x03F8, 0x3E8C,
0x0008, 0x0000, 0x000C, 0x3E8C, 0x03D0, 0x0AE8, 0x0420, 0x3E90, 0x0000, 0x0000, 0x000C, 0x3E8C,
0x03AC, 0x0AE8, 0x0444, 0x3E90, 0x0000, 0x0000, 0x0010, 0x3E90, 0x0384, 0x0AE0, 0x046C, 0x3E94,
0x3FFC, 0x0000, 0x0014, 0x3E90, 0x035C, 0x0ADC, 0x0494, 0x3E94, 0x3FF8, 0x0004, 0x0018, 0x3E90,
0x0334, 0x0AD8, 0x04BC, 0x3E98, 0x3FF4, 0x0004, 0x001C, 0x3E94, 0x0310, 0x0AD0, 0x04E4, 0x3E9C,
0x3FEC, 0x0004, 0x0020, 0x3E98, 0x02E8, 0x0AC4, 0x050C, 0x3EA0, 0x3FE8, 0x0008, 0x0020, 0x3E98,
0x02C4, 0x0AC0, 0x0534, 0x3EA4, 0x3FE4, 0x0008, 0x0024, 0x3E9C, 0x02A0, 0x0AB4, 0x055C, 0x3EAC,
0x3FDC, 0x0008, 0x0024, 0x3EA0, 0x027C, 0x0AA8, 0x0584, 0x3EB0, 0x3FD8, 0x000C, 0x0028, 0x3EA4,
0x0258, 0x0A9C, 0x05AC, 0x3EB8, 0x3FD0, 0x000C, 0x0028, 0x3EA8, 0x0234, 0x0A90, 0x05D4, 0x3EC0,
0x3FC8, 0x0010, 0x002C, 0x3EAC, 0x0210, 0x0A80, 0x05FC, 0x3EC8, 0x3FC4, 0x0010, 0x002C, 0x3EB4,
0x01F0, 0x0A70, 0x0624, 0x3ED0, 0x3FBC, 0x0010, 0x002C, 0x3EB8, 0x01CC, 0x0A60, 0x064C, 0x3EDC,
0x3FB4, 0x0014, 0x0030, 0x3EBC, 0x01A8, 0x0A50, 0x0674, 0x3EE4, 0x3FB0, 0x0014, 0x0030, 0x3EC4,
0x0188, 0x0A38, 0x069C, 0x3EF0, 0x3FA8, 0x0018, 0x0030, 0x3ECC, 0x0168, 0x0A28, 0x06C0, 0x3EFC,
0x3FA0, 0x0018, 0x0030, 0x3ED0, 0x0148, 0x0A14, 0x06E8, 0x3F08, 0x3F98, 0x001C, 0x0030, 0x3ED8,
0x012C, 0x0A00, 0x070C, 0x3F14, 0x3F90, 0x001C, 0x0034, 0x3EE0, 0x0108, 0x09E4, 0x0734, 0x3F24,
0x3F8C, 0x001C, 0x0034, 0x3EE4, 0x00EC, 0x09CC, 0x0758, 0x3F34, 0x3F84, 0x0020, 0x0034, 0x3EEC,
0x00D0, 0x09B8, 0x077C, 0x3F40, 0x3F7C, 0x0020, 0x0034, 0x3EF4, 0x00B4, 0x0998, 0x07A4, 0x3F50,
0x3F74, 0x0024, 0x0030, 0x3EFC, 0x0098, 0x0980, 0x07C8, 0x3F64, 0x3F6C, 0x0024, 0x0030, 0x3F04,
0x0080, 0x0968, 0x07E8, 0x3F74, 0x3F64, 0x0024, 0x0030, 0x3F0C, 0x0060, 0x094C, 0x080C, 0x3F88,
0x3F5C, 0x0028, 0x0030, 0x3F14, 0x0048, 0x0930, 0x0830, 0x3F98, 0x3F54, 0x0028, 0x0030, 0x3F1C,
0x0030, 0x0914, 0x0850, 0x3FAC, 0x3F4C, 0x0028, 0x0030, 0x3F24, 0x0018, 0x08F0, 0x0874, 0x3FC0,
0x3F44, 0x002C, 0x002C, 0x3F2C, 0x0000, 0x08D4, 0x0894, 0x3FD8, 0x3F3C, 0x002C, 0x002C, 0x3F34,
0x3FEC, 0x08B4, 0x08B4, 0x3FEC, 0x3F34, 0x002C};
//=========================================
// <num_taps> = 8
// <num_phases> = 64
// <scale_ratio> = 1.83332 (input/output)
// <sharpness> = 0
// <CoefType> = ModifiedLanczos
// <CoefQuant> = 1.10
// <CoefOut> = 1.12
//=========================================
static const uint16_t filter_8tap_64p_183[264] = {0x3F88, 0x0048, 0x047C, 0x0768, 0x047C, 0x0048,
0x3F88, 0x0000, 0x3F88, 0x003C, 0x0468, 0x076C, 0x0490, 0x0054, 0x3F84, 0x0000, 0x3F8C, 0x0034,
0x0454, 0x0768, 0x04A4, 0x005C, 0x3F84, 0x0000, 0x3F8C, 0x0028, 0x0444, 0x076C, 0x04B4, 0x0068,
0x3F80, 0x0000, 0x3F90, 0x0020, 0x042C, 0x0768, 0x04C8, 0x0074, 0x3F80, 0x0000, 0x3F90, 0x0018,
0x041C, 0x0764, 0x04DC, 0x0080, 0x3F7C, 0x0000, 0x3F94, 0x0010, 0x0408, 0x075C, 0x04F0, 0x008C,
0x3F7C, 0x0000, 0x3F94, 0x0004, 0x03F8, 0x0760, 0x0500, 0x0098, 0x3F7C, 0x3FFC, 0x3F98, 0x0000,
0x03E0, 0x075C, 0x0514, 0x00A4, 0x3F78, 0x3FFC, 0x3F9C, 0x3FF8, 0x03CC, 0x0754, 0x0528, 0x00B0,
0x3F78, 0x3FFC, 0x3F9C, 0x3FF0, 0x03B8, 0x0754, 0x0538, 0x00BC, 0x3F78, 0x3FFC, 0x3FA0, 0x3FE8,
0x03A4, 0x0750, 0x054C, 0x00CC, 0x3F74, 0x3FF8, 0x3FA4, 0x3FE0, 0x0390, 0x074C, 0x055C, 0x00D8,
0x3F74, 0x3FF8, 0x3FA4, 0x3FDC, 0x037C, 0x0744, 0x0570, 0x00E4, 0x3F74, 0x3FF8, 0x3FA8, 0x3FD4,
0x0368, 0x0740, 0x0580, 0x00F4, 0x3F74, 0x3FF4, 0x3FA8, 0x3FCC, 0x0354, 0x073C, 0x0590, 0x0104,
0x3F74, 0x3FF4, 0x3FAC, 0x3FC8, 0x0340, 0x0730, 0x05A4, 0x0110, 0x3F74, 0x3FF4, 0x3FB0, 0x3FC0,
0x0330, 0x0728, 0x05B4, 0x0120, 0x3F74, 0x3FF0, 0x3FB0, 0x3FBC, 0x031C, 0x0724, 0x05C4, 0x0130,
0x3F70, 0x3FF0, 0x3FB4, 0x3FB4, 0x0308, 0x0720, 0x05D4, 0x013C, 0x3F70, 0x3FF0, 0x3FB8, 0x3FB0,
0x02F4, 0x0714, 0x05E4, 0x014C, 0x3F74, 0x3FEC, 0x3FB8, 0x3FAC, 0x02E0, 0x0708, 0x05F8, 0x015C,
0x3F74, 0x3FEC, 0x3FBC, 0x3FA8, 0x02CC, 0x0704, 0x0604, 0x016C, 0x3F74, 0x3FE8, 0x3FC0, 0x3FA0,
0x02BC, 0x06F8, 0x0614, 0x017C, 0x3F74, 0x3FE8, 0x3FC0, 0x3F9C, 0x02A8, 0x06F4, 0x0624, 0x018C,
0x3F74, 0x3FE4, 0x3FC4, 0x3F98, 0x0294, 0x06E8, 0x0634, 0x019C, 0x3F74, 0x3FE4, 0x3FC8, 0x3F94,
0x0284, 0x06D8, 0x0644, 0x01AC, 0x3F78, 0x3FE0, 0x3FC8, 0x3F90, 0x0270, 0x06D4, 0x0650, 0x01BC,
0x3F78, 0x3FE0, 0x3FCC, 0x3F8C, 0x025C, 0x06C8, 0x0660, 0x01D0, 0x3F78, 0x3FDC, 0x3FCC, 0x3F8C,
0x024C, 0x06B8, 0x066C, 0x01E0, 0x3F7C, 0x3FDC, 0x3FD0, 0x3F88, 0x0238, 0x06B0, 0x067C, 0x01F0,
0x3F7C, 0x3FD8, 0x3FD4, 0x3F84, 0x0228, 0x069C, 0x0688, 0x0204, 0x3F80, 0x3FD8, 0x3FD4, 0x3F84,
0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4};
const uint16_t *vpe_get_filter_4tap_64p(struct fixed31_32 ratio)
{
if (ratio.value < vpe_fixpt_one.value)
return filter_4tap_64p_upscale;
else if (ratio.value < vpe_fixpt_from_fraction(4, 3).value)
return filter_4tap_64p_116;
else if (ratio.value < vpe_fixpt_from_fraction(5, 3).value)
return filter_4tap_64p_149;
else
return filter_4tap_64p_183;
}
const uint16_t *vpe_get_filter_6tap_64p(struct fixed31_32 ratio)
{
if (ratio.value < vpe_fixpt_one.value)
return filter_6tap_64p_upscale;
else if (ratio.value < vpe_fixpt_from_fraction(4, 3).value)
return filter_6tap_64p_116;
else if (ratio.value < vpe_fixpt_from_fraction(5, 3).value)
return filter_6tap_64p_149;
else
return filter_6tap_64p_183;
}
const uint16_t *vpe_get_filter_8tap_64p(struct fixed31_32 ratio)
{
if (ratio.value < vpe_fixpt_one.value)
return filter_8tap_64p_upscale;
else if (ratio.value < vpe_fixpt_from_fraction(4, 3).value)
return filter_8tap_64p_116;
else if (ratio.value < vpe_fixpt_from_fraction(5, 3).value)
return filter_8tap_64p_149;
else
return filter_8tap_64p_183;
}
const uint16_t *vpe_get_filter_2tap_64p(void)
{
return filter_2tap_64p;
}
const uint16_t *vpe_get_2tap_bilinear_64p(void)
{
return filter_2tap_bilinear_64p;
}
@@ -0,0 +1,217 @@
/* Copyright 2023 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_visual_confirm.h"
#include "common.h"
#include "vpe_priv.h"
#include "color_bg.h"
#include "background.h"
#include "resource.h"
static uint16_t get_visual_confirm_segs_count(uint32_t max_seg_width, uint32_t target_rect_width)
{
// Unlike max_gaps logic in vpe10_calculate_segments, we are pure BG seg, no need to worry
// stream splitted among one of the segment. so no need to "+1", just round up the calculated
// number of segments.
uint16_t seg_cnt = (uint16_t)(max((target_rect_width + max_seg_width - 1) / max_seg_width, 1));
return seg_cnt;
}
static uint16_t vpe_get_visual_confirm_total_seg_count(
struct vpe_priv *vpe_priv, uint32_t max_seg_width, const struct vpe_build_param *params)
{
uint16_t segs_num = 0;
uint16_t total_visual_confirm_segs = 0;
uint16_t stream_idx;
struct stream_ctx *stream_ctx;
if (vpe_priv->init.debug.visual_confirm_params.input_format) {
for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
total_visual_confirm_segs += get_visual_confirm_segs_count(
max_seg_width, stream_ctx->stream.scaling_info.dst_rect.width);
}
}
if (vpe_priv->init.debug.visual_confirm_params.output_format) {
total_visual_confirm_segs +=
get_visual_confirm_segs_count(max_seg_width, params->target_rect.width);
}
return total_visual_confirm_segs;
}
struct vpe_color vpe_get_visual_confirm_color(enum vpe_surface_pixel_format format,
struct vpe_color_space cs, enum color_space output_cs, struct transfer_func *output_tf,
bool enable_3dlut)
{
struct vpe_color visual_confirm_color;
visual_confirm_color.is_ycbcr = false;
visual_confirm_color.rgba.a = 0.0;
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 0.0;
visual_confirm_color.rgba.b = 0.0;
switch (format) {
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
// YUV420 8bit: Green
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 1.0;
visual_confirm_color.rgba.b = 0.0;
break;
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
// YUV420 10bit: yellow (SDR)
switch (cs.tf) {
case VPE_TF_G22:
case VPE_TF_G24:
visual_confirm_color.rgba.r = 1.0;
visual_confirm_color.rgba.g = 1.0;
visual_confirm_color.rgba.b = 0.0;
break;
// YUV420 10bit: White (HDR)
case VPE_TF_PQ:
case VPE_TF_HLG:
if (enable_3dlut) {
visual_confirm_color.rgba.r = 1.0;
visual_confirm_color.rgba.g = 1.0;
visual_confirm_color.rgba.b = 1.0;
} else {
visual_confirm_color.rgba.r = 1.0;
visual_confirm_color.rgba.g = 0.0;
visual_confirm_color.rgba.b = 0.0;
}
break;
default:
break;
}
break;
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_XRGB8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
// RGBA and RGBX 8 bit and variants : Pink
visual_confirm_color.rgba.r = 1.0;
visual_confirm_color.rgba.g = 0.5;
visual_confirm_color.rgba.b = 1.0;
break;
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:
// RGBA 10 bit and variants : Cyan
visual_confirm_color.rgba.r = 0.0;
visual_confirm_color.rgba.g = 1.0;
visual_confirm_color.rgba.b = 1.0;
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:
// FP16 and variants: orange
visual_confirm_color.rgba.r = 1.0;
visual_confirm_color.rgba.g = 0.21972f;
visual_confirm_color.rgba.b = 0.0;
break;
default:
break;
}
// Due to there will be regamma (ogam), need convert the bg color for visual confirm
vpe_bg_color_convert(output_cs, output_tf, &visual_confirm_color);
// Experimental: To make FP16 Linear color looks more visually ok
if (output_tf->tf == TRANSFER_FUNC_LINEAR_0_125) {
visual_confirm_color.rgba.r /= 125;
visual_confirm_color.rgba.g /= 125;
visual_confirm_color.rgba.b /= 125;
}
return visual_confirm_color;
}
enum vpe_status vpe_create_visual_confirm_segs(
struct vpe_priv *vpe_priv, const struct vpe_build_param *params, uint32_t max_seg_width)
{
uint16_t stream_idx;
struct stream_ctx *stream_ctx;
struct vpe_rect visual_confirm_rect;
struct vpe_rect *visual_confirm_gaps;
struct vpe_rect *current_gap;
uint16_t total_seg_cnt =
vpe_get_visual_confirm_total_seg_count(vpe_priv, max_seg_width, params);
uint16_t seg_cnt = 0;
if (!total_seg_cnt)
return VPE_STATUS_OK;
visual_confirm_gaps = vpe_zalloc(sizeof(struct vpe_rect) * total_seg_cnt);
if (!visual_confirm_gaps)
return VPE_STATUS_NO_MEMORY;
current_gap = visual_confirm_gaps;
// Do visual confirm bg generation for intput format
if (vpe_priv->init.debug.visual_confirm_params.input_format &&
params->target_rect.height > 2 * VISUAL_CONFIRM_HEIGHT) {
for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
visual_confirm_rect = stream_ctx->stream.scaling_info.dst_rect;
visual_confirm_rect.y += 0;
visual_confirm_rect.height = VISUAL_CONFIRM_HEIGHT;
seg_cnt = get_visual_confirm_segs_count(
max_seg_width, stream_ctx->stream.scaling_info.dst_rect.width);
vpe_full_bg_gaps(current_gap, &visual_confirm_rect, seg_cnt);
vpe_priv->resource.create_bg_segments(
vpe_priv, current_gap, seg_cnt, VPE_CMD_OPS_BG_VSCF_INPUT);
current_gap += seg_cnt;
}
}
// Do visual confirm bg generation for output format
if (vpe_priv->init.debug.visual_confirm_params.output_format &&
params->target_rect.height > VISUAL_CONFIRM_HEIGHT) {
visual_confirm_rect = params->target_rect;
visual_confirm_rect.y += VISUAL_CONFIRM_HEIGHT;
visual_confirm_rect.height = VISUAL_CONFIRM_HEIGHT;
seg_cnt = get_visual_confirm_segs_count(max_seg_width, params->target_rect.width);
vpe_full_bg_gaps(current_gap, &visual_confirm_rect, seg_cnt);
vpe_priv->resource.create_bg_segments(
vpe_priv, current_gap, seg_cnt, VPE_CMD_OPS_BG_VSCF_OUTPUT);
}
if (visual_confirm_gaps != NULL) {
vpe_free(visual_confirm_gaps);
visual_confirm_gaps = NULL;
current_gap = NULL;
}
return VPE_STATUS_OK;
}
+658
View File
@@ -0,0 +1,658 @@
/* 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 "vpelib.h"
#include "vpe_priv.h"
#include "common.h"
#include "color_bg.h"
#include "color_gamma.h"
#include "cmd_builder.h"
#include "resource.h"
#include "color.h"
#include "vpec.h"
#include "vpe_desc_writer.h"
#include "dpp.h"
#include "mpc.h"
#include "opp.h"
static void override_debug_option(
struct vpe_debug_options *debug, const struct vpe_debug_options *user_debug)
{
if (user_debug->flags.bg_bit_depth)
debug->bg_bit_depth = user_debug->bg_bit_depth;
if (user_debug->flags.cm_in_bypass)
debug->cm_in_bypass = user_debug->cm_in_bypass;
if (user_debug->flags.vpcnvc_bypass)
debug->vpcnvc_bypass = user_debug->vpcnvc_bypass;
if (user_debug->flags.mpc_bypass)
debug->mpc_bypass = user_debug->mpc_bypass;
if (user_debug->flags.disable_reuse_bit)
debug->disable_reuse_bit = user_debug->disable_reuse_bit;
if (user_debug->flags.identity_3dlut)
debug->identity_3dlut = user_debug->identity_3dlut;
if (user_debug->flags.sce_3dlut)
debug->sce_3dlut = user_debug->sce_3dlut;
if (user_debug->enable_mem_low_power.flags.cm)
debug->enable_mem_low_power.bits.cm = user_debug->enable_mem_low_power.bits.cm;
if (user_debug->enable_mem_low_power.flags.dscl)
debug->enable_mem_low_power.bits.dscl = user_debug->enable_mem_low_power.bits.dscl;
if (user_debug->enable_mem_low_power.flags.mpc)
debug->enable_mem_low_power.bits.mpc = user_debug->enable_mem_low_power.bits.mpc;
if (user_debug->flags.bg_color_fill_only)
debug->bg_color_fill_only = user_debug->bg_color_fill_only;
if (user_debug->flags.assert_when_not_support)
debug->assert_when_not_support = user_debug->assert_when_not_support;
if (user_debug->flags.bypass_ogam)
debug->bypass_ogam = user_debug->bypass_ogam;
if (user_debug->flags.bypass_gamcor)
debug->bypass_gamcor = user_debug->bypass_gamcor;
if (user_debug->flags.bypass_dpp_gamut_remap)
debug->bypass_dpp_gamut_remap = user_debug->bypass_dpp_gamut_remap;
if (user_debug->flags.bypass_post_csc)
debug->bypass_post_csc = user_debug->bypass_post_csc;
if (user_debug->flags.force_tf_calculation)
debug->force_tf_calculation = user_debug->force_tf_calculation;
if (user_debug->flags.clamping_setting) {
debug->clamping_setting = user_debug->clamping_setting;
debug->clamping_params = user_debug->clamping_params;
}
if (user_debug->flags.expansion_mode)
debug->expansion_mode = user_debug->expansion_mode;
if (user_debug->flags.bypass_per_pixel_alpha)
debug->bypass_per_pixel_alpha = user_debug->bypass_per_pixel_alpha;
if (user_debug->flags.opp_pipe_crc_ctrl)
debug->opp_pipe_crc_ctrl = user_debug->opp_pipe_crc_ctrl;
if (user_debug->flags.dpp_crc_ctrl)
debug->dpp_crc_ctrl = user_debug->dpp_crc_ctrl;
if (user_debug->flags.mpc_crc_ctrl)
debug->mpc_crc_ctrl = user_debug->mpc_crc_ctrl;
if (user_debug->flags.visual_confirm)
debug->visual_confirm_params = user_debug->visual_confirm_params;
}
struct vpe *vpe_create(const struct vpe_init_data *params)
{
struct vpe_priv *vpe_priv;
enum vpe_status status;
if (!params || (params->funcs.zalloc == NULL) || (params->funcs.free == NULL) ||
(params->funcs.log == NULL))
return NULL;
vpe_priv =
(struct vpe_priv *)params->funcs.zalloc(params->funcs.mem_ctx, sizeof(struct vpe_priv));
if (!vpe_priv)
return NULL;
vpe_priv->init = *params;
vpe_priv->pub.level =
vpe_resource_parse_ip_version(params->ver_major, params->ver_minor, params->ver_rev);
vpe_priv->pub.version = (VPELIB_API_VERSION_MAJOR << VPELIB_API_VERSION_MAJOR_SHIFT) |
(VPELIB_API_VERSION_MINOR << VPELIB_API_VERSION_MINOR_SHIFT);
status = vpe_construct_resource(vpe_priv, vpe_priv->pub.level, &vpe_priv->resource);
if (status != VPE_STATUS_OK) {
vpe_free(vpe_priv);
return NULL;
}
override_debug_option(&vpe_priv->init.debug, &params->debug);
vpe_color_setup_x_points_distribution();
vpe_color_setup_x_points_distribution_degamma();
vpe_priv->ops_support = false;
vpe_priv->scale_yuv_matrix = true;
return &vpe_priv->pub;
}
void vpe_destroy(struct vpe **vpe)
{
struct vpe_priv *vpe_priv;
if (!vpe || ((*vpe) == NULL))
return;
vpe_priv = container_of(*vpe, struct vpe_priv, pub);
vpe_destroy_resource(vpe_priv, &vpe_priv->resource);
vpe_free_output_ctx(vpe_priv);
vpe_free_stream_ctx(vpe_priv);
if (vpe_priv->dummy_input_param)
vpe_free(vpe_priv->dummy_input_param);
if (vpe_priv->dummy_stream)
vpe_free(vpe_priv->dummy_stream);
vpe_free(vpe_priv);
*vpe = NULL;
}
/*****************************************************************************************
* handle_zero_input
* handle any zero input stream but background output only
* struct vpe* vpe
* [input] vpe context
* const struct vpe_build_param* org_param
* [input] original parameter from caller
* struct vpe_build_param* dummy_input_param
* [output] caller provided param struct for filling with dummy input
* struct struct vpe_stream* dummy_stream
* [output] caller provided vpe_stream struct for use in dummy_input_param->streams
*****************************************************************************************/
static enum vpe_status handle_zero_input(struct vpe *vpe, const struct vpe_build_param *in_param,
const struct vpe_build_param **out_param)
{
struct vpe_priv *vpe_priv;
struct vpe_surface_info *surface_info;
struct vpe_scaling_info *scaling_info;
struct vpe_scaling_filter_coeffs *polyphaseCoeffs;
struct vpe_stream *stream;
vpe_priv = container_of(vpe, struct vpe_priv, pub);
if (!in_param || !out_param)
return VPE_STATUS_ERROR;
*out_param = NULL;
if (in_param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) {
// if output surface is too small, don't use it as dummy input
// request 2x2 instead of 1x1 for bpc safety
// as we are to treat output as input for RGB 1x1, need 4bytes at least
// but if output is YUV, bpc will be smaller and need larger dimension
if (in_param->dst_surface.plane_size.surface_size.width < VPE_MIN_VIEWPORT_SIZE ||
in_param->dst_surface.plane_size.surface_size.height < VPE_MIN_VIEWPORT_SIZE ||
in_param->dst_surface.plane_size.surface_pitch < 256 / 4 || // 256bytes, 4bpp
in_param->target_rect.width < VPE_MIN_VIEWPORT_SIZE ||
in_param->target_rect.height < VPE_MIN_VIEWPORT_SIZE) {
return VPE_STATUS_ERROR;
}
if (!vpe_priv->dummy_input_param) {
vpe_priv->dummy_input_param = vpe_zalloc(sizeof(struct vpe_build_param));
if (!vpe_priv->dummy_input_param)
return VPE_STATUS_NO_MEMORY;
}
if (!vpe_priv->dummy_stream) {
vpe_priv->dummy_stream = vpe_zalloc(sizeof(struct vpe_stream));
if (!vpe_priv->dummy_stream)
return VPE_STATUS_NO_MEMORY;
}
*vpe_priv->dummy_input_param = *in_param;
vpe_priv->dummy_input_param->num_streams = 1;
vpe_priv->dummy_input_param->streams = vpe_priv->dummy_stream;
// set output surface as our dummy input
stream = vpe_priv->dummy_stream;
surface_info = &stream->surface_info;
scaling_info = &stream->scaling_info;
polyphaseCoeffs = &stream->polyphase_scaling_coeffs;
surface_info->address.type = VPE_PLN_ADDR_TYPE_GRAPHICS;
surface_info->address.tmz_surface = in_param->dst_surface.address.tmz_surface;
surface_info->address.grph.addr.quad_part =
in_param->dst_surface.address.grph.addr.quad_part;
surface_info->swizzle = VPE_SW_LINEAR; // treat it as linear for simple
surface_info->plane_size.surface_size.x = 0;
surface_info->plane_size.surface_size.y = 0;
surface_info->plane_size.surface_size.width = VPE_MIN_VIEWPORT_SIZE; // min width in pixels
surface_info->plane_size.surface_size.height =
VPE_MIN_VIEWPORT_SIZE; // min height in pixels
surface_info->plane_size.surface_pitch = 256 / 4; // pitch in pixels
surface_info->plane_size.surface_aligned_height = VPE_MIN_VIEWPORT_SIZE;
surface_info->dcc.enable = false;
surface_info->format = VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888;
surface_info->cs.encoding = VPE_PIXEL_ENCODING_RGB;
surface_info->cs.range = VPE_COLOR_RANGE_FULL;
surface_info->cs.tf = VPE_TF_G22;
surface_info->cs.cositing = VPE_CHROMA_COSITING_NONE;
surface_info->cs.primaries = VPE_PRIMARIES_BT709;
scaling_info->src_rect.x = 0;
scaling_info->src_rect.y = 0;
scaling_info->src_rect.width = VPE_MIN_VIEWPORT_SIZE;
scaling_info->src_rect.height = VPE_MIN_VIEWPORT_SIZE;
scaling_info->dst_rect.x = in_param->target_rect.x;
scaling_info->dst_rect.y = in_param->target_rect.y;
scaling_info->dst_rect.width = VPE_MIN_VIEWPORT_SIZE;
scaling_info->dst_rect.height = VPE_MIN_VIEWPORT_SIZE;
scaling_info->taps.v_taps = 4;
scaling_info->taps.h_taps = 4;
scaling_info->taps.v_taps_c = 2;
scaling_info->taps.h_taps_c = 2;
polyphaseCoeffs->taps = scaling_info->taps;
polyphaseCoeffs->nb_phases = 64;
stream->blend_info.blending = true;
stream->blend_info.pre_multiplied_alpha = false;
stream->blend_info.global_alpha = true; // hardcoded upon DAL request
stream->blend_info.global_alpha_value = 0; // transparent as we are dummy input
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->flags.hdr_metadata = 0;
stream->use_external_scaling_coeffs = false;
*out_param = vpe_priv->dummy_input_param;
} else {
*out_param = in_param;
}
return VPE_STATUS_OK;
}
enum vpe_status vpe_check_support(
struct vpe *vpe, const struct vpe_build_param *param, struct vpe_bufs_req *req)
{
struct vpe_priv *vpe_priv;
struct vpec *vpec;
struct dpp *dpp;
enum vpe_status status;
struct stream_ctx *stream_ctx;
struct output_ctx *output_ctx = NULL;
uint32_t i;
bool input_h_mirror, output_h_mirror;
vpe_priv = container_of(vpe, struct vpe_priv, pub);
vpec = &vpe_priv->resource.vpec;
dpp = vpe_priv->resource.dpp[0];
status = handle_zero_input(vpe, param, &param);
if (status != VPE_STATUS_OK)
status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED;
if (!vpe_priv->stream_ctx || vpe_priv->num_streams != param->num_streams) {
if (vpe_priv->stream_ctx)
vpe_free_stream_ctx(vpe_priv);
vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, param->num_streams);
}
if (!vpe_priv->stream_ctx)
status = VPE_STATUS_NO_MEMORY;
// VPElib needs to cache whether or not the 3DLUT has been updated
// This is to deal with case when 3DLUT has been updated but VPE rejects the job.
// Need a sticky bit to tell vpe to program the 3dlut on next jobs submission even
// if 3dlut has not changed
for (i = 0; i < param->num_streams; i++) {
vpe_cache_tone_map_params(&vpe_priv->stream_ctx[i], param);
}
if (status == VPE_STATUS_OK) {
// output checking - check per asic support
status = vpe_check_output_support(vpe, param);
if (status != VPE_STATUS_OK) {
vpe_log("fail output support check. status %d\n", (int)status);
}
}
if (status == VPE_STATUS_OK) {
// input checking - check per asic support
for (i = 0; i < param->num_streams; i++) {
status = vpe_check_input_support(vpe, &param->streams[i]);
if (status != VPE_STATUS_OK) {
vpe_log("fail input support check. status %d\n", (int)status);
break;
}
}
}
if (status == VPE_STATUS_OK) {
// input checking - check tone map support
for (i = 0; i < param->num_streams; i++) {
status = vpe_check_tone_map_support(vpe, &param->streams[i], param);
if (status != VPE_STATUS_OK) {
vpe_log("fail input support check. status %d\n", (int)status);
break;
}
}
}
if (status == VPE_STATUS_OK) {
// output resource preparation for further checking (cache the result)
output_ctx = &vpe_priv->output_ctx;
output_ctx->surface = param->dst_surface;
output_ctx->bg_color = param->bg_color;
output_ctx->target_rect = param->target_rect;
output_ctx->alpha_mode = param->alpha_mode;
output_ctx->flags.hdr_metadata = param->flags.hdr_metadata;
output_ctx->hdr_metadata = param->hdr_metadata;
vpe_priv->num_vpe_cmds = 0;
output_ctx->clamping_params = vpe_priv->init.debug.clamping_params;
vpe_priv->num_streams = param->num_streams;
}
if (status == VPE_STATUS_OK) {
// blending support check
vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror);
for (i = 0; i < param->num_streams; i++) {
stream_ctx = &vpe_priv->stream_ctx[i];
stream_ctx->stream_idx = (int32_t)i;
stream_ctx->per_pixel_alpha =
vpe_has_per_pixel_alpha(param->streams[i].surface_info.format);
if (vpe_priv->init.debug.bypass_per_pixel_alpha) {
stream_ctx->per_pixel_alpha = false;
}
if (param->streams[i].horizontal_mirror && !input_h_mirror && output_h_mirror)
stream_ctx->flip_horizonal_output = true;
else
stream_ctx->flip_horizonal_output = false;
memcpy(&stream_ctx->stream, &param->streams[i], sizeof(struct vpe_stream));
/* if top-bottom blending is not supported,
* the 1st stream still can support blending with background,
* however, the 2nd stream and onward can't enable blending.
*/
if (i && param->streams[i].blend_info.blending &&
!vpe_priv->pub.caps->color_caps.mpc.top_bottom_blending) {
status = VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED;
break;
}
}
}
if (status == VPE_STATUS_OK) {
status = vpe_priv->resource.calculate_segments(vpe_priv, param);
if (status != VPE_STATUS_OK)
vpe_log("failed in calculate segments %d\n", (int)status);
}
if (status == VPE_STATUS_OK) {
// if the bg_color support is false, there is a flag to verify if the bg_color falls in the
// output gamut
if (!vpe_priv->pub.caps->bg_color_check_support) {
status = vpe_bg_color_outside_cs_gamut(&output_ctx->surface.cs, &output_ctx->bg_color);
if (status != VPE_STATUS_OK) {
vpe_log(
"failed in checking the background color versus the output color space %d\n",
(int)status);
}
}
}
if (status == VPE_STATUS_OK) {
// Calculate the buffer needed (worst case)
vpe_priv->resource.get_bufs_req(vpe_priv, &vpe_priv->bufs_required);
*req = vpe_priv->bufs_required;
vpe_priv->ops_support = true;
}
if (vpe_priv->init.debug.assert_when_not_support)
VPE_ASSERT(status == VPE_STATUS_OK);
return status;
}
enum vpe_status vpe_build_noops(struct vpe *vpe, uint32_t num_dword, uint32_t **ppcmd_space)
{
struct vpe_priv *vpe_priv;
struct cmd_builder *builder;
enum vpe_status status;
if (!vpe || !ppcmd_space || ((*ppcmd_space) == NULL))
return VPE_STATUS_ERROR;
vpe_priv = container_of(vpe, struct vpe_priv, pub);
builder = &vpe_priv->resource.cmd_builder;
status = builder->build_noops(vpe_priv, ppcmd_space, num_dword);
return status;
}
static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
uint32_t i;
struct output_ctx *output_ctx;
if (vpe_priv->num_streams != param->num_streams)
return false;
for (i = 0; i < param->num_streams; i++) {
struct vpe_stream stream = param->streams[i];
vpe_clip_stream(
&stream.scaling_info.src_rect, &stream.scaling_info.dst_rect, &param->target_rect);
if (memcmp(&vpe_priv->stream_ctx[i].stream, &stream, sizeof(struct vpe_stream)))
return false;
}
output_ctx = &vpe_priv->output_ctx;
if (output_ctx->alpha_mode != param->alpha_mode)
return false;
if (memcmp(&output_ctx->bg_color, &param->bg_color, sizeof(struct vpe_color)))
return false;
if (memcmp(&output_ctx->target_rect, &param->target_rect, sizeof(struct vpe_rect)))
return false;
if (memcmp(&output_ctx->surface, &param->dst_surface, sizeof(struct vpe_surface_info)))
return false;
return true;
}
static bool validate_color_pipeline(struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
{
uint32_t stream_idx;
struct stream_ctx *stream_ctx;
struct output_ctx *output_ctx;
output_ctx = &vpe_priv->output_ctx;
/* For BG color, we need to make sure degamm / regamm is not bypass,
* as we want to have input in the range of 0-1 in mpc,
* since mpc only allows 0-1 range for BG color
*/
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
if (output_ctx->output_tf->type == TF_TYPE_BYPASS &&
stream_ctx->input_tf->type == TF_TYPE_BYPASS)
return false;
}
return true;
}
enum vpe_status vpe_build_commands(
struct vpe *vpe, const struct vpe_build_param *param, struct vpe_build_bufs *bufs)
{
struct vpe_priv *vpe_priv;
struct cmd_builder *builder;
enum vpe_status status = VPE_STATUS_OK;
uint32_t cmd_idx, i, j;
struct vpe_build_bufs curr_bufs;
int64_t cmd_buf_size;
int64_t emb_buf_size;
uint64_t cmd_buf_gpu_a, cmd_buf_cpu_a;
uint64_t emb_buf_gpu_a, emb_buf_cpu_a;
if (!vpe || !param || !bufs)
return VPE_STATUS_ERROR;
vpe_priv = container_of(vpe, struct vpe_priv, pub);
if (!vpe_priv->ops_support) {
VPE_ASSERT(vpe_priv->ops_support);
status = VPE_STATUS_NOT_SUPPORTED;
}
if (status == VPE_STATUS_OK) {
status = handle_zero_input(vpe, param, &param);
if (status != VPE_STATUS_OK)
status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED;
}
if (status == VPE_STATUS_OK) {
if (!validate_cached_param(vpe_priv, param)) {
status = VPE_STATUS_PARAM_CHECK_ERROR;
}
}
if (status == VPE_STATUS_OK) {
if (bufs->cmd_buf.size == 0 || bufs->emb_buf.size == 0) {
/* Here we directly return without setting ops_support to false
* becaues the supported check is already passed
* and the caller can come again with correct buffer size.
*/
bufs->cmd_buf.size = (int64_t)vpe_priv->bufs_required.cmd_buf_size;
bufs->emb_buf.size = (int64_t)vpe_priv->bufs_required.emb_buf_size;
return VPE_STATUS_OK;
} else if ((bufs->cmd_buf.size < (int32_t)vpe_priv->bufs_required.cmd_buf_size) ||
(bufs->emb_buf.size < (int32_t)vpe_priv->bufs_required.emb_buf_size)) {
status = VPE_STATUS_INVALID_BUFFER_SIZE;
}
}
builder = &vpe_priv->resource.cmd_builder;
// store buffers original values
cmd_buf_cpu_a = bufs->cmd_buf.cpu_va;
cmd_buf_gpu_a = bufs->cmd_buf.gpu_va;
cmd_buf_size = bufs->cmd_buf.size;
emb_buf_cpu_a = bufs->emb_buf.cpu_va;
emb_buf_gpu_a = bufs->emb_buf.gpu_va;
emb_buf_size = bufs->emb_buf.size;
// curr_bufs is used for tracking the built size and next pointers
curr_bufs = *bufs;
// copy the param, reset saved configs
for (i = 0; i < param->num_streams; i++) {
vpe_priv->stream_ctx[i].num_configs = 0;
for (j = 0; j < VPE_CMD_TYPE_COUNT; j++)
vpe_priv->stream_ctx[i].num_stream_op_configs[j] = 0;
}
vpe_priv->output_ctx.num_configs = 0;
// Reset pipes
vpe_pipe_reset(vpe_priv);
if (status == VPE_STATUS_OK) {
status = vpe_color_update_color_space_and_tf(vpe_priv, param);
if (status != VPE_STATUS_OK) {
vpe_log("failed in updating color space and tf %d\n", (int)status);
}
}
if (status == VPE_STATUS_OK) {
status = vpe_color_update_movable_cm(vpe_priv, param);
if (status != VPE_STATUS_OK) {
vpe_log("failed in updating movable 3d lut unit %d\n", (int)status);
}
}
if (status == VPE_STATUS_OK) {
status = vpe_color_update_whitepoint(vpe_priv, param);
if (status != VPE_STATUS_OK) {
vpe_log("failed updating whitepoint gain %d\n", (int)status);
}
}
if (status == VPE_STATUS_OK) {
VPE_ASSERT(validate_color_pipeline(vpe_priv, param));
}
if (status == VPE_STATUS_OK) {
vpe_bg_color_convert(vpe_priv->output_ctx.cs, vpe_priv->output_ctx.output_tf,
&vpe_priv->output_ctx.bg_color);
for (cmd_idx = 0; cmd_idx < vpe_priv->num_vpe_cmds; cmd_idx++) {
status = builder->build_vpe_cmd(vpe_priv, &curr_bufs, cmd_idx);
if (status != VPE_STATUS_OK) {
vpe_log("failed in building vpe cmd %d\n", (int)status);
}
}
}
if (status == VPE_STATUS_OK) {
bufs->cmd_buf.size = cmd_buf_size - curr_bufs.cmd_buf.size; // used cmd buffer size
bufs->cmd_buf.gpu_va = cmd_buf_gpu_a;
bufs->cmd_buf.cpu_va = cmd_buf_cpu_a;
bufs->emb_buf.size = emb_buf_size - curr_bufs.emb_buf.size; // used emb buffer size
bufs->emb_buf.gpu_va = emb_buf_gpu_a;
bufs->emb_buf.cpu_va = emb_buf_cpu_a;
}
vpe_priv->ops_support = false;
if (vpe_priv->init.debug.assert_when_not_support)
VPE_ASSERT(status == VPE_STATUS_OK);
return status;
}
+100
View File
@@ -0,0 +1,100 @@
/* 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 "conversion.h"
#define DIVIDER 10000
/* S2D13 value in [-3.99...3.9999] */
#define S2D13_MIN ((long long)(-3.999 * DIVIDER))
#define S2D13_MAX ((long long)(3.999 * DIVIDER))
#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))
uint16_t conv_fixed_point_to_int_frac(
struct fixed31_32 arg, uint8_t integer_bits, uint8_t fractional_bits)
{
int32_t numerator;
int32_t divisor = 1 << fractional_bits;
uint16_t result;
uint16_t d = (uint16_t)vpe_fixpt_floor(vpe_fixpt_abs(arg));
if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
numerator = (uint16_t)vpe_fixpt_round(vpe_fixpt_mul_int(arg, divisor));
else {
numerator = vpe_fixpt_floor(vpe_fixpt_sub(
vpe_fixpt_from_int(1LL << integer_bits), vpe_fixpt_recip(vpe_fixpt_from_int(divisor))));
}
if (numerator >= 0)
result = (uint16_t)numerator;
else
result = (uint16_t)((1 << (integer_bits + fractional_bits + 1)) + numerator);
if ((result != 0) && vpe_fixpt_lt(arg, vpe_fixpt_zero))
result |= 1 << (integer_bits + fractional_bits);
return result;
}
void conv_convert_float_matrix(uint16_t *matrix, const struct fixed31_32 *flt, uint32_t buffer_size)
{
const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
uint32_t i;
for (i = 0; i < buffer_size; ++i) {
uint32_t reg_value =
conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
matrix[i] = (uint16_t)reg_value;
}
}
struct fixed31_32 vpe_convfix31_32(int16_t inval)
{
const int integerBits = 2;
const int fractionalBits = 13;
struct fixed31_32 result;
long long outintegerPart;
long long outfractionalPart;
int sign = 1;
if (inval & (1 << (integerBits + fractionalBits + 1))) {
sign = -1;
inval = -inval;
}
outintegerPart = ((long long)inval >> fractionalBits) << 32;
outfractionalPart = ((long long)inval & (((long long)1 << fractionalBits) - 1));
;
outfractionalPart <<= (32 - fractionalBits);
result.value = outintegerPart | outfractionalPart;
if (sign < 0)
result.value = -result.value;
return result;
}
+155
View File
@@ -0,0 +1,155 @@
/* 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 "custom_float.h"
static bool build_custom_float(struct fixed31_32 value, const struct custom_float_format *format,
bool *negative, uint32_t *mantissa, uint32_t *exponenta)
{
uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
const struct fixed31_32 mantissa_constant_plus_max_fraction = vpe_fixpt_from_fraction(
(1LL << (format->mantissa_bits + 1)) - 1, 1LL << format->mantissa_bits);
struct fixed31_32 mantiss;
if (vpe_fixpt_eq(value, vpe_fixpt_zero)) {
*negative = false;
*mantissa = 0;
*exponenta = 0;
return true;
}
if (vpe_fixpt_lt(value, vpe_fixpt_zero)) {
*negative = format->sign;
value = vpe_fixpt_neg(value);
} else {
*negative = false;
}
if (vpe_fixpt_lt(value, vpe_fixpt_one)) {
uint32_t i = 1;
do {
value = vpe_fixpt_shl(value, 1);
++i;
} while (vpe_fixpt_lt(value, vpe_fixpt_one));
--i;
if (exp_offset <= i) {
*mantissa = 0;
*exponenta = 0;
return true;
}
*exponenta = exp_offset - i;
} else if (vpe_fixpt_le(mantissa_constant_plus_max_fraction, value)) {
uint32_t i = 1;
do {
value = vpe_fixpt_shr(value, 1);
++i;
} while (vpe_fixpt_lt(mantissa_constant_plus_max_fraction, value));
*exponenta = exp_offset + i - 1;
} else {
*exponenta = exp_offset;
}
mantiss = vpe_fixpt_sub(value, vpe_fixpt_one);
if (vpe_fixpt_lt(mantiss, vpe_fixpt_zero) || vpe_fixpt_lt(vpe_fixpt_one, mantiss))
mantiss = vpe_fixpt_zero;
else
mantiss = vpe_fixpt_shl(mantiss, (unsigned char)format->mantissa_bits);
*mantissa = (uint32_t)vpe_fixpt_floor(mantiss);
return true;
}
static bool setup_custom_float(const struct 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) {
VPE_ASSERT(0);
mantissa = mantissa_mask;
}
if (exponenta & ~exponenta_mask) {
VPE_ASSERT(0);
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 vpe_convert_to_custom_float_format(
struct fixed31_32 value, const struct custom_float_format *format, uint32_t *result)
{
uint32_t mantissa;
uint32_t exponenta;
bool negative;
return build_custom_float(value, format, &negative, &mantissa, &exponenta) &&
setup_custom_float(format, negative, mantissa, exponenta, result);
}
+312
View File
@@ -0,0 +1,312 @@
/* 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 "vpe_assert.h"
#include "custom_fp16.h"
#include <math.h>
#include <stdbool.h>
static bool build_custom_float(double value, const struct vpe_custom_float_format2 *fmt,
bool *pbNegative, unsigned int *pexponent, unsigned int *pmantissa)
{
bool bRet = false;
double mantissaConstant = 1.0;
double base = 2.0;
int expOffset = (int)(pow(2.0, fmt->exponentaBits - 1) - 1);
double maxFraction = 1.0 - pow(0.5, fmt->mantissaBits);
unsigned int exponent;
double mantissa;
unsigned int Mantissa;
int i;
bool bAlwaysFalse = false;
// if value negative and we should consider this otherwize just ignore
if (value < 0 && fmt->flags.bits.sign == 1)
*pbNegative = true;
else
*pbNegative = false;
do {
if (value == 0.0) {
*pexponent = 0;
*pmantissa = 0;
bRet = true;
break;
}
if (value < 0)
value = (-1.0) * value;
if (value < mantissaConstant) {
/*if log works faster then remove the loops!*/
for (i = 1;; i++) {
value *= base;
if (value >= mantissaConstant)
break;
}
if (expOffset <= i) {
*pexponent = 0;
*pmantissa = 0;
bRet = true;
break;
}
exponent = (unsigned int)(expOffset - i);
} else if (value >= mantissaConstant + maxFraction) {
for (i = 1;; i++) {
value /= base;
if (value <= mantissaConstant + maxFraction)
break;
}
exponent = (unsigned int)(expOffset + i);
} else
exponent = (unsigned int)expOffset;
mantissa = value - mantissaConstant;
if (mantissa < 0.0 || mantissa > 1.0)
mantissa = 0;
else
mantissa *= pow(2.0, fmt->mantissaBits);
Mantissa = (unsigned int)mantissa;
*pexponent = exponent;
*pmantissa = Mantissa;
bRet = true;
} while (bAlwaysFalse);
return bRet;
}
static bool setup_custom_float(const struct vpe_custom_float_format2 *fmt, bool bNegative,
unsigned int exponent, unsigned int mantissa, uint16_t *pvalue)
{
unsigned int value = 0;
unsigned int mask;
unsigned int i;
unsigned int j;
if (fmt->exponentaBits == 6 && fmt->mantissaBits == 12 && fmt->flags.bits.sign == 0) {
if (exponent & ~(unsigned int)0x3F)
exponent = 0x3F;
if (mantissa & ~(unsigned int)0xFFF)
mantissa = 0xFFF;
} else if (fmt->exponentaBits == 6 && fmt->mantissaBits == 10 && fmt->flags.bits.sign == 0) {
if (exponent & ~(unsigned int)0x3F)
exponent = 0x3F;
if (mantissa & ~(unsigned int)0x3FF)
mantissa = 0x3FF;
} else if (fmt->exponentaBits == 6 && fmt->mantissaBits == 12 && fmt->flags.bits.sign == 1) {
if (exponent & ~(unsigned int)0x3F)
exponent = 0x3F;
if (mantissa & ~(unsigned int)0xFFF)
mantissa = 0xFFF;
} else if (fmt->exponentaBits == 5 && fmt->mantissaBits == 10 && fmt->flags.bits.sign == 1) {
if (exponent & ~(unsigned int)0x1F)
exponent = 0x1F;
if (mantissa & ~(unsigned int)0x3FF)
mantissa = 0x3FF;
} else
return false;
for (i = 0; i < fmt->mantissaBits; i++) {
mask = 1 << i;
if (mantissa & mask)
value |= mask;
}
for (j = 0; j < fmt->exponentaBits; j++) {
mask = 1 << j;
if (exponent & mask)
value |= mask << i;
}
if (bNegative == true && fmt->flags.bits.sign == 1)
value |= 1 << (i + j);
*pvalue = (uint16_t)value;
return true;
}
bool vpe_convert_from_float_to_custom_float(
double value, const struct vpe_custom_float_format2 *fmt, uint16_t *pvalue)
{
bool isNegative;
unsigned int exponent;
unsigned int mantissa;
bool ret = false;
VPE_ASSERT(
(fmt->flags.bits.sign == 1) && (fmt->mantissaBits == 10) && (fmt->exponentaBits == 5));
if (!build_custom_float(value, fmt, &isNegative, &exponent, &mantissa))
goto release;
if (!setup_custom_float(fmt, isNegative, exponent, mantissa, pvalue))
goto release;
ret = true;
release:
return ret;
}
static bool setup_custom_float_generic(const struct vpe_custom_float_format2 *fmt, bool bNegative,
unsigned int exponent, unsigned int mantissa, int *pvalue)
{
unsigned int value = 0;
int mask;
if (fmt->exponentaBits == 6 && fmt->mantissaBits == 12 && fmt->flags.bits.sign == 0) {
if (exponent & ~0x3F)
exponent = 0x3F;
if (mantissa & ~0xFFF)
mantissa = 0xFFF;
} else if (fmt->exponentaBits == 6 && fmt->mantissaBits == 10 && fmt->flags.bits.sign == 0) {
if (exponent & ~0x3F)
exponent = 0x3F;
if (mantissa & ~0x3FF)
mantissa = 0x3FF;
} else if (fmt->exponentaBits == 6 && fmt->mantissaBits == 12 && fmt->flags.bits.sign == 1) {
if (exponent & ~0x3F)
exponent = 0x3F;
if (mantissa & ~0xFFF)
mantissa = 0xFFF;
} else
return false;
unsigned int i;
unsigned int j;
for (i = 0; i < fmt->mantissaBits; i++) {
mask = 1 << i;
if (mantissa & mask)
value |= mask;
}
for (j = 0; j < fmt->exponentaBits; j++) {
mask = 1 << j;
if (exponent & mask)
value |= mask << i;
}
if (bNegative == true && fmt->flags.bits.sign == 1)
value |= 1 << (i + j);
*pvalue = value;
return true;
}
bool vpe_convert_to_custom_float_generic(
double value, const struct vpe_custom_float_format2 *fmt, int *pvalue)
{
bool isNegative;
unsigned int exponent;
unsigned int mantissa;
bool ret = false;
if (!build_custom_float(value, fmt, &isNegative, &exponent, &mantissa))
goto release;
if (!setup_custom_float_generic(fmt, isNegative, exponent, mantissa, pvalue))
goto release;
ret = true;
release:
return ret;
}
bool vpe_convert_to_custom_float_ex_generic(double value,
const struct vpe_custom_float_format2 *fmt, struct vpe_custom_float_value2 *pvalue)
{
bool ret = false;
if (!build_custom_float(value, fmt, &pvalue->isNegative, &pvalue->exponenta, &pvalue->mantissa))
goto release;
if (!setup_custom_float_generic(
fmt, pvalue->isNegative, pvalue->exponenta, pvalue->mantissa, &pvalue->value))
goto release;
ret = true;
release:
return ret;
}
bool vpe_from_1_6_12_to_double(
bool bIsNegative, unsigned int E, unsigned int F, double *DoubleFloat)
{
double ret = 0;
double M, F1, A, B, C, D2, e12;
A = 2.0;
B = 31.0;
C = 1.0;
D2 = -30.0;
e12 = pow(2, 12);
M = F / e12;
if (bIsNegative == false)
F1 = 1.0;
else
F1 = -1.0;
if (E > 0 && E < 63)
ret = F1 * (C + M) * pow(A, E - B);
else if (E == 0 && F != 0)
ret = F1 * M * pow(A, D2);
else if (E == 0 && F == 0 && bIsNegative == true)
ret = -0;
else if (E == 0 && F == 0 && bIsNegative == false)
ret = 0;
else if (E == 63 && F != 0)
return false; // -1; /* Not a number*/
else if (E == 63 && F == 0 && bIsNegative == true)
return false; //-2; /* -Infinity*/
else if (E == 63 && F == 0 && bIsNegative == false)
return false; // -3; /* Infinity */
*DoubleFloat = ret;
return true;
}
bool vpe_convert_from_float_to_fp16(double value, uint16_t *pvalue)
{
struct vpe_custom_float_format2 fmt;
fmt.flags.Uint = 0;
fmt.flags.bits.sign = 1;
fmt.mantissaBits = 10;
fmt.exponentaBits = 5;
return vpe_convert_from_float_to_custom_float(value, &fmt, pvalue);
}
+429
View File
@@ -0,0 +1,429 @@
/* 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 "fixed31_32.h"
#include "calc_u64.h"
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 complete_integer_division_u64(
unsigned long long dividend, unsigned long long divisor, unsigned long long *remainder)
{
unsigned long long result;
VPE_ASSERT(divisor);
result = 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 fixed31_32 vpe_fixpt_from_fraction(long long numerator, long long denominator)
{
struct fixed31_32 res;
bool arg1_negative = numerator < 0;
bool arg2_negative = denominator < 0;
unsigned long long arg1_value = (unsigned long long)(arg1_negative ? -numerator : numerator);
unsigned long long arg2_value =
(unsigned long long)(arg2_negative ? -denominator : denominator);
unsigned long long remainder;
/* determine integer part */
unsigned long long res_value =
complete_integer_division_u64(arg1_value, arg2_value, &remainder);
VPE_ASSERT(res_value <= 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;
VPE_ASSERT(res_value <= LLONG_MAX - summand);
res_value += summand;
}
res.value = (long long)res_value;
if (arg1_negative ^ arg2_negative)
res.value = -res.value;
return res;
}
struct fixed31_32 vpe_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
struct fixed31_32 res;
bool arg1_negative = arg1.value < 0;
bool arg2_negative = arg2.value < 0;
unsigned long long arg1_value = (unsigned long long)(arg1_negative ? -arg1.value : arg1.value);
unsigned long long arg2_value = (unsigned long long)(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 = (long long)(arg1_int * arg2_int);
VPE_ASSERT(res.value <= LONG_MAX);
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
tmp = arg1_int * arg2_fra;
VPE_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
tmp = arg2_int * arg1_fra;
VPE_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)vpe_fixpt_half.value);
VPE_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
if (arg1_negative ^ arg2_negative)
res.value = -res.value;
return res;
}
struct fixed31_32 vpe_fixpt_sqr(struct fixed31_32 arg)
{
struct 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 = (long long)(arg_int * arg_int);
VPE_ASSERT(res.value <= LONG_MAX);
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
tmp = arg_int * arg_fra;
VPE_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
VPE_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)vpe_fixpt_half.value);
VPE_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
res.value += tmp;
return res;
}
struct fixed31_32 vpe_fixpt_recip(struct fixed31_32 arg)
{
/*
* @note
* Good idea to use Newton's method
*/
VPE_ASSERT(arg.value);
return vpe_fixpt_from_fraction(vpe_fixpt_one.value, arg.value);
}
struct fixed31_32 vpe_fixpt_sinc(struct fixed31_32 arg)
{
struct fixed31_32 square;
struct fixed31_32 res = vpe_fixpt_one;
int n = 27;
struct fixed31_32 arg_norm = arg;
if (vpe_fixpt_le(vpe_fixpt_two_pi, vpe_fixpt_abs(arg))) {
arg_norm =
vpe_fixpt_sub(arg_norm, vpe_fixpt_mul_int(vpe_fixpt_two_pi,
(int)div64_s64(arg_norm.value, vpe_fixpt_two_pi.value)));
}
square = vpe_fixpt_sqr(arg_norm);
do {
res = vpe_fixpt_sub(
vpe_fixpt_one, vpe_fixpt_div_int(vpe_fixpt_mul(square, res), n * (n - 1)));
n -= 2;
} while (n > 2);
if (arg.value != arg_norm.value)
res = vpe_fixpt_div(vpe_fixpt_mul(res, arg_norm), arg);
return res;
}
struct fixed31_32 vpe_fixpt_sin(struct fixed31_32 arg)
{
return vpe_fixpt_mul(arg, vpe_fixpt_sinc(arg));
}
struct fixed31_32 vpe_fixpt_cos(struct fixed31_32 arg)
{
/* TODO implement argument normalization */
const struct fixed31_32 square = vpe_fixpt_sqr(arg);
struct fixed31_32 res = vpe_fixpt_one;
int n = 26;
do {
res = vpe_fixpt_sub(
vpe_fixpt_one, vpe_fixpt_div_int(vpe_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 fixed31_32 fixed31_32_exp_from_taylor_series(struct fixed31_32 arg)
{
unsigned int n = 9;
struct fixed31_32 res = vpe_fixpt_from_fraction(n + 2, n + 1);
/* TODO find correct res */
VPE_ASSERT(vpe_fixpt_lt(arg, vpe_fixpt_one));
do
res = vpe_fixpt_add(vpe_fixpt_one, vpe_fixpt_div_int(vpe_fixpt_mul(arg, res), n));
while (--n != 1);
return vpe_fixpt_add(vpe_fixpt_one, vpe_fixpt_mul(arg, res));
}
struct fixed31_32 vpe_fixpt_exp(struct 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 (vpe_fixpt_le(vpe_fixpt_ln2_div_2, vpe_fixpt_abs(arg))) {
int m = vpe_fixpt_round(vpe_fixpt_div(arg, vpe_fixpt_ln2));
struct fixed31_32 r = vpe_fixpt_sub(arg, vpe_fixpt_mul_int(vpe_fixpt_ln2, m));
VPE_ASSERT(m != 0);
VPE_ASSERT(vpe_fixpt_lt(vpe_fixpt_abs(r), vpe_fixpt_one));
if (m > 0)
return vpe_fixpt_shl(fixed31_32_exp_from_taylor_series(r), (unsigned char)m);
else
return vpe_fixpt_div_int(fixed31_32_exp_from_taylor_series(r), 1LL << -m);
} else if (arg.value != 0)
return fixed31_32_exp_from_taylor_series(arg);
else
return vpe_fixpt_one;
}
struct fixed31_32 vpe_fixpt_log(struct fixed31_32 arg)
{
struct fixed31_32 res = vpe_fixpt_neg(vpe_fixpt_one);
/* TODO improve 1st estimation */
struct fixed31_32 error;
VPE_ASSERT(arg.value > 0);
/* TODO if arg is negative, return NaN */
/* TODO if arg is zero, return -INF */
do {
struct fixed31_32 res1 = vpe_fixpt_add(
vpe_fixpt_sub(res, vpe_fixpt_one), vpe_fixpt_div(arg, vpe_fixpt_exp(res)));
error = vpe_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
* vpe_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 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 & (unsigned long long)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 clamp_ux_dy(long long value, unsigned int integer_bits,
unsigned int fractional_bits, unsigned int min_clamp)
{
unsigned int truncated_val = 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 vpe_fixpt_u4d19(struct fixed31_32 arg)
{
return ux_dy(arg.value, 4, 19);
}
unsigned int vpe_fixpt_u3d19(struct fixed31_32 arg)
{
return ux_dy(arg.value, 3, 19);
}
unsigned int vpe_fixpt_u2d19(struct fixed31_32 arg)
{
return ux_dy(arg.value, 2, 19);
}
unsigned int vpe_fixpt_u0d19(struct fixed31_32 arg)
{
return ux_dy(arg.value, 0, 19);
}
unsigned int vpe_fixpt_clamp_u0d14(struct fixed31_32 arg)
{
return clamp_ux_dy(arg.value, 0, 14, 1);
}
unsigned int vpe_fixpt_clamp_u0d10(struct fixed31_32 arg)
{
return clamp_ux_dy(arg.value, 0, 10, 1);
}
int vpe_fixpt_s4d19(struct fixed31_32 arg)
{
if (arg.value < 0)
return -(int)ux_dy(vpe_fixpt_abs(arg).value, 4, 19);
else
return (int)ux_dy(arg.value, 4, 19);
}
unsigned int vpe_to_fixed_point(
unsigned int decimalBits, double value, unsigned int mask, double d_pix)
{
unsigned int d_i;
d_i = (int)((value * d_pix) + 0.5);
d_i = d_i & mask;
return d_i;
}
+65
View File
@@ -0,0 +1,65 @@
/* 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 <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
*remainder = dividend % divisor;
return dividend / divisor;
}
static inline uint64_t div_u64(uint64_t dividend, uint32_t divisor)
{
return dividend / divisor;
}
static inline uint64_t div64_u64(uint64_t dividend, uint64_t divisor)
{
return dividend / divisor;
}
static inline uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{
*remainder = dividend % divisor;
return dividend / divisor;
}
static inline int64_t div64_s64(int64_t dividend, int64_t divisor)
{
return dividend / divisor;
}
#ifdef __cplusplus
}
#endif
+43
View File
@@ -0,0 +1,43 @@
/* 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 "fixed31_32.h"
#ifdef __cplusplus
extern "C" {
#endif
uint16_t conv_fixed_point_to_int_frac(
struct fixed31_32 arg, uint8_t integer_bits, uint8_t fractional_bits);
void conv_convert_float_matrix(
uint16_t *matrix, const struct fixed31_32 *flt, uint32_t buffer_size);
struct fixed31_32 vpe_convfix31_32(int16_t inval);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,46 @@
/* 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 <stdint.h>
#include <stdbool.h>
#include "fixed31_32.h"
#ifdef __cplusplus
extern "C" {
#endif
struct custom_float_format {
uint32_t mantissa_bits;
uint32_t exponenta_bits;
bool sign;
};
bool vpe_convert_to_custom_float_format(
struct fixed31_32 value, const struct custom_float_format *format, uint32_t *result);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,59 @@
/* 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 <stdbool.h>
#include <stdint.h>
union custom_float_format_flags2 {
unsigned int Uint;
struct {
unsigned int sign : 1;
unsigned int reserved31 : 31;
} bits;
};
struct vpe_custom_float_format2 {
unsigned int mantissaBits;
unsigned int exponentaBits;
union custom_float_format_flags2 flags;
};
struct vpe_custom_float_value2 {
unsigned int mantissa;
unsigned int exponenta;
int value;
bool isNegative;
};
bool vpe_convert_from_float_to_custom_float(
double value, const struct vpe_custom_float_format2 *fmt, uint16_t *pvalue);
bool vpe_convert_from_float_to_fp16(double value, uint16_t *pvalue);
bool vpe_convert_to_custom_float_generic(
double value, const struct vpe_custom_float_format2 *fmt, int *pvalue);
bool vpe_convert_to_custom_float_ex_generic(double value,
const struct vpe_custom_float_format2 *fmt, struct vpe_custom_float_value2 *pvalue);
bool vpe_from_1_6_12_to_double(
bool bIsNegative, unsigned int E, unsigned int F, double *DoubleFloat);
+548
View File
@@ -0,0 +1,548 @@
/* 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 <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <stddef.h>
#include "vpe_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#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
#ifndef ASSERT
#define ASSERT assert
#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 fixed31_32 {
long long value;
};
/*
* @brief
* Useful constants
*/
static const struct fixed31_32 vpe_fixpt_zero = {0};
static const struct fixed31_32 vpe_fixpt_epsilon = {1LL};
static const struct fixed31_32 vpe_fixpt_half = {0x80000000LL};
static const struct fixed31_32 vpe_fixpt_one = {0x100000000LL};
static const struct fixed31_32 vpe_fixpt_pi = {13493037705LL};
static const struct fixed31_32 vpe_fixpt_two_pi = {26986075409LL};
static const struct fixed31_32 vpe_fixpt_e = {11674931555LL};
static const struct fixed31_32 vpe_fixpt_ln2 = {2977044471LL};
static const struct fixed31_32 vpe_fixpt_ln2_div_2 = {1488522236LL};
/*
* @brief
* Initialization routines
*/
/*
* @brief
* result = numerator / denominator
*/
struct fixed31_32 vpe_fixpt_from_fraction(long long numerator, long long denominator);
/*
* @brief
* result = arg
*/
static inline struct fixed31_32 vpe_fixpt_from_int(long long arg)
{
struct 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 fixed31_32 vpe_fixpt_neg(struct fixed31_32 arg)
{
struct fixed31_32 res;
res.value = -arg.value;
return res;
}
/*
* @brief
* result = abs(arg) := (arg >= 0) ? arg : -arg
*/
static inline struct fixed31_32 vpe_fixpt_abs(struct fixed31_32 arg)
{
if (arg.value < 0)
return vpe_fixpt_neg(arg);
else
return arg;
}
/*
* @brief
* Binary relational operators
*/
/*
* @brief
* result = arg1 < arg2
*/
static inline bool vpe_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
return arg1.value < arg2.value;
}
/*
* @brief
* result = arg1 <= arg2
*/
static inline bool vpe_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
return arg1.value <= arg2.value;
}
/*
* @brief
* result = arg1 == arg2
*/
static inline bool vpe_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
return arg1.value == arg2.value;
}
/*
* @brief
* result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
*/
static inline struct fixed31_32 vpe_fixpt_min(struct fixed31_32 arg1, struct 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 fixed31_32 vpe_fixpt_max(struct fixed31_32 arg1, struct 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 fixed31_32 vpe_fixpt_clamp(
struct fixed31_32 arg, struct fixed31_32 min_value, struct fixed31_32 max_value)
{
if (vpe_fixpt_le(arg, min_value))
return min_value;
else if (vpe_fixpt_le(max_value, arg))
return max_value;
else
return arg;
}
/*
* @brief
* Binary shift operators
*/
/*
* @brief
* result = arg << shift
*/
static inline struct fixed31_32 vpe_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
{
VPE_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 fixed31_32 vpe_fixpt_shr(struct fixed31_32 arg, unsigned char 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 fixed31_32 vpe_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
struct fixed31_32 res;
VPE_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 fixed31_32 vpe_fixpt_add_int(struct fixed31_32 arg1, int arg2)
{
return vpe_fixpt_add(arg1, vpe_fixpt_from_int(arg2));
}
/*
* @brief
* result = arg1 - arg2
*/
static inline struct fixed31_32 vpe_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
struct fixed31_32 res;
VPE_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 fixed31_32 vpe_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
{
return vpe_fixpt_sub(arg1, vpe_fixpt_from_int(arg2));
}
/*
* @brief
* Binary multiplicative operators
*/
/*
* @brief
* result = arg1 * arg2
*/
struct fixed31_32 vpe_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
/*
* @brief
* result = arg1 * arg2
*/
static inline struct fixed31_32 vpe_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
{
return vpe_fixpt_mul(arg1, vpe_fixpt_from_int(arg2));
}
/*
* @brief
* result = square(arg) := arg * arg
*/
struct fixed31_32 vpe_fixpt_sqr(struct fixed31_32 arg);
/*
* @brief
* result = arg1 / arg2
*/
static inline struct fixed31_32 vpe_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
{
return vpe_fixpt_from_fraction(arg1.value, vpe_fixpt_from_int(arg2).value);
}
/*
* @brief
* result = arg1 / arg2
*/
static inline struct fixed31_32 vpe_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
return vpe_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 fixed31_32 vpe_fixpt_recip(struct 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 fixed31_32 vpe_fixpt_sinc(struct fixed31_32 arg);
/*
* @brief
* result = sin(arg)
*
* @note
* Argument specified in radians,
* internally it's normalized to [-2pi...2pi] range.
*/
struct fixed31_32 vpe_fixpt_sin(struct 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 fixed31_32 vpe_fixpt_cos(struct fixed31_32 arg);
/*
* @brief
* Transcendent functions
*/
/*
* @brief
* result = exp(arg)
*
* @note
* Currently, function is verified for abs(arg) <= 1.
*/
struct fixed31_32 vpe_fixpt_exp(struct 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 fixed31_32 vpe_fixpt_log(struct 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 fixed31_32 vpe_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
{
if (arg1.value == 0)
return arg2.value == 0 ? vpe_fixpt_one : vpe_fixpt_zero;
return vpe_fixpt_exp(vpe_fixpt_mul(vpe_fixpt_log(arg1), arg2));
}
/*
* @brief
* Rounding functions
*/
/*
* @brief
* result = floor(arg) := greatest integer lower than or equal to arg
*/
static inline int vpe_fixpt_floor(struct 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 vpe_fixpt_round(struct fixed31_32 arg)
{
unsigned long long arg_value = (unsigned long long)(arg.value > 0 ? arg.value : -arg.value);
const long long summand = vpe_fixpt_half.value;
VPE_ASSERT(LLONG_MAX - (long long)arg_value >= summand);
arg_value += (unsigned long long)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 vpe_fixpt_ceil(struct fixed31_32 arg)
{
unsigned long long arg_value = (unsigned long long)(arg.value > 0 ? arg.value : -arg.value);
const long long summand = vpe_fixpt_one.value - vpe_fixpt_epsilon.value;
VPE_ASSERT(LLONG_MAX - (long long)arg_value >= summand);
arg_value += (unsigned long long)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 vpe_fixpt_u4d19(struct fixed31_32 arg);
unsigned int vpe_fixpt_u3d19(struct fixed31_32 arg);
unsigned int vpe_fixpt_u2d19(struct fixed31_32 arg);
unsigned int vpe_fixpt_u0d19(struct fixed31_32 arg);
unsigned int vpe_fixpt_clamp_u0d14(struct fixed31_32 arg);
unsigned int vpe_fixpt_clamp_u0d10(struct fixed31_32 arg);
int vpe_fixpt_s4d19(struct fixed31_32 arg);
static inline struct fixed31_32 vpe_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
{
bool negative = arg.value < 0;
if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
VPE_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;
}
unsigned int vpe_to_fixed_point(
unsigned int decimalBits, double value, unsigned int mask, double d_pix);
#ifdef __cplusplus
}
#endif