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:
@@ -41,3 +41,7 @@ endif
|
||||
if with_tools.contains('drm-shim')
|
||||
subdir('drm-shim')
|
||||
endif
|
||||
|
||||
if with_gallium_radeonsi
|
||||
subdir('vpelib')
|
||||
endif
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, ¶ms, 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
@@ -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;
|
||||
}
|
||||
@@ -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, ¶ms->lut_3d);
|
||||
params->state.bits.initialized = 1;
|
||||
|
||||
vpe_free(rgb_area);
|
||||
ret = true;
|
||||
release:
|
||||
return ret;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, ¶ms, 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, ¶ms, 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, ¶m->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,
|
||||
¶m->streams[stream_idx].surface_info.cs, ¶m->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,
|
||||
¶m->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,
|
||||
¶m->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;
|
||||
}
|
||||
@@ -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, °am_r, true);
|
||||
compute_degam(output_tf->tf, (double)bg_color->rgba.g, °am_g, true);
|
||||
compute_degam(output_tf->tf, (double)bg_color->rgba.b, °am_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, °am_r, true);
|
||||
compute_depq((double)bg_color->rgba.g, °am_g, true);
|
||||
compute_depq((double)bg_color->rgba.b, °am_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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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 = ¶m->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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, ¶ms->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, ¶m);
|
||||
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, ¶m->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, ¶m->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, ¶m->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, ¶m->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, ¶m->bg_color, sizeof(struct vpe_color)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&output_ctx->target_rect, ¶m->target_rect, sizeof(struct vpe_rect)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&output_ctx->surface, ¶m->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, ¶m);
|
||||
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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -165,8 +165,8 @@ libradeonsi = static_library(
|
||||
|
||||
driver_radeonsi = declare_dependency(
|
||||
compile_args : '-DGALLIUM_RADEONSI',
|
||||
link_with : radeonsi_gfx_libs + amd_common_libs + [
|
||||
libradeonsi, libradeonwinsys, libamdgpuwinsys, libgalliumvl
|
||||
link_with : radeonsi_gfx_libs + [
|
||||
libradeonsi, libradeonwinsys, libamdgpuwinsys, libamd_common, libamd_common_llvm, libgalliumvl, libvpe
|
||||
],
|
||||
dependencies : idep_nir,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user