amd/vpelib: General cleanup / optimization tasks

Various small optimizations that have been accumulating, deal with them
in one commit:

- Add erase functionality for vector util, remove memsets for time opt.
- Update should_gen_cmd_info to take in any stream variables.
- Program funcs should directly program - update mpcc mux hook func to
  take in blend_mode.
- Add reserved bits for debug flags.

Signed-off-by: Brendan Steven, Leder <BrendanSteven.Leder@amd.com>
Acked-by: Chuanyu Tseng <Chuanyu.Tseng@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36809>
This commit is contained in:
Leder, Brendan Steve (Brendan) 2025-07-30 12:07:36 -04:00 committed by ChuanYu Tseng (Max)
parent e5cdc78e0e
commit a486404e4d
9 changed files with 71 additions and 23 deletions

View file

@ -450,6 +450,7 @@ struct vpe_debug_options {
uint32_t skip_optimal_tap_check : 1; /**< Skip optimal tap check */
uint32_t disable_lut_caching : 1; /**< disable config caching for all luts */
uint32_t disable_performance_mode : 1; /**< disable performance mode */
uint32_t reserved : 8;
} flags; /**< debug flags */
// valid only if the corresponding flag is set

View file

@ -1404,7 +1404,7 @@ void vpe10_construct_mpc(struct vpe_priv *vpe_priv, struct mpc *mpc);
void vpe10_mpc_program_mpcc_mux(struct mpc *mpc, enum mpc_mpccid mpcc_idx,
enum mpc_mux_topsel topsel, enum mpc_mux_botsel botsel, enum mpc_mux_outmux outmux,
enum mpc_mux_oppid oppid);
enum mpc_mux_oppid oppid, enum mpcc_blend_mode blend_mode);
void vpe10_mpc_program_mpcc_blending(
struct mpc *mpc, enum mpc_mpccid mpcc_idx, struct mpcc_blnd_cfg *blnd_cfg);

View file

@ -67,7 +67,7 @@ void vpe10_construct_mpc(struct vpe_priv *vpe_priv, struct mpc *mpc)
void vpe10_mpc_program_mpcc_mux(struct mpc *mpc, enum mpc_mpccid mpcc_idx,
enum mpc_mux_topsel topsel, enum mpc_mux_botsel botsel, enum mpc_mux_outmux outmux,
enum mpc_mux_oppid oppid)
enum mpc_mux_oppid oppid, enum mpcc_blend_mode blend_mode)
{
PROGRAM_ENTRY();
@ -77,21 +77,7 @@ void vpe10_mpc_program_mpcc_mux(struct mpc *mpc, enum mpc_mpccid mpcc_idx,
REG_SET(VPMPCC_BOT_SEL, 0, VPMPCC_BOT_SEL, botsel);
REG_SET(VPMPC_OUT_MUX, 0, VPMPC_OUT_MUX, outmux);
REG_SET(VPMPCC_VPOPP_ID, 0, VPMPCC_VPOPP_ID, oppid);
/* program mux and MPCC_MODE */
if (mpc->vpe_priv->init.debug.mpc_bypass) {
REG_UPDATE(VPMPCC_CONTROL, VPMPCC_MODE, MPCC_BLEND_MODE_BYPASS);
} else if (botsel != MPC_MUX_BOTSEL_DISABLE) {
// ERROR: Actually VPE10 only supports 1 MPCC so botsel should always disable
VPE_ASSERT(0);
REG_UPDATE(VPMPCC_CONTROL, VPMPCC_MODE, MPCC_BLEND_MODE_TOP_BOT_BLENDING);
} else {
// single layer, use Top layer bleneded with background color
if (topsel != MPC_MUX_TOPSEL_DISABLE)
REG_UPDATE(VPMPCC_CONTROL, VPMPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_ONLY);
else // both layer disabled, pure bypass mode
REG_UPDATE(VPMPCC_CONTROL, VPMPCC_MODE, MPCC_BLEND_MODE_BYPASS);
}
REG_UPDATE(VPMPCC_CONTROL, VPMPCC_MODE, blend_mode);
}
void vpe10_mpc_program_mpcc_blending(

View file

@ -815,6 +815,27 @@ static void build_clamping_params(
}
}
static enum mpcc_blend_mode get_blend_mode(
enum mpc_mux_topsel topsel, enum mpc_mux_botsel botsel, bool bypass)
{
enum mpcc_blend_mode blend_mode;
/* program mux and MPCC_MODE */
if (bypass) {
blend_mode = MPCC_BLEND_MODE_BYPASS;
} else if (botsel != MPC_MUX_BOTSEL_DISABLE) {
// ERROR: Actually VPE10 only supports 1 MPCC so botsel should always disable
VPE_ASSERT(0);
blend_mode = MPCC_BLEND_MODE_TOP_BOT_BLENDING;
} else {
// single layer, use Top layer bleneded with background color
if (topsel != MPC_MUX_TOPSEL_DISABLE)
blend_mode = MPCC_BLEND_MODE_TOP_LAYER_ONLY;
else // both layer disabled, pure bypass mode
blend_mode = MPCC_BLEND_MODE_BYPASS;
}
return blend_mode;
}
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)
{
@ -869,9 +890,12 @@ int32_t vpe10_program_frontend(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uin
dpp->funcs->program_input_transfer_func(dpp, stream_ctx->input_tf);
dpp->funcs->program_gamut_remap(dpp, stream_ctx->gamut_remap);
enum mpcc_blend_mode blend_mode = get_blend_mode(
MPC_MUX_TOPSEL_DPP0, MPC_MUX_BOTSEL_DISABLE, vpe_priv->init.debug.mpc_bypass == 1);
// for not bypass mode, we always are in single layer coming from DPP and output to OPP
mpc->funcs->program_mpcc_mux(mpc, MPC_MPCCID_0, MPC_MUX_TOPSEL_DPP0, MPC_MUX_BOTSEL_DISABLE,
MPC_MUX_OUTMUX_MPCC0, MPC_MUX_OPPID_OPP0);
MPC_MUX_OUTMUX_MPCC0, MPC_MUX_OPPID_OPP0, blend_mode);
// program shaper, 3dlut and 1dlut in MPC for stream before blend
mpc->funcs->program_movable_cm(

View file

@ -109,7 +109,8 @@ struct mpc_denorm_clamp {
struct mpc_funcs {
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);
enum mpc_mux_botsel botsel, enum mpc_mux_outmux outmux, enum mpc_mux_oppid oppid,
enum mpcc_blend_mode blend_mode);
void (*program_mpcc_blending)(
struct mpc *mpc, enum mpc_mpccid mpcc_idx, struct mpcc_blnd_cfg *blnd_cfg);

View file

@ -163,7 +163,7 @@ void calculate_scaling_ratios(struct scaler_data *scl_data, struct vpe_rect *src
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);
bool should_generate_cmd_info(enum vpe_stream_type stream_type);
bool should_generate_cmd_info(struct stream_ctx *stream_ctx);
enum vpe_status vpe_resource_build_scaling_params(struct segment_ctx *segment);

View file

@ -613,8 +613,10 @@ uint16_t vpe_get_num_segments(struct vpe_priv *vpe_priv, const struct vpe_rect *
return (uint16_t)(max(max(num_seg_src, num_seg_dst), 1));
}
bool should_generate_cmd_info(enum vpe_stream_type stream_type)
bool should_generate_cmd_info(struct stream_ctx *stream_ctx)
{
enum vpe_stream_type stream_type = stream_ctx->stream_type;
switch (stream_type) {
case VPE_STREAM_TYPE_INPUT:
case VPE_STREAM_TYPE_BG_GEN:

View file

@ -65,6 +65,14 @@ void *vpe_vector_get(struct vpe_vector *vector, size_t idx);
*/
void vpe_vector_push(struct vpe_vector *vector, void *p_element);
/**
* Remove elements from the vector by index. (ex. remove idx, idx+1 ... idx+(num_to_erase-1))
* @param[in] vector vector that we want to push to the end.
* @param[in] idx pointer of the element
* @param[in] number of elements to erase, starting from and including idx
*/
void vpe_vector_erase(struct vpe_vector *vector, size_t idx, size_t num_to_erase);
/**
* Clear the vector.
* @param[in] vector vector that we want to clear.

View file

@ -66,7 +66,7 @@ static struct vpe_vector *vector_realloc(struct vpe_vector *vector, size_t new_s
void *vpe_vector_get(struct vpe_vector *vector, size_t idx)
{
if (!vector)
if (!vector || idx >= vector->num_elements)
return NULL;
return (void *)((char *)(vector->element) + (idx * vector->element_size));
@ -90,13 +90,39 @@ void vpe_vector_push(struct vpe_vector *vector, void *p_element)
vector->num_elements++;
}
void vpe_vector_erase(struct vpe_vector *vector, size_t idx, size_t num_to_erase)
{
if (!vector)
return;
if (idx >= vector->num_elements)
return;
if ((num_to_erase < 1) || ((num_to_erase + idx) > vector->num_elements))
return;
if (idx != (vector->num_elements - num_to_erase)) {
void *erase_element = vpe_vector_get(vector, idx);
void *next_element = vpe_vector_get(vector, idx + num_to_erase);
void *new_first_empty_element = vpe_vector_get(vector, vector->num_elements - num_to_erase);
memcpy(erase_element, next_element,
(vector->num_elements - idx - num_to_erase) * vector->element_size);
vector->num_elements -= num_to_erase;
} else {
void *last_element = vpe_vector_get(vector, vector->num_elements - num_to_erase);
vector->num_elements -= num_to_erase;
}
}
void vpe_vector_clear(struct vpe_vector *vector)
{
if (!vector)
return;
vector->num_elements = 0;
memset(vector->element, 0, vector->capacity * vector->element_size);
}
void vpe_vector_free(struct vpe_vector *vector)